xref: /minix3/external/bsd/llvm/dist/clang/test/SemaTemplate/cxx1z-fold-expressions.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -std=c++1z -verify %s
2*0a6a1f1dSLionel Sambuc 
sum(T...t)3*0a6a1f1dSLionel Sambuc template<typename ...T> constexpr auto sum(T ...t) { return (... + t); }
product(T...t)4*0a6a1f1dSLionel Sambuc template<typename ...T> constexpr auto product(T ...t) { return (t * ...); }
all(T...t)5*0a6a1f1dSLionel Sambuc template<typename ...T> constexpr auto all(T ...t) { return (true && ... && t); }
dumb(T...t)6*0a6a1f1dSLionel Sambuc template<typename ...T> constexpr auto dumb(T ...t) { return (false && ... && t); }
7*0a6a1f1dSLionel Sambuc 
8*0a6a1f1dSLionel Sambuc static_assert(sum(1, 2, 3, 4, 5) == 15);
9*0a6a1f1dSLionel Sambuc static_assert(product(1, 2, 3, 4, 5) == 120);
10*0a6a1f1dSLionel Sambuc static_assert(!all(true, true, false, true, false));
11*0a6a1f1dSLionel Sambuc static_assert(all(true, true, true, true, true));
12*0a6a1f1dSLionel Sambuc static_assert(!dumb(true, true, true, true, true));
13*0a6a1f1dSLionel Sambuc 
14*0a6a1f1dSLionel Sambuc struct S {
15*0a6a1f1dSLionel Sambuc   int a, b, c, d, e;
16*0a6a1f1dSLionel Sambuc };
increment_all(T &...t)17*0a6a1f1dSLionel Sambuc template<typename ...T> constexpr auto increment_all(T &...t) {
18*0a6a1f1dSLionel Sambuc   (++t, ...);
19*0a6a1f1dSLionel Sambuc }
check()20*0a6a1f1dSLionel Sambuc constexpr bool check() {
21*0a6a1f1dSLionel Sambuc   S s = { 1, 2, 3, 4, 5 };
22*0a6a1f1dSLionel Sambuc   increment_all(s.a, s.b, s.c, s.d, s.e);
23*0a6a1f1dSLionel Sambuc   return s.a == 2 && s.b == 3 && s.c == 4 && s.d == 5 && s.e == 6;
24*0a6a1f1dSLionel Sambuc }
25*0a6a1f1dSLionel Sambuc static_assert(check());
26*0a6a1f1dSLionel Sambuc 
empty()27*0a6a1f1dSLionel Sambuc template<int ...N> void empty() {
28*0a6a1f1dSLionel Sambuc   static_assert((N + ...) == 0);
29*0a6a1f1dSLionel Sambuc   static_assert((N * ...) == 1);
30*0a6a1f1dSLionel Sambuc   static_assert((N | ...) == 0);
31*0a6a1f1dSLionel Sambuc   static_assert((N & ...) == -1);
32*0a6a1f1dSLionel Sambuc   static_assert((N || ...) == false);
33*0a6a1f1dSLionel Sambuc   static_assert((N && ...) == true);
34*0a6a1f1dSLionel Sambuc   (N, ...);
35*0a6a1f1dSLionel Sambuc }
36*0a6a1f1dSLionel Sambuc template void empty<>();
37*0a6a1f1dSLionel Sambuc 
38*0a6a1f1dSLionel Sambuc // An empty fold-expression isn't a null pointer just because it's an integer
39*0a6a1f1dSLionel Sambuc // with value 0.
null_ptr()40*0a6a1f1dSLionel Sambuc template<int ...N> void null_ptr() {
41*0a6a1f1dSLionel Sambuc   void *p = (N + ...); // expected-error {{rvalue of type 'int'}}
42*0a6a1f1dSLionel Sambuc   void *q = (N | ...); // expected-error {{rvalue of type 'int'}}
43*0a6a1f1dSLionel Sambuc }
44*0a6a1f1dSLionel Sambuc template void null_ptr<>(); // expected-note {{in instantiation of}}
45*0a6a1f1dSLionel Sambuc 
bad_empty()46*0a6a1f1dSLionel Sambuc template<int ...N> void bad_empty() {
47*0a6a1f1dSLionel Sambuc   (N - ...); // expected-error {{empty expansion for operator '-' with no fallback}}
48*0a6a1f1dSLionel Sambuc   (N / ...); // expected-error {{empty expansion for operator '/' with no fallback}}
49*0a6a1f1dSLionel Sambuc   (N % ...); // expected-error {{empty expansion for operator '%' with no fallback}}
50*0a6a1f1dSLionel Sambuc   (N = ...); // expected-error {{empty expansion for operator '=' with no fallback}}
51*0a6a1f1dSLionel Sambuc }
52*0a6a1f1dSLionel Sambuc template void bad_empty<>(); // expected-note {{in instantiation of}}
53*0a6a1f1dSLionel Sambuc 
empty_with_base()54*0a6a1f1dSLionel Sambuc template<int ...N> void empty_with_base() {
55*0a6a1f1dSLionel Sambuc   extern int k;
56*0a6a1f1dSLionel Sambuc   (k = ... = N); // expected-warning{{unused}}
57*0a6a1f1dSLionel Sambuc 
58*0a6a1f1dSLionel Sambuc   void (k = ... = N); // expected-error {{expected ')'}} expected-note {{to match}}
59*0a6a1f1dSLionel Sambuc   void ((k = ... = N));
60*0a6a1f1dSLionel Sambuc   (void) (k = ... = N);
61*0a6a1f1dSLionel Sambuc }
62*0a6a1f1dSLionel Sambuc template void empty_with_base<>(); // expected-note {{in instantiation of}}
63*0a6a1f1dSLionel Sambuc template void empty_with_base<1>();
64*0a6a1f1dSLionel Sambuc 
65*0a6a1f1dSLionel Sambuc struct A {
66*0a6a1f1dSLionel Sambuc   struct B {
67*0a6a1f1dSLionel Sambuc     struct C {
68*0a6a1f1dSLionel Sambuc       struct D {
69*0a6a1f1dSLionel Sambuc         int e;
70*0a6a1f1dSLionel Sambuc       } d;
71*0a6a1f1dSLionel Sambuc     } c;
72*0a6a1f1dSLionel Sambuc   } b;
73*0a6a1f1dSLionel Sambuc } a;
apply(T & t,Ts...ts)74*0a6a1f1dSLionel Sambuc template<typename T, typename ...Ts> constexpr decltype(auto) apply(T &t, Ts ...ts) {
75*0a6a1f1dSLionel Sambuc   return (t.*....*ts);
76*0a6a1f1dSLionel Sambuc }
77*0a6a1f1dSLionel Sambuc static_assert(&apply(a, &A::b, &A::B::c, &A::B::C::d, &A::B::C::D::e) == &a.b.c.d.e);
78