SHARE
TWEET

Untitled

a guest Aug 25th, 2019 73 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #ifndef TEMPLATING_HPP
  2. #define TEMPLATING_HPP
  3.  
  4. #include <functional>
  5. #include <memory>
  6. #include <array>
  7.  
  8. namespace Templating {
  9.  
  10.     // since we're dealing with C++11 at the moment, naively implement some stuff
  11.     namespace detail
  12.     {
  13.         template<typename T, T... Ints>
  14.         struct integer_sequence {
  15.             typedef T value_type;
  16.             static constexpr std::size_t size() { return sizeof...(Ints); }
  17.         };
  18.  
  19.         template<std::size_t... Ints>
  20.         using index_sequence = integer_sequence<std::size_t, Ints...>;
  21.  
  22.         template<typename T, std::size_t N, T... Is>
  23.         struct make_integer_sequence : make_integer_sequence<T, N-1, N-1, Is...> {};
  24.  
  25.         template<typename T, T... Is>
  26.         struct make_integer_sequence<T, 0, Is...> : integer_sequence<T, Is...> {};
  27.  
  28.         template<std::size_t N>
  29.         using make_index_sequence = make_integer_sequence<std::size_t, N>;
  30.  
  31.         template<typename... T>
  32.         using index_sequence_for = make_index_sequence<sizeof...(T)>;
  33.  
  34.  
  35.         constexpr int array_size(int i0, int i1=1, int i2=1, int i3=1, int i4=1, int i5=1, int i6=1, int i7=1) {
  36.             return i0 * i1 * i2 * i3 * i4 * i5 * i6 * i7;
  37.         }
  38.  
  39.         template<int N0, int N1=1, int N2=1, int N3=1, int N4=1, int N5=1, int N6=1, int N7=1>
  40.         constexpr int flatten(int i0, int i1=0, int i2=0, int i3=0, int i4=0, int i5=0, int i6=0, int i7=0) {
  41.             return i0 + N0 * (i1 + N1 * (i2 + N2 * (i3 + N3 * (i4 + N4 * (i5 + N5 * (i6 + N6 * i7))))));
  42.         }
  43.  
  44.     }
  45.  
  46.     /// Runtime choosing of specialized and prepared templates
  47.     template <typename StructHolder, typename FnSignature, int...NS>
  48.     class Chooser {
  49.  
  50.     private:
  51.  
  52.         using FnBind = std::function<FnSignature>;
  53.         std::array<std::shared_ptr<FnBind>, detail::array_size(NS...)> fn_ptrs;
  54.  
  55.         template<int i, int N0>
  56.         static const FnBind get_ptr() { return &StructHolder::template run<i%N0>; }
  57.         template<int i, int N0, int N1>
  58.         static const FnBind get_ptr() { return &StructHolder::template run<i%N0, (i/N0)%N1>; }
  59.         template<int i, int N0, int N1, int N2>
  60.         static const FnBind get_ptr() { return &StructHolder::template run<i%N0, (i/N0)%N1, (i/(N0*N1))%N2>; }
  61.         template<int i, int N0, int N1, int N2, int N3>
  62.         static const FnBind get_ptr() { return &StructHolder::template run<i%N0, (i/N0)%N1, (i/(N0*N1))%N2, (i/(N0*N1*N2))%N3>; }
  63.         template<int i, int N0, int N1, int N2, int N3, int N4>
  64.         static const FnBind get_ptr() { return &StructHolder::template run<i%N0, (i/N0)%N1, (i/(N0*N1))%N2, (i/(N0*N1*N2))%N3, (i/(N0*N1*N2*N3))%N4>; }
  65.         template<int i, int N0, int N1, int N2, int N3, int N4, int N5>
  66.         static const FnBind get_ptr() { return &StructHolder::template run<i%N0, (i/N0)%N1, (i/(N0*N1))%N2, (i/(N0*N1*N2))%N3, (i/(N0*N1*N2*N3))%N4, (i/(N0*N1*N2*N3*N4))%N5>; }
  67.         template<int i, int N0, int N1, int N2, int N3, int N4, int N5, int N6>
  68.         static const FnBind get_ptr() { return &StructHolder::template run<i%N0, (i/N0)%N1, (i/(N0*N1))%N2, (i/(N0*N1*N2))%N3, (i/(N0*N1*N2*N3))%N4, (i/(N0*N1*N2*N3*N4))%N5, (i/(N0*N1*N2*N3*N4*N5))%N6>; }
  69.         template<int i, int N0, int N1, int N2, int N3, int N4, int N5, int N6, int N7>
  70.         static const FnBind get_ptr() { return &StructHolder::template run<i%N0, (i/N0)%N1, (i/(N0*N1))%N2, (i/(N0*N1*N2))%N3, (i/(N0*N1*N2*N3))%N4, (i/(N0*N1*N2*N3*N4))%N5, (i/(N0*N1*N2*N3*N4*N5))%N6, (i/(N0*N1*N2*N3*N4*N5*N6))%N7>; }
  71.  
  72.         template <std::size_t... I>
  73.         void combination_maker(const detail::index_sequence<I...>) {
  74.             fn_ptrs = {std::make_shared<FnBind>(get_ptr<I, NS...>())...};
  75.         }
  76.  
  77.     public:
  78.  
  79.         /// Prepare all possible combinations of the template function
  80.         Chooser() {
  81.             combination_maker(detail::make_index_sequence<detail::array_size(NS...)>{});
  82.         }
  83.  
  84.         ~Chooser() {}
  85.  
  86.         /// Get std::function of the specialized function deduced from given runtime parameters
  87.         template <typename...Indices>
  88.         FnBind const& operator()(Indices... indices) const {
  89.             static_assert (sizeof...(indices) == sizeof...(NS), "Template called with inappropriate number of arguments.");
  90.             return *fn_ptrs[detail::flatten<NS...>(indices...)];
  91.         }
  92.     };
  93.  
  94. }
  95.  
  96.  
  97. /*
  98. struct TestCase {
  99.  
  100.     template<int i, int j, int k, int l>
  101.     static void run(const char* message) {
  102.         std::cout << "Kernel: " << i << "," << j << "," << k << "," << l << "; message: " << message << std::endl;
  103.     }
  104.  
  105. };
  106.  
  107. #include <iostream>
  108.  
  109. int main()
  110. {
  111.     Templating::Chooser<TestCase, void(const char*), 2, 2, 3, 2> runner;
  112.     runner(0,0,0,1)("Hi");
  113.     runner(0,1,0,0)("this");
  114.     runner(1,0,1,1)("is");
  115.     runner(1,1,2,0)("test");
  116.  
  117. }
  118. */
  119.  
  120. #endif // end header
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top