1 
2 template TT(T...) { alias T TT; }
3 
4 void TestOpAssign(Tx, Ux, ops)()
5 {
main()6     foreach(T; Tx.x)
7     foreach(U; Ux.x)
8     foreach(op; ops.x)
9     {
10         T a = cast(T)1;
11         mixin("a " ~ op ~ " cast(U)1;");
12     }
13 }
14 
15 void TestOpAssignAssign(Tx, Ux, ops)()
16 {
17     foreach(T; Tx.x)
18     foreach(U; Ux.x)
19     foreach(op; ops.x)
20     {
21         T a = cast(T)1;
22         U b = cast(U)1;
23         T r;
24         mixin("r = a " ~ op ~ " cast(U)1;");
25     }
26 }
27 
28 void TestOpAssignAuto(Tx, Ux, ops)()
29 {
30     foreach(T; Tx.x)
31     foreach(U; Ux.x)
32     static if (U.sizeof <= T.sizeof)
33     foreach(op; ops.x)
34     {
35         T a = cast(T)1;
36         U b = cast(U)1;
37         mixin("auto r = a " ~ op ~ " cast(U)1;");
38     }
39 }
40 
41 void TestOpAndAssign(Tx, Ux, ops)()
42 {
43     foreach(T; Tx.x)
44     foreach(U; Ux.x)
45     static if (U.sizeof <= T.sizeof && T.sizeof >= 4)
46     foreach(op; ops.x)
47     {
48         T a = cast(T)1;
49         U b = cast(U)1;
50         mixin("a = a " ~ op[0..$-1] ~ " cast(U)1;");
51     }
52 }
53 
54 struct boolean   { alias TT!(bool) x; }
55 struct integral  { alias TT!(byte, ubyte, short, ushort, int, uint, long, ulong) x; }
56 struct floating  { alias TT!(float, double, real) x; }
57 struct imaginary { alias TT!(ifloat, idouble, ireal) x; }
58 struct complex   { alias TT!(cfloat, cdouble, creal) x; }
59 
60 struct all       { alias TT!("+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>=", ">>>=") x; }
61 struct arith     { alias TT!("+=", "-=", "*=", "/=", "%=") x; }
62 struct bitwise   { alias TT!("&=", "|=", "^=") x; }
63 struct shift     { alias TT!("<<=", ">>=", ">>>=") x; }
64 struct addsub    { alias TT!("+=", "-=") x; }
65 struct muldivmod { alias TT!("*=", "/=", "%=") x; }
66 struct nomod     { alias TT!("+=", "-=", "*=", "/=") x; }
67 
68 void OpAssignCases(alias X)()
69 {
70     X!(boolean, boolean, bitwise)();
71 
72     X!(integral, boolean, all)();
73     X!(integral, integral, all)();
74     X!(integral, floating, arith)();
75 
76     X!(floating, boolean, arith)();
77     X!(floating, integral, arith)();
78     X!(floating, floating, arith)();
79 
80     X!(imaginary, boolean, muldivmod)();
81     X!(imaginary, integral, muldivmod)();
82     X!(imaginary, floating, muldivmod)();
83     X!(imaginary, imaginary, addsub)();
84 
85     X!(complex, boolean, arith)();
86     X!(complex, integral, arith)();
87     X!(complex, floating, arith)();
88     X!(complex, imaginary, arith)();
89     X!(complex, complex, nomod)();
90 }
91 
92 void OpReAssignCases(alias X)()
93 {
94     X!(boolean, boolean, bitwise)();
95 
96     X!(integral, boolean, all)();
97     X!(integral, integral, all)();
98 
99     X!(floating, boolean, arith)();
100     X!(floating, integral, arith)();
101     X!(floating, floating, arith)();
102 
103     X!(imaginary, boolean, muldivmod)();
104     X!(imaginary, integral, muldivmod)();
105     X!(imaginary, floating, muldivmod)();
106     X!(imaginary, imaginary, addsub)();
107 
108     X!(complex, boolean, arith)();
109     X!(complex, integral, arith)();
110     X!(complex, floating, arith)();
111     X!(complex, imaginary, arith)();
112     X!(complex, complex, nomod)();
113 }
114 
115 void main()
116 {
117     OpAssignCases!TestOpAssign();
118     OpAssignCases!TestOpAssignAssign(); // was once disabled due to bug 7436
119     OpAssignCases!TestOpAssignAuto(); // 5181
120     OpReAssignCases!TestOpAndAssign();
121 }
122