/// <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); }
/// <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); }
/// <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); }
/// <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); }
internal Builder(ImmVector <T> inner) { _inner = inner.Root; _lineage = Lineage.Mutable(); }
protected override ISequentialBuilder <T, ImmVector <T> > BuilderFrom(ImmVector <T> collection) { return(new Builder(collection)); }
public VectorDebugView(ImmVector <T> arr) { View = new SequentialDebugView <T>(arr); }