sharplib/imm/List.cs

83 lines
6.6 KiB
C#

#nullable enable
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Runtime.CompilerServices;
namespace io;
/// <summary>
/// An immutable list implementation that tracks history, metadata, and time.
/// </summary>
public record class List<T> : io.Timed<List<T>>, IImmutableList<T>
{
static public List<T> Empty { get; } = new();
public ImmutableList<T> Values { get; init; } = ImmutableList<T>.Empty;
public List() { }
// Required for 'with' expressions to work with the base class hierarchy
protected List( io.Timed<List<T>> original ) : base( original ) { }
// Helper to apply changes using the Process method
private List<T> Change(
Func<ImmutableList<T>, ImmutableList<T>> listChange,
[CallerMemberName] string dbgMethod = "",
[CallerFilePath] string dbgPath = "",
[CallerLineNumber] int dbgLine = -1,
[CallerArgumentExpression( "listChange" )] string reason = "" )
{
var newValues = listChange( Values );
return ReferenceEquals( Values, newValues )
? this
: Process( l => l with { Values = newValues }, reason, dbgMethod, dbgPath, dbgLine, reason );
}
// --- IImmutableList<T> implementation using the Change helper ---
public T this[int index] => Values[index];
public int Count => Values.Count;
public List<T> Add( T value, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Add( value ), dbgMethod, dbgPath, dbgLine );
public List<T> AddRange( IEnumerable<T> items, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.AddRange( items ), dbgMethod, dbgPath, dbgLine );
public List<T> Clear( [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Clear(), dbgMethod, dbgPath, dbgLine );
#region IImmutableList Implementati, dbgMethod, dbgPath, dbgLineon
public List<T> Insert( int index, T element, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Insert( index, element ), dbgMethod, dbgPath, dbgLine );
public List<T> InsertRange( int index, IEnumerable<T> items, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.InsertRange( index, items ), dbgMethod, dbgPath, dbgLine );
public List<T> Remove( T value, IEqualityComparer<T>? equalityComparer, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Remove( value, equalityComparer ), dbgMethod, dbgPath, dbgLine );
public List<T> Remove( T value, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Remove( value, EqualityComparer<T>.Default, dbgMethod, dbgPath, dbgLine );
public List<T> RemoveAll( Predicate<T> match, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveAll( match ), dbgMethod, dbgPath, dbgLine );
public List<T> RemoveAt( int index, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveAt( index ), dbgMethod, dbgPath, dbgLine );
public List<T> RemoveRange( int index, int count, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveRange( index, count ), dbgMethod, dbgPath, dbgLine );
public List<T> RemoveRange( IEnumerable<T> items, IEqualityComparer<T>? equalityComparer, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.RemoveRange( items, equalityComparer ), dbgMethod, dbgPath, dbgLine );
public List<T> Replace( T oldValue, T newValue, IEqualityComparer<T>? equalityComparer, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.Replace( oldValue, newValue, equalityComparer ), dbgMethod, dbgPath, dbgLine );
public List<T> SetItem( int index, T value, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => Change( v => v.SetItem( index, value ), dbgMethod, dbgPath, dbgLine );
public int IndexOf( T item, int index, int count, IEqualityComparer<T>? equalityComparer ) => Values.IndexOf( item, index, count, equalityComparer ?? EqualityComparer<T>.Default );
public int LastIndexOf( T item, int index, int count, IEqualityComparer<T>? equalityComparer ) => Values.LastIndexOf( item, index, count, equalityComparer ?? EqualityComparer<T>.Default );
public int IndexOf( T item, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 ) => IndexOf( item, 0, Count, EqualityComparer<T>.Default );
IImmutableList<T> IImmutableList<T>.Clear() => Clear();
IImmutableList<T> IImmutableList<T>.Add( T value ) => Add( value );
IImmutableList<T> IImmutableList<T>.AddRange( IEnumerable<T> items ) => AddRange( items );
IImmutableList<T> IImmutableList<T>.Insert( int index, T element ) => Insert( index, element );
IImmutableList<T> IImmutableList<T>.InsertRange( int index, IEnumerable<T> items ) => InsertRange( index, items );
IImmutableList<T> IImmutableList<T>.Remove( T value, IEqualityComparer<T>? equalityComparer ) => Remove( value, equalityComparer );
IImmutableList<T> IImmutableList<T>.RemoveAll( Predicate<T> match ) => RemoveAll( match );
IImmutableList<T> IImmutableList<T>.RemoveAt( int index ) => RemoveAt( index );
IImmutableList<T> IImmutableList<T>.RemoveRange( IEnumerable<T> items, IEqualityComparer<T>? equalityComparer ) => RemoveRange( items, equalityComparer );
IImmutableList<T> IImmutableList<T>.RemoveRange( int index, int count ) => RemoveRange( index, count );
IImmutableList<T> IImmutableList<T>.Replace( T oldValue, T newValue, IEqualityComparer<T>? equalityComparer ) => Replace( oldValue, newValue, equalityComparer );
IImmutableList<T> IImmutableList<T>.SetItem( int index, T value ) => SetItem( index, value );
#endregion
// --- Standard Interfaces ---
public IEnumerator<T> GetEnumerator() => Values.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => ( (IEnumerable)Values ).GetEnumerator();
}