You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 line
1.6 KiB

  1. #pragma once
  2. #include <cpputils/mp/core/const.h>
  3. #include <cpputils/mp/misc/when.h>
  4. #include <cpputils/mp/misc/tag_of.h>
  5. #include <cpputils/mp/misc/default.h>
  6. #include <cpputils/mp/operations/if.h>
  7. #include <cpputils/mp/intern/fold_left.h>
  8. namespace utl {
  9. namespace mp {
  10. namespace __impl
  11. {
  12. struct or_t
  13. {
  14. template<typename X, typename Y>
  15. constexpr auto operator()(X&& x, Y&& y) const;
  16. template<typename X, typename... Y>
  17. constexpr auto operator()(X&& x, Y&&... y) const;
  18. };
  19. }
  20. constexpr __impl::or_t or_ { };
  21. namespace __impl
  22. {
  23. template <typename T, typename = void>
  24. struct or_impl
  25. : or_impl<T, when<true>>
  26. { };
  27. template <typename T, bool condition>
  28. struct or_impl<T, when<condition>>
  29. : default_
  30. {
  31. template <typename X, typename Y>
  32. static constexpr auto apply(X&& x, Y&& y)
  33. { return if_(x, x, static_cast<Y&&>(y)); }
  34. };
  35. template <typename X, typename Y>
  36. constexpr auto or_t::operator()(X&& x, Y&& y) const
  37. {
  38. using tag_type = tag_of<X>;
  39. using or_impl_type = or_impl<tag_type>;
  40. return or_impl_type::apply(std::forward<X>(x), std::forward<Y>(y));
  41. };
  42. template <typename X, typename ...Y>
  43. constexpr auto or_t::operator()(X&& x, Y&& ...y) const
  44. {
  45. return intern::fold_left(
  46. *this,
  47. static_cast<X&&>(x),
  48. static_cast<Y&&>(y)...
  49. );
  50. }
  51. }
  52. }
  53. }