Пример #1
0
        /// <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);
        }
Пример #2
0
 /// <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);
 }
Пример #3
0
        /// <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;
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
 /// <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));
     }
 }
Пример #7
0
        /// <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;
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
 /// <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);
 }