選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

63 行
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 and_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::and_t and_ { };
  21. namespace __impl
  22. {
  23. template <typename T, typename = void>
  24. struct and_impl
  25. : and_impl<T, when<true>>
  26. { };
  27. template <typename T, bool condition>
  28. struct and_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, static_cast<Y&&>(y), x); }
  34. };
  35. template <typename X, typename Y>
  36. constexpr auto and_t::operator()(X&& x, Y&& y) const
  37. {
  38. using tag_type = tag_of<X>;
  39. using and_impl_type = and_impl<tag_type>;
  40. return and_impl_type::apply(std::forward<X>(x), std::forward<Y>(y));
  41. };
  42. template <typename X, typename ...Y>
  43. constexpr auto and_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. }