Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <type_traits>
- #include <utility>
- #include <cassert>
- template< typename E, E first, E ...rest >
- struct front
- {
- static constexpr E value = first;
- };
- template< typename E, template< E > class I, E ...es >
- struct D
- {
- template< E e, typename ...Ts >
- static
- constexpr
- decltype(auto)
- call(Ts &&... ts)
- {
- return I< e >{}(std::forward< Ts >(ts)...);
- }
- template< typename ...Ts >
- using caller = decltype(&D::template call< front< E, es... >::value, Ts... >);
- template< typename ...Ts >
- static constexpr caller< Ts... > callers_[sizeof...(es)] = {D::template call< es, Ts... >...};
- template< std::size_t ...indices >
- constexpr
- std::size_t
- to_sequential_number(E e, std::index_sequence< indices... >) const
- {
- std::size_t i = 0;
- for (E ee : {es...}) {
- if (ee == e) {
- return i;
- }
- ++i;
- }
- assert(false);
- }
- template< typename ...Ts >
- constexpr
- decltype(auto) operator () (E e, Ts &&... ts) const
- {
- return callers_< Ts... >[to_sequential_number(e, std::make_index_sequence< sizeof...(es) >{})](std::forward< Ts >(ts)...);
- }
- };
- template< typename E, template< E > class I, E ...es >
- template< typename ...Ts >
- constexpr typename D< E, I, es... >::template caller< Ts... > D< E, I, es... >::callers_[sizeof...(es)];
- #include <iostream>
- #define PP { std::cout << __PRETTY_FUNCTION__ << std::endl; (std::cout << ... << ts) << std::endl; }
- enum class E
- {
- A,
- B,
- C,
- };
- template< E >
- struct I;
- template<>
- struct I< E::A >
- {
- template< typename ...Ts >
- decltype(auto) operator () (Ts &&... ts) PP
- };
- template<>
- struct I< E::B >
- {
- template< typename ...Ts >
- decltype(auto) operator () (Ts &&... ts) PP
- };
- template<>
- struct I< E::C >
- {
- template< typename ...Ts >
- decltype(auto) operator () (Ts &&... ts) PP
- };
- #include <cstdlib>
- int
- main()
- {
- D< E, I, E::C, E::A, E::B >{}(E::A, 1, -2.1f, '3');
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment