using System; using System.Collections; namespace Tests { class Generics2 { class ClassA { public virtual int32 GetWidth() { return 123; } } class ClassB : ClassA { public override int32 GetWidth() { return base.GetWidth(); } } struct TestFunc { private int mId; private Del mComparer; public static TestFunc Create(int id, Del comparer) { return .() { mId = id, mComparer = comparer }; } public bool CheckDlg(T item) { return false; } public bool CheckDlg(T item) where Del : delegate bool(T) { return mComparer(item); } public bool CheckDlg(T item) where Del : delegate bool(int, T) { return mComparer(mId, item); } public bool CallCheck(T val) { return CheckDlg(val); } } struct Iterator { public static Iterator Wrap(TCollection items) where TCollection : concrete, IEnumerable { return .(items.GetEnumerator()); } } struct Iterator : IDisposable where TEnum : concrete, IEnumerator { public TEnum mEnum; public this(TEnum items) { mEnum = items; } [SkipCall] public void Dispose() { } } public static bool SequenceEquals(this TLeft left, TRight right) where TLeft : concrete, IEnumerable where TRight : concrete, IEnumerable where bool : operator TSource == TSource { using (let iterator0 = Iterator.Wrap(left)) { var e0 = iterator0.mEnum; using (let iterator1 = Iterator.Wrap(right)) { var e1 = iterator1.mEnum; while (true) { switch (e0.GetNext()) { case .Ok(let i0): switch (e1.GetNext()) { case .Ok(let i1): if (i0 != i1) return false; case .Err: return false; } case .Err: return e1.GetNext() case .Err; } } } } } class IFaceA where T0 : Dictionary where T1 : IHashable { Dictionary mDict; } public static void MethodA() where T0 : Dictionary where T1 : IHashable { } typealias BigNum = BigNum; public struct BigNum where ArgN : const int where ExponentCells : const int64 { static int CalculateN() => Math.Max(1,(int)ArgN); public const int N = CalculateN(); } public static int Test(T param1, params Span param2) where T : const String { int total = param1.Length; for (int val in param2) total += val; return total; } public static int StrTest(T param2) where T : const String { return StrTest2(param2); } public static int StrTest2(T param1) where T : const String { return param1.Length; } public static void TestEmitMixin(T c, int a, String outStr) where T : const int { delegate void() d = scope () => { Compiler.Mixin(scope $"outStr.AppendF(\"{{}}{{}}\", {c}, a);"); }; d(); } class GenClass { public int test { get; set; }; } // Using a field instead of a property wouldn't cause the error public static int GenClassMethodA(A a) where A : GenClass { return a.test++; } public static int GenClassMethodB(GenClass a) { return a.test++; } public static int GenClassMethodC(A a) where A : GenClass { return a.test += 1; } public static TDerived AssertSubtype(TBase instance) where TDerived : TBase where TBase : class { if (instance == null) Runtime.FatalError(); if (TDerived derived = instance as TDerived) { return derived; } Runtime.FatalError(); } public static int TestOverload(TProc proc) where TProc : class, delegate void() { return 1; } public static int TestOverload(TProc proc) where TProc : delegate void() { return 2; } public static int TestOverload2(function void() proc) { return 3; } [Test] public static void TestBasics() { let testF = TestFunc.Create(10, scope (s) => s == "Str"); Test.Assert(testF.CallCheck("Str")); Test.Assert(!testF.CallCheck("Str2")); List iList = scope .() { 1, 2, 3 }; Span iSpan = iList; Test.Assert(iList.SequenceEquals(iSpan)); iList.Add(4); Test.Assert(!iList.SequenceEquals(iSpan)); Test.Assert(BigNum.N == 3); Test.Assert(Test("test", 1, 2, 3) == 10); Test.Assert(StrTest("ABCDE") == 5); Test.Assert(TestEmitMixin(123, 456, .. scope .()) == "123456"); GenClass gci = scope .(); Test.Assert(GenClassMethodA(gci) == 0); Test.Assert(gci.test == 1); Test.Assert(GenClassMethodB(gci) == 1); Test.Assert(gci.test == 2); Test.Assert(GenClassMethodC(gci) == 3); Test.Assert(gci.test == 3); delegate void() dlg = scope () => {}; function void() func = () => {}; Test.Assert(TestOverload(dlg) == 1); Test.Assert(TestOverload(() => {}) == 2); Test.Assert(TestOverload(func) == 2); Test.Assert(TestOverload2(func) == 3); } } }