tuple-dynamic.H 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // (c) Daniel Llorens - 2013-2015
  2. // This library is free software; you can redistribute it and/or modify it under
  3. // the terms of the GNU Lesser General Public License as published by the Free
  4. // Software Foundation; either version 3 of the License, or (at your option) any
  5. // later version.
  6. #ifndef RA_TUPLE_DYNAMIC_H
  7. #define RA_TUPLE_DYNAMIC_H
  8. /// @file tuple-dynamic.H
  9. /// @brief Use tuples with dynamic parameters.
  10. // @TODO Think about struct <int k> { int const value = k; static int const static_value = k; }
  11. // where the tuple can be cast to an array ref.
  12. #include <tuple>
  13. #include <cassert>
  14. namespace mp {
  15. template <class T, class C>
  16. struct tuple_copy;
  17. template <class C, class ... t>
  18. struct tuple_copy<std::tuple<t ...>, C>
  19. {
  20. constexpr static C f()
  21. {
  22. return C { {t::value} ... };
  23. }
  24. };
  25. // Do things along a tuple.
  26. template <class T, int k=0>
  27. struct on_tuple;
  28. template <class t0, class ... ti, int k>
  29. struct on_tuple<std::tuple<t0, ti ...>, k>
  30. {
  31. using T = std::tuple<t0, ti ...>;
  32. using next = on_tuple<std::tuple<ti ...>, k+1>;
  33. template <class I, class J> static void map_indices(I const & i, J & j)
  34. {
  35. j[k] = i[t0::value];
  36. next::map_indices(i, j);
  37. }
  38. // @TODO merge with mp::Index?
  39. static int constexpr index(int const q)
  40. {
  41. return (q==t0::value) ? k : next::index(q);
  42. }
  43. // @TODO merge with mp::Ref?
  44. static int constexpr ref(int const i)
  45. {
  46. return k==i ? t0::value : next::ref(i);
  47. }
  48. };
  49. template <int k>
  50. struct on_tuple<std::tuple<>, k>
  51. {
  52. using T = std::tuple<>;
  53. template <class I, class J> static void map_indices(I const & i, J & j)
  54. {
  55. static_assert(j.size()==k, "bad indices in map_indices");
  56. }
  57. template <class I, class T, std::size_t N> static void map_indices(I const & i, std::array<T, N> & j)
  58. {
  59. static_assert(N==k, "bad indices in map_indices");
  60. }
  61. static int constexpr index(int const q)
  62. {
  63. return -1;
  64. }
  65. static int constexpr ref(int const i)
  66. {
  67. static_assert(true, "bad ref");
  68. return -1;
  69. }
  70. };
  71. } // namespace mp
  72. #endif // RA_TUPLE_DYNAMIC_H