Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

61 Zeilen
2.0 KiB

  1. #pragma once
  2. #include <utility>
  3. #include <cpputils/mp/misc/tag_of.h>
  4. #include <cpputils/mp/misc/default.h>
  5. #include <cpputils/mp/operations/at.h>
  6. #include <cpputils/mp/operations/length.h>
  7. #include <cpputils/mp/operations/unpack.fwd.h>
  8. namespace utl {
  9. namespace mp {
  10. namespace __impl
  11. {
  12. template<typename T, typename = void>
  13. struct unpack_impl
  14. : unpack_impl<T, when<true>>
  15. { };
  16. template<typename T>
  17. struct unpack_impl<T, when<
  18. !is_default<length_impl<tag_of<T>>>::value &&
  19. !is_default<at_impl <tag_of<T>>>::value>>
  20. {
  21. template<typename Xs, typename F, size_t... I>
  22. static constexpr auto unpack_helper(Xs&& xs, F&& f, std::index_sequence<I...>)
  23. { return std::forward<F>(f)(at_c<I>(std::forward<Xs>(xs))...); }
  24. template<typename Xs, typename F>
  25. static constexpr auto apply(Xs&& xs, F&& f)
  26. {
  27. constexpr size_t N = decltype(length(xs))::value;
  28. return unpack_helper(std::forward<Xs>(xs), std::forward<F>(f), std::make_index_sequence<N> { });
  29. }
  30. };
  31. template<typename T, size_t N>
  32. struct unpack_impl<T[N]>
  33. {
  34. template<typename Xs, typename F, size_t... I>
  35. static constexpr auto unpack_helper(Xs&& xs, F&& f, std::index_sequence<I...>)
  36. { return std::forward<F>(f)(std::forward<Xs>(xs)[I]...); }
  37. template<typename Xs, typename F>
  38. static constexpr auto apply(Xs&& xs, F&& f)
  39. { return unpack_helper(std::forward<Xs>(xs), std::forward<F>(f), std::make_index_sequence<N> { }); }
  40. };
  41. // TODO: Pair, Struct
  42. template<typename Xs, typename F>
  43. constexpr auto unpack_t::operator()(Xs&& xs, F&& f) const
  44. {
  45. using tag_type = tag_of<Xs>;
  46. using unpack_impl_type = unpack_impl<tag_type>;
  47. return unpack_impl_type::apply(std::forward<Xs>(xs), std::forward<F>(f));
  48. }
  49. }
  50. }
  51. }