82 lines
6.6 KiB
C#
82 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 imm;
|
|
|
|
/// <summary>
|
|
/// An immutable list implementation that tracks history, metadata, and time.
|
|
/// </summary>
|
|
public record class List<T> : 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(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();
|
|
} |