/// <summary>Gets the last item from the list (at <c>list.Max</c>).</summary> /// <exception cref="EmptySequenceException">The list is empty</exception> public static T Last <T>(this INegListSource <T> list) { int last = list.Max; if (last < list.Min) { throw new EmptySequenceException(); } return(list[last]); }
/// <summary>Copies the contents of an <see cref="INegListSource{T}"/> to an array.</summary> public static T[] ToArray <T>(this INegListSource <T> c) { var array = new T[c.Count]; int min = c.Min; for (int i = 0; i < array.Length; i++) { array[i] = c[i + min]; } return(array); }
/// <summary>Tries to get a value from the list at the specified index.</summary> /// <param name="index">The index to access. Valid indexes are between Min and Max.</param> /// <param name="value">A variable that will be changed to the retrieved value. If the index is not valid, this variable is left unmodified.</param> /// <returns>True on success, or false if the index was not valid.</returns> public static bool TryGet <T>(this INegListSource <T> list, int index, ref T value) { bool fail; T result = list.TryGet(index, out fail); if (fail) { return(false); } value = result; return(true); }
/// <summary>Tries to get a value from the list at the specified index.</summary> /// <param name="index">The index to access. Valid indexes are between Min and Max.</param> /// <param name="defaultValue">A value to return if the index is not valid.</param> /// <returns>The retrieved value, or defaultValue if the index provided was not valid.</returns> public static T TryGet <T>(this INegListSource <T> list, int index, T defaultValue) { bool fail; T result = list.TryGet(index, out fail); if (fail) { return(defaultValue); } else { return(result); } }
/// <summary>Determines the index of a specific value.</summary> /// <returns>The index of the value, if found, or null if it was not found.</returns> /// <remarks> /// At first, this method was a member of IListSource itself, just in /// case the source might have some kind of fast lookup logic (e.g. binary /// search) or custom comparer. However, since the item to find is an "in" /// argument, it would prevent IListSource from being marked covariant when /// I upgrade to C# 4. /// </remarks> public static int?IndexOf <T>(this INegListSource <T> list, T item) { int max = list.Max; EqualityComparer <T> comparer = EqualityComparer <T> .Default; for (int i = list.Min; i <= max; i++) { if (comparer.Equals(item, list[i])) { return(i); } } return(null); }
/// <summary>Tries to get a value from the list at the specified index.</summary> /// <param name="index">The index to access. Valid indexes are between Min and Max.</param> /// <returns>The retrieved value, or <see cref="Maybe{T}.NoValue"/> if the index provided was not valid.</returns> public static Maybe <T> TryGet <T>(this INegListSource <T> list, int index) { bool fail; T result = list.TryGet(index, out fail); if (fail) { return(default(Maybe <T>)); } else { return(result); } }
/// <summary>Returns a slice without the initial elements of the list that meet the specified /// criteria. The word "now" is added to the name because unlike Enumerable.SkipWhile, this /// method scans the list immediately.</summary> /// <remarks>Example: new[] { 24, 28, 2, 12, 11 }.SkipNowWhile(n => n > 10) returns a slice /// (not a copy) of the last 2 elements.</remarks> public static NegListSlice <T> SkipNowWhile <T>(this INegListSource <T> list, Func <T, bool> predicate) { Maybe <T> value; for (int i = list.Min;; i++) { if (!(value = list.TryGet(i)).HasValue) { return(new NegListSlice <T>()); } else if (!predicate(value.Value)) { return(new NegListSlice <T>(list, i)); } } }
/// <summary>Initializes a slice.</summary> /// <exception cref="ArgumentException">The start index was below zero.</exception> /// <remarks>The (start, count) range is allowed to be invalid, as long /// as 'start' is <c>Min</c> or above and 'count' is zero or above. /// <ul> /// <li>If 'start' is above the original Count, the Count of the new slice /// is set to zero.</li> /// <li>if (start + count) is above the original Count, the Count of the new /// slice is reduced to <c>list.Count - start</c>.</li> /// </ul> /// </remarks> public NegListSlice(INegListSource <T> list, int start, int count) { _list = list; _start = start; _count = count; if (start < list.Min) { throw new ArgumentException("The start index was below Min."); } if (count < 0) { throw new ArgumentException("The count was below zero."); } if ((long)start + count - 1 > _list.Max) { _count = (int)System.Math.Max((long)_list.Max + 1 - start, 0); // use long to avoid overflow if start==int.MaxValue && Max<0 } }
public static int Count <T>(this INegListSource <T> list) => list.Count;
public static NegListSlice <T> Take <T>(this INegListSource <T> list, int count) { CheckParam.IsNotNegative("count", count); return(new NegListSlice <T>(list, list.Min, count)); }
// *** Reminder: do not edit the generated output! *** public static NegListSlice <T> Skip <T>(this INegListSource <T> list, int count) { CheckParam.IsNotNegative("count", count); return(new NegListSlice <T>(list, checked (list.Min + count), int.MaxValue)); }
// *** Reminder: do not edit the generated output! *** public static int Count <T>(this INegListSource <T> list) { return(list.Count); }
/// <inheritdoc cref="TryGet{K,V}(ITryGet{K,V}, K, V)"/> public static T TryGet <T>(this INegListSource <T> self, int key, T defaultValue) => TryGet((ITryGet <int, T>)self, key, defaultValue);
/// <inheritdoc cref="NegList{T}.NegList"/> public static NegListSlice <T> Slice <T>(this INegListSource <T> list, int start, int count) { return(new NegListSlice <T>(list, start, count)); }
// Workarounds: even though interfaces such as IListSource include ITryGet<int, T>, // C# in 2020 is too stupid to figure out how to call the overload for ITryGet<K, V>. // But in the case of IListSource, it includes IReadOnlyList which has its own // TryGet(), so we'd need to disambiguate anyway. /// <inheritdoc cref="TryGet{K,V}(ITryGet{K,V}, K)"/> public static Maybe <T> TryGet <T>(this INegListSource <T> self, int key) => TryGet((ITryGet <int, T>)self, key);
/// <summary>Gets the last item from the list (at <c>list.Max</c>), or <c>defaultValue</c> if the list is empty.</summary> public static T LastOrDefault <T>(this INegListSource <T> list, T defaultValue = default(T)) { int last = list.Max; return(last < list.Min ? defaultValue : list[last]); }
public NegListSlice(INegListSource <T> list) { _list = list; _start = list.Min; _count = list.Count; }