D Paste by Hxal
Description: infix operators
Hide line numbers

Create new paste
Post a reply
View replies

Paste:
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");
}

Replies:
No replies posted yet