Mercurial > hg > CbC > CbC_gcc
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/testsuite/g++.dg/cpp1z/pr85569.C Thu Feb 13 11:34:05 2020 +0900 @@ -0,0 +1,94 @@ +// { dg-do compile { target c++17 } } + +#include <utility> +#include <tuple> +#include <functional> + +#define LIFT_FWD(x) std::forward<decltype(x)>(x) + +template <typename T> +inline +constexpr +auto +equal( + T &&t) +{ + return [t = std::forward<T>(t)](const auto& obj) + -> decltype(obj == t) + { + return obj == t; + }; +} + +template <typename F, typename T> +struct is_tuple_invocable; + +template <typename F, typename ... Ts> +struct is_tuple_invocable<F, std::tuple<Ts...>> +{ + using type = typename std::is_invocable<F, Ts...>::type; +}; + +template <typename F> +inline +constexpr +auto +compose( + F&& f +) + noexcept +-> F +{ + return std::forward<F>(f); +} + +namespace detail { + template <typename F, typename Tail, typename ... T> + inline + constexpr + auto + compose( + std::true_type, + F&& f, + Tail&& tail, + T&& ... objs) + noexcept(noexcept(f(tail(std::forward<T>(objs)...)))) + -> decltype(f(tail(std::forward<T>(objs)...))) + { + return f(tail(std::forward<T>(objs)...)); + } +} +template <typename F, typename ... Fs> +inline +constexpr +auto +compose( + F&& f, + Fs&&... fs) +{ + return [f = std::forward<F>(f), tail = compose(std::forward<Fs>(fs)...)] + (auto&& ... objs) + -> decltype(detail::compose(typename std::is_invocable<decltype(compose(std::forward<Fs>(fs)...)), decltype(objs)...>::type{}, + f, + compose(std::forward<Fs>(fs)...), + LIFT_FWD(objs)...)) + { + using tail_type = decltype(compose(std::forward<Fs>(fs)...)); + +#ifndef NOT_VIA_TUPLE + using args_type = std::tuple<decltype(objs)...>; + constexpr auto unitail = typename is_tuple_invocable<tail_type, args_type>::type{}; +#else + constexpr auto unitail = typename std::is_invocable<tail_type, decltype(objs)...>::type{}; +#endif + + return detail::compose(unitail, f, tail, LIFT_FWD(objs)...); + }; +} + +template <auto N> +constexpr auto eq = equal(N); + +static_assert(compose(eq<3>, + std::plus<>{})(1,2), + "compose is constexpr");