tuple-dynamic.H 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. /// @file tuple-dynamic.H
  7. /// @brief Use tuples with dynamic parameters.
  8. // TODO Think about struct <int k> { int const value = k; constexpr static int static_value = k; }
  9. // where the tuple can be cast to an array ref.
  10. #pragma once
  11. #include <tuple>
  12. #include <cassert>
  13. namespace mp {
  14. template <class T, class C> struct tuple_copy;
  15. template <class C, class ... t>
  16. struct tuple_copy<std::tuple<t ...>, C>
  17. {
  18. constexpr static C f() { return { t::value ... }; } // clang bug with -Wmissing-braces TODO
  19. };
  20. template <class T, class C> struct map_indices;
  21. template <class C, class ... t>
  22. struct map_indices<std::tuple<t ...>, C>
  23. {
  24. template <class I> constexpr static C f(I const & i) { return { i[t::value] ... }; };
  25. };
  26. // Do things along a tuple.
  27. template <class T, int k=0> 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. constexpr static int index(int const q)
  34. {
  35. return (q==t0::value) ? k : next::index(q);
  36. }
  37. constexpr static int ref(int const i)
  38. {
  39. return k==i ? t0::value : next::ref(i);
  40. }
  41. };
  42. template <int k>
  43. struct on_tuple<std::tuple<>, k>
  44. {
  45. using T = std::tuple<>;
  46. template <class I, class T, std::size_t N> static void map_indices(I const & i, std::array<T, N> & j)
  47. {
  48. static_assert(N==k, "bad indices in map_indices");
  49. }
  50. constexpr static int index(int const q)
  51. {
  52. return -1;
  53. }
  54. constexpr static int ref(int const i)
  55. {
  56. static_assert(true, "bad ref");
  57. return -1;
  58. }
  59. };
  60. } // namespace mp