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