2020-08-12 15:41:38 -07:00
|
|
|
#pragma warning disable 168
|
|
|
|
|
2019-11-17 09:28:39 -08:00
|
|
|
using System;
|
2020-06-30 05:44:34 -07:00
|
|
|
using System.Collections;
|
2019-11-17 09:28:39 -08:00
|
|
|
|
2020-08-16 08:31:26 -07:00
|
|
|
namespace LibA
|
|
|
|
{
|
|
|
|
extension LibA1 : IDisposable
|
|
|
|
{
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int operator<=>(Self lhs, Self rhs)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-17 09:28:39 -08:00
|
|
|
namespace Tests
|
|
|
|
{
|
|
|
|
class Generics
|
|
|
|
{
|
2020-05-16 08:21:34 -07:00
|
|
|
class ClassA : IDisposable, LibA.IVal
|
2019-11-17 09:28:39 -08:00
|
|
|
{
|
2020-05-16 08:21:34 -07:00
|
|
|
int LibA.IVal.Val
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return 123;
|
|
|
|
}
|
|
|
|
|
|
|
|
set
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDisposable.Dispose()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ClassB : IDisposable, LibA.IVal
|
|
|
|
{
|
|
|
|
public int Val
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return 234;
|
|
|
|
}
|
|
|
|
|
|
|
|
set
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-17 09:28:39 -08:00
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-11 16:24:07 -07:00
|
|
|
class Singleton<T> where T : Singleton<T>
|
|
|
|
{
|
|
|
|
public static T mInstance;
|
|
|
|
|
|
|
|
protected this()
|
|
|
|
{
|
|
|
|
mInstance = (T)this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ClassC : Singleton<ClassC>
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-08-16 08:31:26 -07:00
|
|
|
class ClassD
|
|
|
|
{
|
|
|
|
public static int operator<=>(Self lhs, Self rhs)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-17 09:28:39 -08:00
|
|
|
static void DoDispose<T>(mut T val) where T : IDisposable
|
|
|
|
{
|
|
|
|
val.Dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Disposer<T>
|
|
|
|
{
|
|
|
|
static void UseDispose(IDisposable disp)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DoDisposeA(mut T val) where T : IDisposable
|
|
|
|
{
|
|
|
|
val.Dispose();
|
|
|
|
UseDispose(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DoDisposeB(mut T val) where T : IDisposable
|
|
|
|
{
|
|
|
|
val.Dispose();
|
|
|
|
}
|
|
|
|
}
|
2020-02-13 07:53:11 -08:00
|
|
|
|
|
|
|
[Test]
|
|
|
|
public static void TestGenericDelegates()
|
|
|
|
{
|
|
|
|
delegate void(String v) dlg = scope => StrMethod;
|
|
|
|
CallGenericDelegate(dlg);
|
|
|
|
CallGenericDelegate<String>(scope => StrMethod);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void CallGenericDelegate<T>(delegate void(T v) dlg)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void StrMethod(String v)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-30 16:02:15 -07:00
|
|
|
public static int MethodA<T>(T val) where T : var
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int MethodA<T>(T val) where T : ValueType
|
|
|
|
{
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int MethodA<T>(T val) where T : Enum
|
|
|
|
{
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
2020-08-10 17:02:48 -07:00
|
|
|
public struct Entry
|
|
|
|
{
|
|
|
|
public static int operator<=>(Entry lhs, Entry rhs)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-12 15:41:38 -07:00
|
|
|
public static void Alloc0<T>() where T : new, delete, IDisposable
|
|
|
|
{
|
|
|
|
alloctype(T) val = new T();
|
|
|
|
val.Dispose();
|
|
|
|
delete val;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void Alloc1<T>() where T : new, delete, IDisposable, Object
|
|
|
|
{
|
|
|
|
alloctype(T) val = new T();
|
|
|
|
T val2 = val;
|
|
|
|
val.Dispose();
|
|
|
|
delete val;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void Alloc2<T>() where T : new, delete, IDisposable, struct
|
|
|
|
{
|
|
|
|
alloctype(T) val = new T();
|
|
|
|
T* val2 = val;
|
|
|
|
val2.Dispose();
|
|
|
|
delete val;
|
|
|
|
}
|
|
|
|
|
2019-11-17 09:28:39 -08:00
|
|
|
[Test]
|
|
|
|
public static void TestBasics()
|
|
|
|
{
|
2020-08-10 17:02:48 -07:00
|
|
|
List<Entry> list = scope .();
|
|
|
|
list.Sort();
|
|
|
|
|
2020-05-16 08:21:34 -07:00
|
|
|
ClassA ca = scope .();
|
|
|
|
ClassB cb = scope .();
|
|
|
|
Test.Assert(LibA.LibA0.GetVal(ca) == 123);
|
|
|
|
Test.Assert(LibA.LibA0.GetVal(cb) == 234);
|
|
|
|
|
|
|
|
LibA.LibA0.Dispose(ca);
|
|
|
|
LibA.LibA0.Dispose(cb);
|
2019-11-17 09:28:39 -08:00
|
|
|
|
2020-05-16 08:21:34 -07:00
|
|
|
LibA.LibA0.Alloc<ClassA>();
|
|
|
|
LibA.LibA0.Alloc<ClassB>();
|
2020-06-30 16:02:15 -07:00
|
|
|
|
|
|
|
Test.Assert(MethodA("") == 1);
|
|
|
|
Test.Assert(MethodA(1.2f) == 2);
|
|
|
|
Test.Assert(MethodA(TypeCode.Boolean) == 3);
|
2020-07-11 16:24:07 -07:00
|
|
|
|
|
|
|
ClassC cc = scope .();
|
|
|
|
Test.Assert(ClassC.mInstance == cc);
|
2020-08-16 08:31:26 -07:00
|
|
|
|
|
|
|
LibA.LibA1 la1 = scope .();
|
|
|
|
LibA.LibA1 la1b = scope .();
|
|
|
|
LibA.LibA2.DoDispose(la1);
|
|
|
|
Test.Assert(!LibA.LibA2.DoDispose2(la1));
|
|
|
|
Test.Assert(la1 == la1b);
|
|
|
|
Test.Assert(!LibA.LibA2.CheckEq(la1, la1b));
|
|
|
|
|
|
|
|
ClassD cd = scope .();
|
|
|
|
ClassD cd2 = scope .();
|
|
|
|
Test.Assert(LibA.LibA2.CheckEq(cd, cd2));
|
2019-11-17 09:28:39 -08:00
|
|
|
}
|
|
|
|
}
|
2019-11-28 09:11:54 -08:00
|
|
|
|
|
|
|
class ConstGenerics
|
|
|
|
{
|
|
|
|
public static float GetSum<TCount>(float[TCount] vals) where TCount : const int
|
|
|
|
{
|
|
|
|
float total = 0;
|
|
|
|
for (int i < vals.Count)
|
|
|
|
total += vals[i];
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public static void TestBasics()
|
|
|
|
{
|
|
|
|
float[5] fVals = .(10, 20, 30, 40, 50);
|
|
|
|
|
|
|
|
float totals = GetSum(fVals);
|
|
|
|
Test.Assert(totals == 10+20+30+40+50);
|
|
|
|
}
|
2020-06-30 05:44:34 -07:00
|
|
|
|
2020-08-12 15:41:38 -07:00
|
|
|
public static mixin TransformArray<Input, Output, InputSize>(Input[InputSize] array, delegate void(Input, ref Output) predicate) where InputSize : const int where Output : new, class
|
2020-06-30 05:44:34 -07:00
|
|
|
{
|
|
|
|
Output[2] output = default;
|
|
|
|
for (int i = 0; i < array.Count; i++)
|
|
|
|
{
|
|
|
|
output[i] = scope:mixin Output();
|
|
|
|
predicate(array[i], ref output[i]);
|
|
|
|
}
|
|
|
|
output
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public static void TestSizedArrays()
|
|
|
|
{
|
|
|
|
int[2] arr = .(2, 4);
|
|
|
|
|
|
|
|
delegate void(int, ref String) toString = scope (i, str) => { i.ToString(str); };
|
|
|
|
|
|
|
|
List<String[2]> l2 = scope .();
|
|
|
|
l2.Add(TransformArray!(arr, toString));
|
|
|
|
|
|
|
|
Test.Assert(l2.Front[0] == "2");
|
|
|
|
Test.Assert(l2.Front[1] == "4");
|
|
|
|
}
|
2019-11-28 09:11:54 -08:00
|
|
|
}
|
2019-11-17 09:28:39 -08:00
|
|
|
}
|