Mercurial > hg > CbC > CbC_gcc
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"); |