aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp23/lambda-scope4.C
blob: 9442db3f95678511f8d159ba639392b2bd0d1352 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// P2036R3 - Change scope of lambda trailing-return-type
// PR c++/102610
// { dg-do compile { target c++17 } }

struct integral_constant {
  using type = integral_constant;
};
template <bool> using __bool_constant = integral_constant;
template <typename _Fn, typename>
struct is_invocable : __bool_constant<true> {};
int forward() { return 42; }
template <typename...> class tuple;
struct plus {
  template <typename _Tp, typename _Up>
  constexpr auto operator()(_Tp __t, _Up __u) {
    return __t > __u;
  }
};
constexpr auto equal() {
  int t = 0;
  return [t = 3](auto obj) -> decltype(obj == t) { return t; };
}
template <typename> struct is_tuple_invocable;
template <typename... Ts> struct is_tuple_invocable<tuple<Ts...>> {
  using type = typename is_invocable<Ts...>::type;
};
namespace detail {
template <typename F, typename Tail, typename... T>
constexpr auto compose(__bool_constant<true>, F f, Tail tail, T... objs) {
  return f(tail(objs...));
}
} // namespace detail
template <typename F, typename... Fs> constexpr auto compose(F f, Fs... fs) {
  return [f, tail(fs...)](auto... objs) {
    auto unitail =
        typename is_tuple_invocable<tuple<decltype(objs)...>>::type{};
    return detail::compose(unitail, f, tail, objs...);
  };
}
template <auto> constexpr auto eq = equal();
static_assert(compose(eq<3>, plus{})(1, 2));