Last active
June 30, 2020 18:40
-
-
Save schaumb/1f0f0931b5133e2611993f0f8975faae to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <tuple> | |
#include <boost/callable_traits.hpp> | |
#include <boost/type_index/ctti_type_index.hpp> | |
#include <boost/preprocessor/seq/for_each.hpp> | |
#include <boost/preprocessor/variadic/to_seq.hpp> | |
template<template <typename> typename Base, std::size_t ...Dependents> | |
struct Depends : Base<Depends<Base, Dependents...>> { | |
constexpr Depends() : Base<Depends<Base, Dependents...>>(*this) {} | |
template<typename T> | |
constexpr Depends(T&&...) : Depends() {} | |
template<typename T> | |
[[noreturn]] constexpr operator T() const { throw 0; } | |
template<typename T> | |
[[noreturn]] constexpr operator T&() const { throw 0; } | |
}; | |
template<typename Lambda> | |
struct lambda_template_result { | |
template<typename ...Ts> | |
using type = std::invoke_result_t<Lambda, Ts...>; | |
}; | |
struct empty {}; | |
struct lam_empty { | |
template<typename T> | |
empty operator()(T&&) { | |
return {}; | |
} | |
}; | |
template<std::size_t V, typename BaseLam = lam_empty> | |
struct Placeholder : Depends<lambda_template_result<BaseLam>::template type, V> {}; | |
template<typename BaseLam> | |
struct BindPlaceholder { | |
}; | |
template <class Fn> | |
struct invocable_template_impl { | |
template<typename Tup, typename = void> | |
struct with_impl { | |
constexpr static bool value = false; | |
}; | |
template<typename...Ts> | |
struct with_impl<std::tuple<Ts...>, std::void_t<decltype(&Fn::template operator() <Ts...>)>> { | |
constexpr static bool value = true; | |
using type = decltype(&Fn::template operator() <Ts...>); | |
}; | |
template<typename ...Ts> | |
constexpr static auto with = with_impl<std::tuple<Ts...>>::value; | |
template<typename ...Ts> | |
using type = typename with_impl<std::tuple<Ts...>>::type; | |
}; | |
template<typename Fun, template <std::size_t> typename PH = Placeholder, std::size_t N = 0, typename Ix = std::decay_t<decltype(std::make_index_sequence<N>())>, typename = void> | |
struct invocable_typeded : invocable_typeded<Fun, PH, N+1> {}; | |
template<typename Fun, template <std::size_t> typename PH, std::size_t N, std::size_t...ix> | |
struct invocable_typeded<Fun, PH, N, std::index_sequence<ix...>, std::enable_if_t<(N > 10)>> { | |
static_assert(N <= 10, "More than 10 template parameter. Possible wrong members / operators are implemented."); | |
}; | |
template<typename Fun, template <std::size_t> typename PH, std::size_t N, std::size_t...ix> | |
struct invocable_typeded<Fun, PH, N, std::index_sequence<ix...>, std::enable_if_t< | |
invocable_template_impl<Fun>::template with<PH<ix+1> ...> >> { | |
using type = typename invocable_template_impl<Fun>::template type<PH<ix+1> ...>; | |
}; | |
#define INVOKABLE(type_param, ...) [] { \ | |
/*BOOST_PP_SEQ_FOR_EACH(INVOKABLE_CREATE_TYPE, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) */ \ | |
return typename invocable_typeded<type_param>::type{}; \ | |
} | |
int main() { | |
auto l = [](int, auto y, auto) { return y; }; | |
auto X = [] { | |
auto il = [](auto& type) { | |
struct C { | |
decltype(type)& first; | |
decltype(type)& second; | |
C(decltype(type)& p) | |
: first(p) | |
, second(p) {} | |
} c(type); | |
return c; | |
}; | |
return Placeholder<1, decltype(il)>{}; | |
}; | |
std::cout << boost::typeindex::ctti_type_index::type_id<std::invoke_result_t<decltype(X)>>().pretty_name() << std::endl; | |
// using res = boost::callable_traits::return_type_t<invocable_template_impl<decltype(l)>::template type<Placeholder<1>, Placeholder<2>>>; | |
//using res = boost::callable_traits::return_type_t<invocable_typeded<decltype(l)>::type>; | |
auto typeded = INVOKABLE(decltype(l), first, second); | |
using res2 = boost::callable_traits::return_type_t<std::invoke_result_t<typeded>>; | |
std::cout << boost::typeindex::ctti_type_index::type_id<res2>().pretty_name() << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment