view gcc/testsuite/g++.dg/cpp1z/constexpr-lambda6.C @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 84e7813d76e9
children
line wrap: on
line source

// Testcase from P0170R1
// { dg-do compile { target c++17 } }

auto monoid = [](auto v) { return [=] { return v; }; };
auto add = [](auto m1) constexpr {
  auto ret = m1();
  return [=](auto m2) mutable {
    auto m1val = m1();
    auto plus = [=] (auto m2val) mutable constexpr
      { return m1val += m2val; };
    ret = plus(m2());
    return monoid(ret);
  };
};

int main()
{
  constexpr auto zero = monoid(0);
  constexpr auto one = monoid(1);
  static_assert(add(one)(zero)() == one()); // OK
  // Since 'two' below is not declared constexpr, an evaluation of its constexpr
  // member function call operator can not perform an lvalue-to-rvalue conversion
  // on one of its subobjects (that represents its capture) in a constant
  // expression.
  auto two = monoid(2);
  if (!(two() == 2)) __builtin_abort(); // OK, not a constant expression.
  static_assert(add(one)(one)() == two()); // { dg-error "|in .constexpr. expansion of " } two() is not a constant expression
  static_assert(add(one)(one)() == monoid(2)()); // OK
}