Struct ValueSlice<T>
- Namespace
- Badeend.ValueCollections
- Assembly
- Badeend.ValueCollections.dll
An immutable, thread-safe span with value semantics.
public readonly struct ValueSlice<T> : IEquatable<ValueSlice<T>>, IComparable, IComparable<ValueSlice<T>>
Type Parameters
T
The type of items in the slice.
- Implements
-
IEquatable<ValueSlice<T>>
- Inherited Members
Remarks
This type is similar to ReadOnlySpan<T> and ReadOnlyMemory<T> in that this too is just a view into an existing allocation at a specified offset+length. Taking a subslice with Slice(int) and Slice(int, int) is very cheap as it reuses the same allocation and only adjusts the internal offset+length fields.
Unlike ReadOnlySpan&Memory, the data is not just read-only but it is also guaranteed to be immutable.
Additionally, ValueSlice has "structural equality". This means that two slices are considered equal only when their contents are equal. As long as a value is present in a ValueSlice, its hash code may not change.
To prevent accidental boxing, ValueSlice does not implement commonly used interfaces such as IEnumerable<T> and IReadOnlyList<T>. You can still use these interfaces by manually calling AsCollection() instead.
The default
value of every ValueSlice is an empty slice.
Properties
Empty
Get an empty slice.
This does not allocate any memory.
[Pure]
public static ValueSlice<T> Empty { get; }
Property Value
- ValueSlice<T>
IsEmpty
Shortcut for .Length == 0
.
[Pure]
public bool IsEmpty { get; }
Property Value
this[int]
Get an item from the slice at the specified index
.
public ref readonly T this[int index] { get; }
Parameters
index
int
Property Value
- T
Length
Length of the slice.
[Pure]
public int Length { get; }
Property Value
Methods
AsCollection()
Create a new heap-allocated view over the slice.
[Pure]
public ValueSlice<T>.Collection AsCollection()
Returns
Remarks
This method is an O(1)
operation and allocates a new fixed-size
collection instance. The items are not copied.
AsMemory()
Access the slice's contents using a ReadOnlyMemory<T>.
[Pure]
public ReadOnlyMemory<T> AsMemory()
Returns
AsSpan()
Access the slice's contents using a ReadOnlySpan<T>.
[Pure]
public ReadOnlySpan<T> AsSpan()
Returns
- ReadOnlySpan<T>
BinarySearch(T)
Perform a binary search for item
within the slice.
The slice is assumed to already be sorted. This uses the
Default comparer and throws if
T
is not comparable. If the item is found, its
index is returned. Otherwise a negative value is returned representing
the bitwise complement of the index where the item was expected.
[Pure]
public int BinarySearch(T item)
Parameters
item
T
Returns
CastUp<TDerived>(ValueSlice<TDerived>)
Reinterpret the type of the slice to be of another element type.
[Pure]
public static ValueSlice<T> CastUp<TDerived>(ValueSlice<TDerived> source) where TDerived : class, T
Parameters
source
ValueSlice<TDerived>
Returns
- ValueSlice<T>
Type Parameters
TDerived
Element type of the existing slice. Must be derived from
T
.
Examples
ValueSlice<Cat> cats = [/*...*/];
ValueSlice<Animal> animals = ValueSlice<Animal>.CastUp(cats);
Remarks
This does not perform a copy. The returned slice points to the same memory.
This is guaranteed to be safe and infallible because of the generic type constraints. If these constraints are not statically provable, TryCast<TOther>(out ValueSlice<TOther>) may be used to perform the same conversion but using dynamic type checks.
CompareTo(ValueSlice<T>)
Compare two slices based on their contents using lexicographic ordering
(the same algorithm used by MemoryExtensions.SequenceCompareTo
).
[Pure]
public int CompareTo(ValueSlice<T> other)
Parameters
other
ValueSlice<T>
Returns
- int
See IComparable<T>.CompareTo(T) for more information.
Exceptions
- ArgumentException
T
does not implement IComparable.
Contains(T)
Returns true when this
slice
contains the specified item
.
[Pure]
public bool Contains(T item)
Parameters
item
T
Returns
CopyTo(Span<T>)
Copy the contents of the slice into an existing Span<T>.
Similar to CopyTo(Span<T>).
public void CopyTo(Span<T> destination)
Parameters
destination
Span<T>
Exceptions
- ArgumentException
destination
is shorter than the source slice.
Equals(ValueSlice<T>)
Returns true when the two slices have identical length and content.
[Pure]
public bool Equals(ValueSlice<T> other)
Parameters
other
ValueSlice<T>
Returns
GetEnumerator()
Returns an enumerator for this ValueSlice<T>.
Typically, you don't need to manually call this method, but instead use
the built-in foreach
syntax.
[Pure]
public ValueSlice<T>.Enumerator GetEnumerator()
Returns
GetHashCode()
Returns the hash code for this instance.
[Pure]
public override int GetHashCode()
Returns
- int
A 32-bit signed integer that is the hash code for this instance.
IndexOf(T)
Return the index of the first occurrence of item
in
this
, or -1
if not found.
[Pure]
public int IndexOf(T item)
Parameters
item
T
Returns
LastIndexOf(T)
Return the index of the last occurrence of item
in
this
, or -1
if not found.
[Pure]
public int LastIndexOf(T item)
Parameters
item
T
Returns
Slice(int)
Create a subslice, starting at offset
.
[Pure]
public ValueSlice<T> Slice(int offset)
Parameters
offset
intThe index at which to begin the subslice.
Returns
- ValueSlice<T>
Remarks
This is an O(1)
operation and does not allocates any memory.
Similar to Slice(int).
Exceptions
- ArgumentOutOfRangeException
offset
is below0
or greater than the current slice's length.
Slice(int, int)
Create a subslice with a specified length
,
starting at offset
.
[Pure]
public ValueSlice<T> Slice(int offset, int length)
Parameters
Returns
- ValueSlice<T>
Remarks
This is an O(1)
operation and does not allocates any memory.
Similar to Slice(int, int).
Exceptions
- ArgumentOutOfRangeException
offset
is below0
or greater than the current slice's length.- ArgumentOutOfRangeException
length
is below0
or would extend beyond the current slice's length.
ToArray()
Copy the contents of the slice into a new array.
Similar to ToArray().
[Pure]
public T[] ToArray()
Returns
- T[]
ToString()
Get a string representation of the collection for debugging purposes. The format is not stable and may change without prior notice.
[Pure]
public override string ToString()
Returns
ToValueList()
Copy the slice into a new ValueList<T>.
[Pure]
public ValueList<T> ToValueList()
Returns
- ValueList<T>
TryCast<TOther>(out ValueSlice<TOther>)
Attempt to reinterpret the type of the slice to be of another element type.
public bool TryCast<TOther>(out ValueSlice<TOther> result)
Parameters
result
ValueSlice<TOther>
Returns
Type Parameters
TOther
Element type of the new slice.
Examples
ValueSlice<Cat> cats = [/*...*/];
Assert.True(cats.TryCast<Animal>(out var animals)); // Upcast
Assert.True(animals.TryCast<Cat>(out var catsAgain)); // Downcast
Remarks
If the slice is empty this method always succeeds and
result
contains the empty slice for the requested type.
The common use case is to upcast the slice's element type into a base type. However, this method can also be used to downcast the element type if that reverses a prior upcast operation.
This does not perform a copy. On success, the returned slice points to the same memory.
If TOther
is statically provable to be the
supertype of T
, CastUp<TDerived>(ValueSlice<TDerived>) may be used
to perform the same conversion without dynamic type checks.
TryCopyTo(Span<T>)
Attempt to copy the contents of the slice into an existing
Span<T>. If the destination
is too short,
no items are copied and the method returns false.
Similar to TryCopyTo(Span<T>).
public bool TryCopyTo(Span<T> destination)
Parameters
destination
Span<T>
Returns
Operators
operator ==(ValueSlice<T>, ValueSlice<T>)
Check for equality.
[Pure]
public static bool operator ==(ValueSlice<T> left, ValueSlice<T> right)
Parameters
left
ValueSlice<T>right
ValueSlice<T>
Returns
implicit operator ReadOnlyMemory<T>(ValueSlice<T>)
Access the slice as a ReadOnlyMemory<T>.
[Pure]
public static implicit operator ReadOnlyMemory<T>(ValueSlice<T> slice)
Parameters
slice
ValueSlice<T>
Returns
implicit operator ReadOnlySpan<T>(ValueSlice<T>)
Access the slice as a ReadOnlySpan<T>.
[Pure]
public static implicit operator ReadOnlySpan<T>(ValueSlice<T> slice)
Parameters
slice
ValueSlice<T>
Returns
- ReadOnlySpan<T>
operator !=(ValueSlice<T>, ValueSlice<T>)
Check for inequality.
[Pure]
public static bool operator !=(ValueSlice<T> left, ValueSlice<T> right)
Parameters
left
ValueSlice<T>right
ValueSlice<T>