#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();
}