D Paste by Hxal
Description: infix operators
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | import std.metastrings; import std.string; import std.stdio; /* generic custom operator, library code */ template InfixOperator(char[] name) { private struct opStruct { template RT(T) { static if (is(T == class) || is(T == struct) || is(T == interface) || is(T == union)) mixin("alias T." ~ name ~ "Operator RT;"); else mixin("alias " ~ name ~"OperatorGlobal!(T) RT;"); } static RT!(T).RT opOr_r(T)(T left) { return RT!(T).RT(left); } } mixin ("alias opStruct " ~ name ~ ";"); } /* |example| operator declaration */ mixin InfixOperator!("example"); /* |example| operator overloads for basic types */ struct exampleOperatorGlobal(T : char[]) { T left; char[] opOr (char[] right) { return format ("two_strings(%s,%s)", left, right); } char[] opOr (int right) { return format ("string_and_int(%s,%s)", left, right); } } struct exampleOperatorGlobal(T : int) { T left; char[] opOr (char[] right) { return format ("int_and_string(%s,%s)", left, right); } char[] opOr (int right) { return format ("int_and_int(%s,%s)", left, right); } } /* classes implementing |example| operator overloads */ class AClass { int a; float b; struct exampleOperator { AClass left; char[] opOr (char[] right) { return Format!("AClass(%s)", right); } } } class AnotherClass : AClass { struct exampleOperator { AnotherClass left; char[] opOr (char[] right) { return Format!("AnotherClass(%s)", right); } } } void main() { writefln ("foo" |example| "bar"); writefln ("foo" |example| 123); writefln ( 123 |example| "foo"); writefln ( 123 |example| 456); AClass c1 = new AnotherClass; AnotherClass c2 = new AnotherClass; writefln (c1 |example| "foo"); writefln (c2 |example| "foo"); } |