Table of Contents

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
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

bool

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

int

Methods

AsCollection()

Create a new heap-allocated view over the slice.

[Pure]
public ValueSlice<T>.Collection AsCollection()

Returns

ValueSlice<T>.Collection

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

ReadOnlyMemory<T>

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

int

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

bool

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

bool

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

ValueSlice<T>.Enumerator

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

int

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

int

Slice(int)

Create a subslice, starting at offset.

[Pure]
public ValueSlice<T> Slice(int offset)

Parameters

offset int

The 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 below 0 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

offset int

The index at which to begin the subslice.

length int

The length of the new subslice.

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 below 0 or greater than the current slice's length.

ArgumentOutOfRangeException

length is below 0 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

string

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

bool

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

bool

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

bool

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

ReadOnlyMemory<T>

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>

Returns

bool