Beispiel #1
0
        /// <summary>
        /// Inserts a sequence of elements at the specified index.
        /// </summary>
        /// <param name="index">The index at which to insert. The element at this index is pushed forward.</param>
        /// <param name="items">The items to insert. Faster if an array or a known collection type.</param>
        /// <returns></returns>
        public ImmVector <T> InsertRange(int index, IEnumerable <T> items)
        {
            index.CheckIsBetween("index", -Root.Length - 1, Root.Length);
            items.CheckNotNull("items");
            index = index < 0 ? index + Root.Length + 1: index;
            if (index == 0)
            {
                return(AddFirstRange(items));
            }
            if (index == Length)
            {
                return(AddLastRange(items));
            }
#if ASSERTS
            var oldLast  = Last;
            var oldFirst = First;
#endif
            var start     = Root.Take(index - 1, Lineage.Immutable);
            var lineage   = Lineage.Mutable();
            var len       = 0;
            var s         = 0;
            var oldLength = Length;
            var arrInsert = items.ToArrayFast(out len);
            if (len == 0)
            {
                return(this);
            }
            var arrAfter = new T[oldLength - index];
            CopyTo(arrAfter, index, 0, oldLength - index);
            var arrLength = len;
            if (len == 0)
            {
                return(this);
            }
            if (oldLength + len >= MaxCapacity)
            {
                throw Errors.Capacity_exceeded();
            }
            start = start.AddRange(arrInsert, lineage, 6, ref s, ref len);
            len   = oldLength - index;
            s     = 0;
            start = start.AddRange(arrAfter, lineage, 6, ref s, ref len);
            ImmVector <T> ret = start;
#if ASSERTS
            ret.Length.AssertEqual(oldLength + arrLength);
            ret.RecursiveLength().AssertEqual(ret.Length);
            ret.Last.AssertEqual(oldLast);
            ret.First.AssertEqual(oldFirst);
            ret[index].AssertEqual(arrInsert[0]);
            ret[index + arrLength - 1].AssertEqual(arrInsert[arrLength - 1]);
#endif
            return(ret);
        }
Beispiel #2
0
        /// <summary>
        ///     Adds the specified element to the end of the vector. O(logn), fast.
        /// </summary>
        /// <param name="item">The item to add.</param>
        /// <returns>ImmVector{`0}.</returns>
        /// <exception cref="InvalidOperationException">Thrown if the data structure exceeds its maximum capacity.</exception>
        public ImmVector <T> AddLast(T item)
        {
#if ASSERTS
            var expected = Length + 1;
#endif
            if (Root.Length >= MaxCapacity)
            {
                throw Errors.Capacity_exceeded();
            }

            ImmVector <T> ret = Root.Add(item, Lineage.Immutable);
#if ASSERTS
            ret.Last.AssertEqual(item);
            ret.Length.AssertEqual(expected);
#endif
            return(ret);
        }
Beispiel #3
0
        /// <summary>
        ///     Removes the last item from the collection.
        /// </summary>
        /// <exception cref="InvalidOperationException">Thrown if the data structure is empty.</exception>
        public ImmVector <T> RemoveLast()
        {
            if (Root.Length == 0)
            {
                throw Errors.Is_empty;
            }
#if ASSERTS
            var expected = Length - 1;
#endif
            var           lineage = Lineage.Immutable;
            ImmVector <T> ret     = Root.RemoveLast(lineage);
#if ASSERTS
            ret.Length.AssertEqual(expected);
            if (Length > 1)
            {
                ret.Last.AssertEqual(this[-2]);
            }
#endif
            return(ret);
        }
Beispiel #4
0
        /// <summary>
        ///     Adds a sequence of items to the end of the collection.
        /// </summary>
        /// <param name="items">A sequence of items to add. Faster if the sequence is an array or a known collection type.</param>
        /// <exception cref="ArgumentNullException">Thrown if the argument is null.</exception>
        /// <exception cref="InvalidOperationException">Thrown if the collection exceeds its capacity.</exception>
        /// <remarks>This member performs a lot better when the specified sequence is an array.</remarks>
        public ImmVector <T> AddLastRange(IEnumerable <T> items)
        {
            items.CheckNotNull("items");
#if ASSERTS
            var expected = Length;
            var oldLast  = TryLast;
#endif
            var len = 0;
            var s   = 0;
            if (IsEmpty)
            {
                var asVector = items as ImmVector <T>;
                if (asVector != null)
                {
                    return(asVector);
                }
            }
            var arr    = items.ToArrayFast(out len);
            var oldLen = len;
            if (Root.Length + len >= MaxCapacity)
            {
                throw Errors.Capacity_exceeded();
            }
            ImmVector <T> ret = Root.AddRange(arr, Lineage.Mutable(), 6, ref s, ref len);
#if ASSERTS
            ret.Length.AssertEqual(expected + oldLen);
            if (arr.Length > 0 && oldLen > 0)
            {
                ret.Last.AssertEqual(arr[oldLen - 1]);
            }
            else if (oldLast.IsSome)
            {
                ret.Last.AssertEqual(oldLast.Value);
            }
#endif
            return(ret);
        }
Beispiel #5
0
 internal Builder(ImmVector <T> inner)
 {
     _inner   = inner.Root;
     _lineage = Lineage.Mutable();
 }
Beispiel #6
0
 protected override ISequentialBuilder <T, ImmVector <T> > BuilderFrom(ImmVector <T> collection)
 {
     return(new Builder(collection));
 }
Beispiel #7
0
 public VectorDebugView(ImmVector <T> arr)
 {
     View = new SequentialDebugView <T>(arr);
 }