Guest User

Untitled

a guest
Aug 25th, 2019
77
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