Пример #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>
        /// 将指定长度的值插入 <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;
        }
Пример #7
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);
        }
Пример #8
0
        /// <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();
        }