private static Node NodeTreeFromList(IOrderedCollection <KeyValuePair <TKey, TValue> > items, int start, int length) { Requires.NotNull(items, nameof(items)); Requires.Range(start >= 0, nameof(start)); Requires.Range(length >= 0, nameof(length)); if (length == 0) { return(EmptyNode); } int rightCount = (length - 1) / 2; int leftCount = (length - 1) - rightCount; Node left = NodeTreeFromList(items, start, leftCount); Node right = NodeTreeFromList(items, start + leftCount + 1, rightCount); var item = items[start + leftCount]; return(new Node(item.Key, item.Value, left, right, true)); }
private static SortedInt32KeyNode <TValue> NodeTreeFromList(IOrderedCollection <KeyValuePair <int, TValue> > items, int start, int length) { Requires.NotNull(items, "items"); Requires.Range(start >= 0, "start"); Requires.Range(length >= 0, "length"); if (length == 0) { return(EmptyNode); } int rightCount = (length - 1) / 2; int leftCount = (length - 1) - rightCount; SortedInt32KeyNode <TValue> left = NodeTreeFromList(items, start, leftCount); SortedInt32KeyNode <TValue> right = NodeTreeFromList(items, start + leftCount + 1, rightCount); var item = items[start + leftCount]; return(new SortedInt32KeyNode <TValue>(item.Key, item.Value, left, right, true)); }
/// <summary> /// Inserts the specified values at the specified index. /// </summary> /// <param name="index">The index at which to insert the value.</param> /// <param name="items">The elements to insert.</param> public void InsertRange(int index, ImmutableArray <T> items) { Requires.Range(index >= 0 && index <= this.Count, nameof(index)); if (items.IsEmpty) { return; } this.EnsureCapacity(this.Count + items.Length); if (index != this.Count) { Array.Copy(_elements, index, _elements, index + items.Length, _count - index); } Array.Copy(items.array !, 0, _elements, index, items.Length); _count += items.Length; }
/// <summary> /// Gets the element of the set at the given index. /// </summary> /// <param name="index">The 0-based index of the element in the set to return.</param> /// <returns>The element at the given position.</returns> internal T this[int index] { get { Requires.Range(index >= 0 && index < this.Count, nameof(index)); Debug.Assert(_left != null && _right != null); if (index < _left._count) { return(_left[index]); } if (index > _left._count) { return(_right[index - _left._count - 1]); } return(_key); } }
public static ImmutableArray <T> Create <T>(ImmutableArray <T> items, int start, int length) { Requires.Range(start >= 0 && start <= items.Length, nameof(start)); Requires.Range(length >= 0 && start + length <= items.Length, nameof(length)); if (length == 0) { return(Create <T>()); } if (start == 0 && length == items.Length) { return(items); } var array = new T[length]; Array.Copy(items.array, start, array, 0, length); return(new ImmutableArray <T>(array)); }
public static ImmutableArray<T> Create<T>(T[] items, int start, int length) { Requires.NotNull(items, "items"); Requires.Range(start >= 0 && start <= items.Length, "start"); Requires.Range(length >= 0 && start + length <= items.Length, "length"); if (length == 0) { // Avoid allocating an array. return Create<T>(); } var array = new T[length]; for (int i = 0; i < length; i++) { array[i] = items[start + i]; } return new ImmutableArray<T>(array); }
public static ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(ImmutableArray<TSource> items, int start, int length, Func<TSource, TArg, TResult> selector, TArg arg) { int itemsLength = items.Length; Requires.Range(start >= 0 && start <= itemsLength, "start"); Requires.Range(length >= 0 && start + length <= itemsLength, "length"); Requires.NotNull(selector, "selector"); if (length == 0) { return Create<TResult>(); } var array = new TResult[length]; for (int i = 0; i < length; i++) { array[i] = selector(items[i + start], arg); } return new ImmutableArray<TResult>(array); }
public static ImmutableArray <TResult> CreateRange <TSource, TResult>(ImmutableArray <TSource> items, int start, int length, Func <TSource, TResult> selector) { int itemsLength = items.Length; Requires.Range(start >= 0 && start <= itemsLength, nameof(start)); Requires.Range(length >= 0 && start + length <= itemsLength, nameof(length)); Requires.NotNull(selector, nameof(selector)); if (length == 0) { return(Create <TResult>()); } var array = new TResult[length]; for (int i = 0; i < length; i++) { array[i] = selector(items[i + start]); } return(new ImmutableArray <TResult>(array)); }
/// <summary> /// Removes the specified values from this list. /// </summary> /// <param name="index">The 0-based index into the array for the element to omit from the returned array.</param> /// <param name="length">The number of elements to remove.</param> public void RemoveRange(int index, int length) { Requires.Range(index >= 0 && index + length <= _count, nameof(index)); if (length == 0) { return; } if (index + length < this._count) { #if NET6_0_OR_GREATER if (RuntimeHelpers.IsReferenceOrContainsReferences <T>()) { Array.Clear(_elements, index, length); // Clear the elements so that the gc can reclaim the references. } #endif Array.Copy(_elements, index + length, _elements, index, this.Count - index - length); } this._count -= length; }
public ImmutableArray <T> Sort(int index, int count, IComparer <T> comparer) { var self = this; self.ThrowNullRefIfNotInitialized(); Requires.Range(index >= 0, nameof(index)); Requires.Range(count >= 0 && index + count <= self.Length, nameof(count)); // 0 and 1 element arrays don't need to be sorted. if (count > 1) { if (comparer == null) { comparer = Comparer <T> .Default; } // Avoid copying the entire array when the array is already sorted. bool outOfOrder = false; for (int i = index + 1; i < index + count; i++) { if (comparer.Compare(self.array[i - 1], self.array[i]) > 0) { outOfOrder = true; break; } } if (outOfOrder) { var tmp = new T[self.Length]; Array.Copy(self.array, 0, tmp, 0, self.Length); Array.Sort(tmp, index, count, comparer); return(new ImmutableArray <T>(tmp)); } } return(self); }
/// <summary> /// Inserts the specified values at the specified index. /// </summary> /// <param name="index">The index at which to insert the value.</param> /// <param name="items">The elements to insert.</param> public void InsertRange(int index, IEnumerable <T> items) { Requires.Range(index >= 0 && index <= this.Count, nameof(index)); Requires.NotNull(items, nameof(items)); int count = ImmutableExtensions.GetCount(ref items); this.EnsureCapacity(this.Count + count); if (index != this.Count) { Array.Copy(_elements, index, _elements, index + count, _count - index); } if (!items.TryCopyTo(_elements, index)) { foreach (var item in items) { _elements[index++] = item; } } _count += count; }
/// <summary> /// Searches the array for the specified item. /// </summary> /// <param name="item">The item to search for.</param> /// <param name="startIndex">The index at which to begin the search.</param> /// <param name="count">The number of elements to search.</param> /// <param name="equalityComparer"> /// The equality comparer to use in the search. /// If <c>null</c>, <see cref="EqualityComparer{T}.Default"/> is used. /// </param> /// <returns>The 0-based index into the array where the item was found; or -1 if it could not be found.</returns> public int IndexOf(T item, int startIndex, int count, IEqualityComparer <T>?equalityComparer) { var self = this; self.ThrowNullRefIfNotInitialized(); if (count == 0 && startIndex == 0) { return(-1); } Requires.Range(startIndex >= 0 && startIndex < self.Length, nameof(startIndex)); Requires.Range(count >= 0 && startIndex + count <= self.Length, nameof(count)); equalityComparer = equalityComparer ?? EqualityComparer <T> .Default; if (equalityComparer == EqualityComparer <T> .Default) { return(Array.IndexOf(self.array !, item, startIndex, count)); } else { for (int i = startIndex; i < startIndex + count; i++) { if (equalityComparer.Equals(self.array ![i], item))
/// <summary> /// Copies the current contents to the specified array. /// </summary> /// <param name="array">The array to copy to.</param> /// <param name="index">The starting index of the target array.</param> public void CopyTo(T[] array, int index) { Requires.NotNull(array, nameof(array)); Requires.Range(index >= 0 && index + this.Count <= array.Length, nameof(index)); Array.Copy(_elements, 0, array, index, this.Count); }
/// <summary> /// Initializes a new instance of the <see cref="Builder"/> class. /// </summary> /// <param name="capacity">The initial capacity of the internal array.</param> internal Builder(int capacity) { Requires.Range(capacity >= 0, nameof(capacity)); _elements = new T[capacity]; _count = 0; }
/// <summary> /// Initializes an <see cref="Enumerator"/> structure. /// </summary> /// <param name="root">The root of the set to be enumerated.</param> /// <param name="builder">The builder, if applicable.</param> /// <param name="startIndex">The index of the first element to enumerate.</param> /// <param name="count">The number of elements in this collection.</param> /// <param name="reversed"><c>true</c> if the list should be enumerated in reverse order.</param> internal Enumerator(Node root, Builder builder = null, int startIndex = -1, int count = -1, bool reversed = false) { Requires.NotNull(root, nameof(root)); Requires.Range(startIndex >= -1, nameof(startIndex)); Requires.Range(count >= -1, nameof(count)); Requires.Argument(reversed || count == -1 || (startIndex == -1 ? 0 : startIndex) + count <= root.Count); Requires.Argument(!reversed || count == -1 || (startIndex == -1 ? root.Count - 1 : startIndex) - count + 1 >= 0); _root = root; _builder = builder; _current = null; _currentNodeEnumeratingByIndex = null; _startIndex = startIndex >= 0 ? startIndex : (reversed ? root.Count - 1 : 0); _currentIndex = _startIndex; _count = count == -1 ? root.Count : count; _remainingCount = _count; _reversed = reversed; _enumeratingBuilderVersion = builder != null ? builder.Version : -1; _stackSlot0 = default; _stackSlot1 = default; _stackSlot2 = default; _stackSlot3 = default; _stackSlot4 = default; _stackSlot5 = default; _stackSlot6 = default; _stackSlot7 = default; _stackSlot8 = default; _stackSlot9 = default; _stackSlot10 = default; _stackSlot11 = default; _stackSlot12 = default; _stackSlot13 = default; _stackSlot14 = default; _stackSlot15 = default; _stackSlot16 = default; _stackSlot17 = default; _stackSlot18 = default; _stackSlot19 = default; _stackSlot20 = default; _stackSlot21 = default; _stackSlot22 = default; _stackSlot23 = default; _stackSlot24 = default; _stackSlot25 = default; _stackSlot26 = default; _stackSlot27 = default; _stackSlot28 = default; _stackSlot29 = default; _stackSlot30 = default; _stackSlot31 = default; _stackSlot32 = default; _stackSlot33 = default; _stackSlot34 = default; _stackSlot35 = default; _stackSlot36 = default; _stackSlot37 = default; _stackSlot38 = default; _stackSlot39 = default; _stackSlot40 = default; _stackSlot41 = default; _stackSlot42 = default; _stackSlot43 = default; _stackSlot44 = default; _stackSlot45 = default; _stackSlot46 = default; _stackTopIndex = -1; if (_count > 0) { this.ResetStack(); } }
/// <summary> /// Initializes a new instance of the <see cref="Builder"/> class. /// </summary> /// <param name="capacity">The initial capacity of the internal array.</param> internal Builder(int capacity) { Requires.Range(capacity >= 0, "capacity"); _elements = new RefAsValueType <T> [capacity]; this.Count = 0; }
/// <summary> /// Copies the current contents to the specified <see cref="Span{T}"/>. /// </summary> /// <param name="destination">The <see cref="Span{T}"/> to copy to.</param> public void CopyTo(Span <T> destination) { Requires.Range(this.Count <= destination.Length, nameof(destination)); new ReadOnlySpan <T>(_elements, 0, this.Count).CopyTo(destination); }