/// <summary> /// 将指定集合中的元素插入 <see cref="BitList"/> 的指定索引处。 /// </summary> /// <param name="index">应在此处插入新元素的从零开始的索引。</param> /// <param name="collection">一个集合,应将其元素插入到 /// <see cref="BitList"/> 中,其中每个整数表示 8 个连续位。</param> /// <exception cref="ArgumentNullException"><paramref name="collection"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 小于 <c>0</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 大于 <see cref="Count"/>。</exception> public void InsertRange(int index, [NotNull] IEnumerable <byte> collection) { CommonExceptions.CheckArgumentNull(collection, nameof(collection)); CommonExceptions.CheckArgumentNegative(nameof(index), index); CommonExceptions.CheckArgumentOutOfRange(nameof(index), IndexMask, () => index > _count); Contract.EndContractBlock(); IList <uint> uintList = new List <uint>(); var length = 0; var value = 0U; var j = 0; foreach (var b in collection) { value |= unchecked ((uint)(b << j)); j += 8; length += 8; if (j == UnitSize) { uintList.Add(value); value = 0U; j = 0; } } if (j > 0) { uintList.Add(value); } InsertRange(index, length, uintList); }
/// <summary> /// 填充指定范围中的元素。 /// </summary> /// <param name="index">要填充的范围的从零开始的起始索引。</param> /// <param name="length">要填充的范围内的元素数。</param> /// <param name="value">要填充的值。</param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="index"/> 小于 <c>0</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="length"/> 小于 <c>0</c>。</exception> /// <exception cref="System.ArgumentException"> /// <paramref name="index"/> 和 <paramref name="length"/> /// 不表示 <see cref="BitList"/> 中元素的有效范围。</exception> public void Fill(int index, int length, bool value) { CommonExceptions.CheckArgumentNegative(nameof(index), index); CommonExceptions.CheckArgumentNegative(nameof(length), length); CommonExceptions.CheckArgumentOutOfRange(nameof(length), length, () => index + length > _count); Contract.EndContractBlock(); FillInternal(index, length, value); }
/// <summary> /// 从 <see cref="BitList"/> 中移除一定范围的元素。 /// </summary> /// <param name="index">要移除的元素的范围从零开始的起始索引。</param> /// <param name="length">要移除的元素数。</param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="index"/> 小于 <c>0</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="length"/> 小于 <c>0</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="index"/> 和 <paramref name="length"/> 不表示 /// <see cref="BitList"/> 中元素的有效范围。</exception> public void RemoveRange(int index, int length) { CommonExceptions.CheckArgumentNegative(nameof(index), index); CommonExceptions.CheckArgumentNegative(nameof(length), length); CommonExceptions.CheckArgumentOutOfRange(nameof(length), length, () => index + length > _count); Contract.EndContractBlock(); if (length <= 0) { return; } if (length == 1) { RemoveItem(index); return; } var valueIdx = (index + length) >> IndexShift; var idx = index >> IndexShift; var tailSize = index & IndexMask; var rSize = (index + length) & IndexMask; if (rSize > 0) { var value = _items[valueIdx]; var highSize = tailSize == 0 ? 0 : UnitSize - tailSize; var restSize = UnitSize - rSize; if (highSize > restSize) { highSize = restSize; } if (highSize > 0) { var tailMask = GetMask(tailSize); _items[idx] = (_items[idx] & tailMask) | ((value >> rSize) << tailSize); tailSize += highSize; if (tailSize == UnitSize) { idx++; tailSize = 0; } } if (restSize > highSize) { tailSize = restSize - highSize; _items[idx] = value >> (UnitSize - tailSize); } valueIdx++; } // 计算要复制的长度。 var len = _count - (valueIdx << IndexShift) + tailSize; if (len > 0) { CopyItems(_items, valueIdx, idx, tailSize, len); } _count -= length; }
/// <summary> /// 将指定集合中的元素插入 <see cref="BitList"/> 的指定索引处。 /// </summary> /// <param name="index">应在此处插入新元素的从零开始的索引。</param> /// <param name="collection">一个集合,应将其元素插入到 /// <see cref="BitList"/> 中,其中每个整数表示 32 个连续位。</param> /// <exception cref="ArgumentNullException"><paramref name="collection"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 小于 <c>0</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 大于 <see cref="Count"/>。</exception> public void InsertRange(int index, [NotNull] IEnumerable <uint> collection) { CommonExceptions.CheckArgumentNull(collection, nameof(collection)); CommonExceptions.CheckArgumentNegative(nameof(index), index); CommonExceptions.CheckArgumentOutOfRange(nameof(index), index, () => index > _count); Contract.EndContractBlock(); var uintList = collection as IList <uint> ?? new List <uint>(collection); InsertRange(index, uintList.Count << IndexShift, uintList); }
/// <summary> /// 将指定集合中的元素插入 <see cref="BitList"/> 的指定索引处。 /// </summary> /// <param name="index">应在此处插入新元素的从零开始的索引。</param> /// <param name="collection">一个集合,应将其元素插入到 /// <see cref="BitList"/> 中,其中每个整数表示 32 个连续位。</param> /// <exception cref="ArgumentNullException"><paramref name="collection"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 小于 <c>0</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 大于 <see cref="Count"/>。</exception> /// <overloads> /// <summary> /// 将指定集合中的元素插入 <see cref="BitList"/> 的指定索引处。 /// </summary> /// </overloads> public void InsertRange(int index, [NotNull] IEnumerable <int> collection) { CommonExceptions.CheckArgumentNull(collection, nameof(collection)); CommonExceptions.CheckArgumentNegative(nameof(index), index); CommonExceptions.CheckArgumentOutOfRange(nameof(index), index, () => index > _count); Contract.EndContractBlock(); IList <uint> uintList = collection.Select(i => unchecked ((uint)i)).ToList(); InsertRange(index, uintList.Count << IndexShift, uintList); }
/// <summary> /// 将指定长度的值插入 <see cref="BitList"/> 的指定索引处。 /// </summary> /// <param name="index">应在此处插入值的从零开始的索引。</param> /// <param name="length">要插入的值的长度。</param> /// <param name="value">要插入的值。</param> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 小于 <c>0</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> 小于 <c>0</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 大于 <see cref="Count"/>。</exception> public void InsertRange(int index, int length, bool value) { CommonExceptions.CheckArgumentNegative(nameof(index), index); CommonExceptions.CheckArgumentNegative(nameof(length), length); CommonExceptions.CheckArgumentOutOfRange(nameof(length), length, () => index + length > _count); Contract.EndContractBlock(); var cnt = _count + length; EnsureCapacity(cnt + UnitSize); if (index < _count) { LeftShift(index, length); } FillInternal(index, length, value); _count = cnt; }
/// <summary> /// 将指定集合中的元素插入 <see cref="BitList"/> 的指定索引处。 /// </summary> /// <param name="index">应在此处插入新元素的从零开始的索引。</param> /// <param name="collection">一个集合,应将其元素插入到 /// <see cref="BitList"/> 中。</param> /// <exception cref="ArgumentNullException"><paramref name="collection"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 小于 <c>0</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> 大于 <see cref="Count"/>。</exception> public void InsertRange(int index, [NotNull] IEnumerable <bool> collection) { CommonExceptions.CheckArgumentNull(collection, nameof(collection)); CommonExceptions.CheckArgumentNegative(nameof(index), index); CommonExceptions.CheckArgumentOutOfRange(nameof(index), index, () => index > _count); Contract.EndContractBlock(); IList <uint> uintList; var length = 0; var bList = collection as BitList; if (bList != null) { length = bList._count; uintList = bList._items; } else { uintList = new List <uint>(); var value = 0U; var j = 0; foreach (var b in collection) { if (b) { value |= 1U << j; } j++; length++; if (j == UnitSize) { uintList.Add(value); value = 0U; j = 0; } } if (j > 0) { uintList.Add(value); } } InsertRange(index, length, uintList); }
/// <summary> /// 从特定的 <see cref="System.Array"/> 索引处开始,将 /// <see cref="CollectionBase{T}"/> 的元素复制到一个 <see cref="System.Array"/> 中。 /// </summary> /// <param name="array">作为从 <see cref="CollectionBase{T}"/> /// 复制的元素的目标位置的一维 <see cref="System.Array"/>。 /// <see cref="System.Array"/> 必须具有从零开始的索引。</param> /// <param name="index"><paramref name="array"/> 中从零开始的索引,在此处开始复制。</param> /// <exception cref="ArgumentNullException"> /// <paramref name="array"/> 为 <c>null</c>。</exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="index"/> 小于零。</exception> /// <exception cref="System.ArgumentException"> /// <paramref name="array"/> 是多维的。</exception> /// <exception cref="System.ArgumentException">源 <see cref="CollectionBase{T}"/> /// 中的元素数目大于从 <paramref name="index"/> 到目标 /// <paramref name="array"/> 末尾之间的可用空间。</exception> /// <exception cref="System.ArgumentException">源 <see cref="CollectionBase{T}"/> /// 的类型无法自动转换为目标 <paramref name="array"/> 的类型。</exception> void ICollection.CopyTo(Array array, int index) { CommonExceptions.CheckSimplyArray(array, nameof(array)); CommonExceptions.CheckArgumentNegative(nameof(index), index); Contract.EndContractBlock(); var uarr = array as uint[]; if (uarr != null) { var end = 0; if (_count > 0) { end = (_count - 1) >> IndexShift; } Array.Copy(_items, 0, array, index, end + 1); return; } var iarr = array as int[]; if (iarr != null) { var cnt = 1; if (_count > 0) { cnt = ((_count - 1) >> IndexShift) + 1; } if (array.Length - index < cnt) { throw CommonExceptions.ArrayTooSmall(nameof(array)); } for (var i = 0; i < cnt; i++) { iarr[index++] = unchecked ((int)_items[i]); } return; } var barr = array as byte[]; if (barr != null) { var cnt = 1; if (_count > 0) { cnt = (_count - 1) / 8 + 1; } if (array.Length - index < cnt) { throw CommonExceptions.ArrayTooSmall(nameof(array)); } for (var i = 0; i < cnt; i++) { barr[index++] = (byte)((_items[i / 4] >> (i % 4 * 8)) & 0xFF); } return; } var boarr = array as bool[]; if (boarr != null) { if (array.Length - index < _count) { throw CommonExceptions.ArrayTooSmall(nameof(array)); } for (var i = 0; i < _count; i++) { boarr[index++] = (_items[i >> IndexShift] & (1U << (i & IndexMask))) > 0; } return; } throw CommonExceptions.InvalidElementType(); }