Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef TEMPLATING_HPP
- #define TEMPLATING_HPP
- #include <functional>
- #include <memory>
- #include <array>
- namespace Templating {
- // since we're dealing with C++11 at the moment, naively implement some stuff
- namespace detail
- {
- template<typename T, T... Ints>
- struct integer_sequence {
- typedef T value_type;
- static constexpr std::size_t size() { return sizeof...(Ints); }
- };
- template<std::size_t... Ints>
- using index_sequence = integer_sequence<std::size_t, Ints...>;
- template<typename T, std::size_t N, T... Is>
- struct make_integer_sequence : make_integer_sequence<T, N-1, N-1, Is...> {};
- template<typename T, T... Is>
- struct make_integer_sequence<T, 0, Is...> : integer_sequence<T, Is...> {};
- template<std::size_t N>
- using make_index_sequence = make_integer_sequence<std::size_t, N>;
- template<typename... T>
- using index_sequence_for = make_index_sequence<sizeof...(T)>;
- 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) {
- return i0 * i1 * i2 * i3 * i4 * i5 * i6 * i7;
- }
- template<int N0, int N1=1, int N2=1, int N3=1, int N4=1, int N5=1, int N6=1, int N7=1>
- 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) {
- return i0 + N0 * (i1 + N1 * (i2 + N2 * (i3 + N3 * (i4 + N4 * (i5 + N5 * (i6 + N6 * i7))))));
- }
- }
- /// Runtime choosing of specialized and prepared templates
- template <typename StructHolder, typename FnSignature, int...NS>
- class Chooser {
- private:
- using FnBind = std::function<FnSignature>;
- std::array<std::shared_ptr<FnBind>, detail::array_size(NS...)> fn_ptrs;
- template<int i, int N0>
- static const FnBind get_ptr() { return &StructHolder::template run<i%N0>; }
- template<int i, int N0, int N1>
- static const FnBind get_ptr() { return &StructHolder::template run<i%N0, (i/N0)%N1>; }
- template<int i, int N0, int N1, int N2>
- static const FnBind get_ptr() { return &StructHolder::template run<i%N0, (i/N0)%N1, (i/(N0*N1))%N2>; }
- template<int i, int N0, int N1, int N2, int N3>
- static const FnBind get_ptr() { return &StructHolder::template run<i%N0, (i/N0)%N1, (i/(N0*N1))%N2, (i/(N0*N1*N2))%N3>; }
- template<int i, int N0, int N1, int N2, int N3, int N4>
- 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>; }
- template<int i, int N0, int N1, int N2, int N3, int N4, int N5>
- 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>; }
- template<int i, int N0, int N1, int N2, int N3, int N4, int N5, int N6>
- 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>; }
- template<int i, int N0, int N1, int N2, int N3, int N4, int N5, int N6, int N7>
- 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>; }
- template <std::size_t... I>
- void combination_maker(const detail::index_sequence<I...>) {
- fn_ptrs = {std::make_shared<FnBind>(get_ptr<I, NS...>())...};
- }
- public:
- /// Prepare all possible combinations of the template function
- Chooser() {
- combination_maker(detail::make_index_sequence<detail::array_size(NS...)>{});
- }
- ~Chooser() {}
- /// Get std::function of the specialized function deduced from given runtime parameters
- template <typename...Indices>
- FnBind const& operator()(Indices... indices) const {
- static_assert (sizeof...(indices) == sizeof...(NS), "Template called with inappropriate number of arguments.");
- return *fn_ptrs[detail::flatten<NS...>(indices...)];
- }
- };
- }
- /*
- struct TestCase {
- template<int i, int j, int k, int l>
- static void run(const char* message) {
- std::cout << "Kernel: " << i << "," << j << "," << k << "," << l << "; message: " << message << std::endl;
- }
- };
- #include <iostream>
- int main()
- {
- Templating::Chooser<TestCase, void(const char*), 2, 2, 3, 2> runner;
- runner(0,0,0,1)("Hi");
- runner(0,1,0,0)("this");
- runner(1,0,1,1)("is");
- runner(1,1,2,0)("test");
- }
- */
- #endif // end header
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement