/// <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> /// 替换指定索引处的元素。 /// </summary> /// <param name="index">待替换元素的从零开始的索引。</param> /// <param name="item">位于指定索引处的元素的新值。对于引用类型,该值可以为 <c>null</c>。</param> protected override void SetItemAt(int index, bool item) { CommonExceptions.CheckArgumentOutOfRange(nameof(index), index, () => index < 0 || index >= _count); Contract.EndContractBlock(); if (item) { _items[index >> IndexShift] |= 1U << (index & IndexMask); } else { _items[index >> IndexShift] &= ~(1U << (index & IndexMask)); } }
/// <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> /// 返回指定索引处的元素。 /// </summary> /// <param name="index">要返回元素的从零开始的索引。</param> /// <returns>位于指定索引处的元素。</returns> protected override bool GetItemAt(int index) { CommonExceptions.CheckArgumentOutOfRange(nameof(index), index, () => index < 0 || index >= _count); Contract.EndContractBlock(); return((_items[index >> IndexShift] & (1 << (index & IndexMask))) != 0U); }