1 // { dg-do run { target c++17 } }
2 // { dg-options "" }
3 
4 #include <cassert>
5 
6 // Check the semantics of a couple of operations to make sure
7 // that the expressions are formed correctly.
8 
9 #define COMMA ,
10 
11 #define MAKE_FNS(name, op) \
12   template<typename... Ts> \
13     auto unary_left_ ## name (Ts... ts) { return (... op ts); } \
14   template<typename... Ts> \
15     auto unary_right_ ## name (Ts... ts) { return (ts op ...); } \
16   template<typename T, typename... Ts> \
17     auto binary_left_ ## name (T x, Ts... ts) { return (x op ... op ts); } \
18   template<typename T, typename... Ts> \
19     auto binary_right_ ## name (T x, Ts... ts) { return (ts op ... op x); }
20 
21 MAKE_FNS (add, +);
22 MAKE_FNS (sub, -);
23 
main()24 int main() {
25   // assert(unary_left_add() == 0);
26   assert(unary_left_add(1) == 1);
27   assert(unary_left_add(1, 2, 3) == 6);
28 
29   // assert(unary_right_add() == 0);
30   assert(unary_right_add(1) == 1);
31   assert(unary_right_add(1, 2, 3) == 6);
32 
33   assert(binary_left_add(1) == 1);
34   assert(binary_left_add(1, 1) == 2);
35   assert(binary_left_add(1, 1, 2, 3) == 7);
36 
37   assert(binary_right_add(1) == 1);
38   assert(binary_right_add(1, 1) == 2);
39   assert(binary_right_add(1, 1, 2, 3) == 7);
40 
41   // unary_left_sub(); // { dg-error "empty"}
42   assert(unary_left_sub(1) == 1);
43   assert(unary_left_sub(1, 2, 3) == -4);
44 
45   // unary_right_sub(); // { dg-error "empty"}
46   assert(unary_right_sub(1) == 1);
47   assert(unary_right_sub(1, 2, 3) == 2);
48 
49   assert(binary_left_sub(1) == 1);
50   assert(binary_left_sub(1, 1) == 0);
51   assert(binary_left_sub(1, 1, 2, 3) == -5);
52 
53   assert(binary_right_sub(1) == 1);
54   assert(binary_right_sub(1, 1) == 0);
55   assert(binary_right_sub(1, 1, 2, 3) == 1);
56 }
57