tuple-dynamic.H 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file tuple-dynamic.H
  3. /// @brief Using tuples in a dynamic context.
  4. // (c) Daniel Llorens - 2013-2015, 2019
  5. // This library is free software; you can redistribute it and/or modify it under
  6. // the terms of the GNU Lesser General Public License as published by the Free
  7. // Software Foundation; either version 3 of the License, or (at your option) any
  8. // later version.
  9. // TODO Think about struct <int k> { int const value = k; constexpr static int static_value = k; }
  10. // where the tuple can be cast to an array ref.
  11. #pragma once
  12. #include "ra/tuple-list.H"
  13. #include <cassert>
  14. namespace mp {
  15. // like std::make_trom_tuple, but use brace constructor (e.g. for std::array).
  16. // FIXME forward t, e.g. https://vittorioromeo.info/index/blog/capturing_perfectly_forwarded_objects_in_lambdas.html
  17. // until that's fixed, avoid using this for non trivial stuff.
  18. // template <class C, class T>
  19. // constexpr C from_tuple(T const & t)
  20. // {
  21. // return std::apply([&t](auto ... i)
  22. // { return C { std::get<decltype(i)::value>(t) ... }; },
  23. // iota<len<std::decay_t<T>>> {});
  24. // }
  25. // like std::make_trom_tuple, but use brace constructor (e.g. for std::array).
  26. template <class C, class T, int ... i> inline constexpr
  27. C from_tuple_(T && t, int_list<i ...>)
  28. {
  29. return { std::get<i>(std::forward<T>(t)) ... };
  30. }
  31. template <class C, class T> inline constexpr
  32. C from_tuple(T && t)
  33. {
  34. return from_tuple_<C>(std::forward<T>(t), iota<len<std::decay_t<T>>> {});
  35. }
  36. template <class C, class T> inline constexpr
  37. C tuple_values()
  38. {
  39. return std::apply([](auto ... t) { return C { decltype(t)::value ... }; }, T {});
  40. }
  41. template <class C, class T, class I> inline constexpr
  42. C map_indices(I const & i)
  43. {
  44. return std::apply([&i](auto ... t) { return C { i[decltype(t)::value] ... }; }, T {});
  45. };
  46. template <class T, int k=0> inline constexpr
  47. int int_list_index(int i)
  48. {
  49. if constexpr (k>=mp::len<T>) {
  50. return -1;
  51. } else {
  52. return (i==mp::ref<T, k>::value) ? k : int_list_index<T, k+1>(i);
  53. }
  54. }
  55. template <class K, class T, class F, class I = int_t<0>>
  56. constexpr auto
  57. fold_tuple(K && k, T && t, F && f, I && i = int_t<0> {})
  58. {
  59. if constexpr (I::value==std::tuple_size_v<std::decay_t<T>>) {
  60. return k;
  61. } else {
  62. return fold_tuple(f(k, std::get<i>(t)), t, f, int_t<I::value+1> {});
  63. }
  64. }
  65. } // namespace mp