#pragma warning disable 168 using System; namespace Tests { class Operators { struct StructA { public int mA; public static StructA operator+(StructA lhs, StructA rhs) { StructA res; res.mA = lhs.mA + rhs.mA; return res; } public static StructA operator-(StructA lhs, StructA rhs) { StructA res; res.mA = lhs.mA - rhs.mA; return res; } public static StructA operator++(StructA val) { StructA newVal; newVal.mA = val.mA + 1; return newVal; } [Commutable] public static bool operator<(StructA lhs, StructB rhs) { return lhs.mA < rhs.mB; } } struct StructB { public int mB; public static StructA operator+(StructA sa, StructB sb) { StructA result; result.mA = sa.mA + sb.mB + 1000; return result; } public void operator++() mut { mB++; } } struct StructC { public int mA; public int mB; public this(int a, int b) { mA = a; mB = b; } public static bool operator==(StructC lhs, StructC rhs) { return lhs.mA == rhs.mA; } } struct StructOp where T : operator T + T2 { public T DoIt(T val, T2 val2) { return val + val2; } } struct StructOp2 { public T mVal; public static T operator+(StructOp2 lhs, T2 rhs) where T : operator T + T2 { return lhs.mVal + rhs; } public static T operator|(StructOp2 lhs, T2 rhs) where T : operator implicit T2 { T temp = rhs; return temp; } public T GetNeg(T2 val) where T : operator -T2 { return -val; } public T GetInt() where T : Int32 { return mVal; } } /*struct OuterOp { public struct InnerOp where T : operator T + T2 where T : operator -T where T : operator implicit T2 { public static T Op(T val, T2 val2) { return val + val2; } public static T Neg(T val) { return -val; } public static T Cast(T2 val) { return val; } struct InnerOp2 { public static T Op(T val, T2 val2) { return val + val2; } public static T Neg(T val) { return -val; } public static T Cast(T2 val) { return val; } } struct InnerOp3 { public static T Op(T val, T2 val2) { return val + val2; } public static T Neg(T val) { return -val; } public static T Cast(T2 val) { return val; } } } } struct OuterOp2 { public struct InnerOp { } extension InnerOp where T : operator T + T2 where T : operator -T { public static T Op(T val, T2 val2) { return val + val2; } public static T Neg(T val) { return -val; } } }*/ public static T Op(T val, T2 val2) where T : operator T + T2 { return val + val2; } public static T Complex(T val, T2 val2, T3 val3) where T : operator -T where T : operator implicit T2 where T : operator T + T2 where int32 : operator T + T3 { T conv = val2; T result = val + val2; result = -result; int32 iRes = val + val3; return result; } struct StructOp3 where float : operator T + T2 { public float Use(T lhs, T2 rhs) { float f = lhs + rhs; return f; } } [Test] public static void TestBasics() { StructA sa0 = default; sa0.mA = 1; StructA sa1 = default; sa1.mA = 2; StructA sa2 = sa0 + sa1; Test.Assert(sa2.mA == 3); StructB sb0; sb0.mB = 11; StructB sb1; sb1.mB = 12; Test.Assert(sa1 < sb0); Test.Assert(!(sa1 >= sb0)); Test.Assert(sb0 > sa1); Test.Assert(!(sb0 <= sa1)); StructA sa3 = sa0 + sb0; Test.Assert(sa3.mA == 1012); StructA sa4 = Op(sa0, sb0); Test.Assert(sa4.mA == 1012); StructA sa6 = sa0++; Test.Assert(sa0.mA == 2); Test.Assert(sa6.mA == 1); sa6 = ++sa0; Test.Assert(sa0.mA == 3); Test.Assert(sa6.mA == 3); StructB sb6 = sb0++; Test.Assert(sb0.mB == 12); Test.Assert(sb6.mB == 11); sb6 = ++sb0; Test.Assert(sb0.mB == 13); Test.Assert(sb6.mB == 13); float val = Op((int32)100, (int16)23); Test.Assert(val == 123); int32 i32res = Complex((int32)100, (int16)23, (int8)4); Test.Assert(i32res == -123); StructOp sOp; let sa5 = sOp.DoIt(sa1, sb1); Test.Assert(sa5.mA == 1014); StructOp2 sOp2; sOp2.mVal = 100; int32 res6 = sOp2 + (int16)40; Test.Assert(res6 == 140); int32 res7 = sOp2.GetInt(); Test.Assert(res7 == 100); Result rsc = .Ok(.(123, 234)); Result rsc2 = .Ok(.(123, 345)); Test.Assert(rsc == rsc2); Test.Assert(rsc !== rsc2); StructOp3 so3 = .(); float f = so3.Use(1, 2); Test.Assert(f == 3); /*let oai = OuterOp.InnerOp.Op(1.0f, 100); Test.Assert(oai == 101.0f); let oai2 = OuterOp2.InnerOp.Op(2.0f, 200); Test.Assert(oai2 == 202.0f);*/ } struct IntStruct { public int mA = 123; public typealias ZaffInt = int; public ZaffInt GetIt() { return 123; } public static implicit operator int(Self val) { return val.mA; } public static implicit operator Self(int val) { IntStruct sVal; sVal.mA = val; return sVal; } public void operator++() mut { mA++; } } [Test] public static void TestCompareWithCastOperator() { IntStruct iVal = .(); Test.Assert(iVal == 123); Test.Assert(iVal == 123.0f); var iVal2 = iVal++; var iVal3 = ++iVal; ++iVal; Test.Assert(iVal == 126); Test.Assert(iVal2 == 123); Test.Assert(iVal3 == 125); } const String cStrD = "D"; const char8* cStrPD = "D"; public static void TestDefaults(StringView sv = "ABC", IntStruct intStruct = 123) { Test.Assert(sv == "ABC"); Test.Assert(intStruct.mA == 123); } [Test] public static void TestStringOp() { const String cStr1 = "A" + "B"; const String cStr2 = cStr1 + "C" + cStrD; Test.Assert(cStr2 == "ABCD"); Test.Assert(cStr2 === "ABCD"); const char8* cStr3 = "A" + "B"; const char8* cStr4 = cStr1 + "C" + cStrPD; Test.Assert(StringView(cStr4) == "ABCD"); TestDefaults(); String strA = scope String("ABCD"); Test.Assert(strA == cStr2); Test.Assert(strA !== cStr1); let strTup = (strA, strA); Test.Assert(strTup == (cStr2, cStr2)); Test.Assert(strTup !== (cStr2, cStr2)); } public static TTo Convert(TFrom val) where TTo : operator explicit TFrom { return (TTo)val; } [Test] public static void TestConversion() { int a = 123; float f = Convert(a); } } }