comparison gcc/testsuite/g++.dg/cpp1z/pr85569.C @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 // { dg-do compile { target c++17 } }
2
3 #include <utility>
4 #include <tuple>
5 #include <functional>
6
7 #define LIFT_FWD(x) std::forward<decltype(x)>(x)
8
9 template <typename T>
10 inline
11 constexpr
12 auto
13 equal(
14 T &&t)
15 {
16 return [t = std::forward<T>(t)](const auto& obj)
17 -> decltype(obj == t)
18 {
19 return obj == t;
20 };
21 }
22
23 template <typename F, typename T>
24 struct is_tuple_invocable;
25
26 template <typename F, typename ... Ts>
27 struct is_tuple_invocable<F, std::tuple<Ts...>>
28 {
29 using type = typename std::is_invocable<F, Ts...>::type;
30 };
31
32 template <typename F>
33 inline
34 constexpr
35 auto
36 compose(
37 F&& f
38 )
39 noexcept
40 -> F
41 {
42 return std::forward<F>(f);
43 }
44
45 namespace detail {
46 template <typename F, typename Tail, typename ... T>
47 inline
48 constexpr
49 auto
50 compose(
51 std::true_type,
52 F&& f,
53 Tail&& tail,
54 T&& ... objs)
55 noexcept(noexcept(f(tail(std::forward<T>(objs)...))))
56 -> decltype(f(tail(std::forward<T>(objs)...)))
57 {
58 return f(tail(std::forward<T>(objs)...));
59 }
60 }
61 template <typename F, typename ... Fs>
62 inline
63 constexpr
64 auto
65 compose(
66 F&& f,
67 Fs&&... fs)
68 {
69 return [f = std::forward<F>(f), tail = compose(std::forward<Fs>(fs)...)]
70 (auto&& ... objs)
71 -> decltype(detail::compose(typename std::is_invocable<decltype(compose(std::forward<Fs>(fs)...)), decltype(objs)...>::type{},
72 f,
73 compose(std::forward<Fs>(fs)...),
74 LIFT_FWD(objs)...))
75 {
76 using tail_type = decltype(compose(std::forward<Fs>(fs)...));
77
78 #ifndef NOT_VIA_TUPLE
79 using args_type = std::tuple<decltype(objs)...>;
80 constexpr auto unitail = typename is_tuple_invocable<tail_type, args_type>::type{};
81 #else
82 constexpr auto unitail = typename std::is_invocable<tail_type, decltype(objs)...>::type{};
83 #endif
84
85 return detail::compose(unitail, f, tail, LIFT_FWD(objs)...);
86 };
87 }
88
89 template <auto N>
90 constexpr auto eq = equal(N);
91
92 static_assert(compose(eq<3>,
93 std::plus<>{})(1,2),
94 "compose is constexpr");