1 // { dg-do compile }
2 // { dg-options "-std=c++17" }
3
4 // Check that we can fold over all of the operators required
5 // by the standard in every possible way.
6
7 #define COMMA ,
8
9 #define MAKE_FNS(name, op) \
10 template<typename... Ts> \
11 auto unary_left_ ## name (Ts... ts) { return (... op ts); } \
12 template<typename... Ts> \
13 auto unary_right_ ## name (Ts... ts) { return (ts op ...); } \
14 template<typename T, typename... Ts> \
15 auto binary_left_ ## name (T x, Ts... ts) { return (x op ... op ts); } \
16 template<typename T, typename... Ts> \
17 auto binary_right_ ## name (T x, Ts... ts) { return (ts op ... op x); }
18
19 // TODO: These are compile-only tests...
20 #define CHECK_FN(name) \
21 unary_left_ ## name (a); \
22 unary_left_ ## name (a, b, c); \
23 unary_right_ ## name (a); \
24 unary_right_ ## name (a, b, c); \
25 binary_left_ ## name (a); \
26 binary_left_ ## name (a, b, c, d); \
27 binary_right_ ## name (d); \
28 binary_right_ ## name (d, a, b, c);
29
30 MAKE_FNS (add, +);
31 MAKE_FNS (sub, -);
32 MAKE_FNS (mul, *);
33 MAKE_FNS (div, /);
34 MAKE_FNS (mod, %);
35 MAKE_FNS (bxor, ^);
36 MAKE_FNS (bor, |);
37 MAKE_FNS (band, &);
38 MAKE_FNS (lsh, <<);
39 MAKE_FNS (rsh, >>);
40
41 MAKE_FNS (assign, =);
42 MAKE_FNS (addi, +=);
43 MAKE_FNS (subi, -=);
44 MAKE_FNS (muli, *=);
45 MAKE_FNS (divi, /=);
46 MAKE_FNS (modi, %=);
47 MAKE_FNS (bxori, ^=);
48 MAKE_FNS (bori, |=);
49 MAKE_FNS (bandi, &=);
50 MAKE_FNS (lshi, <<=);
51 MAKE_FNS (rshi, >>=);
52
53 MAKE_FNS (eq, ==);
54 MAKE_FNS (ne, !=);
55 MAKE_FNS (lt, <);
56 MAKE_FNS (gt, >);
57 MAKE_FNS (le, <=);
58 MAKE_FNS (ge, >=);
59
60 MAKE_FNS (land, &&);
61 MAKE_FNS (lor, ||);
62
63 MAKE_FNS (comma, COMMA);
64 MAKE_FNS (dot_star, .*);
65 MAKE_FNS (arrow_star, ->*);
66
main()67 int main() {
68 int a = 0, b = 0, c = 0, d = 0;
69
70 CHECK_FN (add);
71 CHECK_FN (sub);
72 CHECK_FN (mul);
73 CHECK_FN (div);
74 CHECK_FN (mod);
75 CHECK_FN (bxor);
76 CHECK_FN (bor);
77 CHECK_FN (band);
78 CHECK_FN (lsh);
79 CHECK_FN (rsh);
80
81 // CHECK_FN (assign);
82 CHECK_FN (addi);
83 CHECK_FN (subi);
84 CHECK_FN (muli);
85 CHECK_FN (divi);
86 CHECK_FN (modi);
87 CHECK_FN (bxori);
88 CHECK_FN (bori);
89 CHECK_FN (bandi);
90 CHECK_FN (lshi);
91 CHECK_FN (rshi);
92
93 CHECK_FN (eq);
94 CHECK_FN (ne);
95 CHECK_FN (lt);
96 CHECK_FN (gt);
97 CHECK_FN (le);
98 CHECK_FN (ge);
99 CHECK_FN (eq);
100 CHECK_FN (ne);
101
102 CHECK_FN (comma);
103
104 struct X {
105 int a;
106 } x, *px = &x;
107
108 int X::* pm = &X::a;
109 unary_left_arrow_star (px, pm); // px ->* pm
110 unary_right_arrow_star (px, pm); // px ->* pm
111 binary_left_arrow_star (px, pm); // px ->* pm
112 binary_right_arrow_star (pm, px); // px ->* pm
113
114 unary_left_dot_star (x, pm); // x ->* pm
115 unary_right_dot_star (x, pm); // x ->* pm
116 binary_left_dot_star (x, pm); // x ->* pm
117 binary_right_dot_star (pm, x); // x ->* pm
118 }
119