111
|
1 // Testcase from P0170R1
|
131
|
2 // { dg-do compile { target c++17 } }
|
111
|
3
|
|
4 auto monoid = [](auto v) { return [=] { return v; }; };
|
|
5 auto add = [](auto m1) constexpr {
|
|
6 auto ret = m1();
|
|
7 return [=](auto m2) mutable {
|
|
8 auto m1val = m1();
|
|
9 auto plus = [=] (auto m2val) mutable constexpr
|
|
10 { return m1val += m2val; };
|
|
11 ret = plus(m2());
|
|
12 return monoid(ret);
|
|
13 };
|
|
14 };
|
|
15
|
|
16 int main()
|
|
17 {
|
|
18 constexpr auto zero = monoid(0);
|
|
19 constexpr auto one = monoid(1);
|
|
20 static_assert(add(one)(zero)() == one()); // OK
|
|
21 // Since 'two' below is not declared constexpr, an evaluation of its constexpr
|
|
22 // member function call operator can not perform an lvalue-to-rvalue conversion
|
|
23 // on one of its subobjects (that represents its capture) in a constant
|
|
24 // expression.
|
|
25 auto two = monoid(2);
|
|
26 if (!(two() == 2)) __builtin_abort(); // OK, not a constant expression.
|
131
|
27 static_assert(add(one)(one)() == two()); // { dg-error "|in .constexpr. expansion of " } two() is not a constant expression
|
111
|
28 static_assert(add(one)(one)() == monoid(2)()); // OK
|
|
29 }
|