25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

73 satır
2.1 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/intern/has_value.h>
  7. #include <cpputils/mp/intern/comparable_equal.h>
  8. #include <cpputils/mp/operations/if.h>
  9. #include <cpputils/mp/operations/value.h>
  10. namespace utl {
  11. namespace mp {
  12. namespace __impl
  13. {
  14. struct equal_t
  15. {
  16. template<typename L, typename R>
  17. constexpr auto operator()(const L& l, const R& r) const;
  18. };
  19. }
  20. constexpr __impl::equal_t equal { };
  21. namespace __impl
  22. {
  23. template <typename L, typename R, typename = void>
  24. struct equal_impl
  25. : equal_impl<L, R, when<true>>
  26. { };
  27. template <typename L, typename R, bool condition>
  28. struct equal_impl<L, R, when<condition>>
  29. : default_
  30. {
  31. template <typename ...Args>
  32. static constexpr auto apply(Args&& ...)
  33. { return c_false; }
  34. };
  35. template <typename T, typename U>
  36. struct equal_impl<T, U, when<intern::comparable_equal<T, U>::value>>
  37. {
  38. template <typename X, typename Y>
  39. static constexpr auto apply(X&& x, Y&& y)
  40. { return static_cast<X&&>(x) == static_cast<Y&&>(y); }
  41. };
  42. template <typename C>
  43. struct equal_impl<C, C, when<intern::has_value<C>::value>>
  44. {
  45. template <typename X, typename Y>
  46. static constexpr auto apply(const X&, const Y&)
  47. {
  48. constexpr auto eq = equal(value<X>(), value<Y>());
  49. constexpr bool truth_value = if_ (eq, true, false);
  50. return c_bool_t<truth_value> { };
  51. }
  52. };
  53. template<typename L, typename R>
  54. constexpr auto equal_t::operator()(const L& l, const R& r) const
  55. {
  56. using l_tag_type = tag_of<L>;
  57. using r_tag_type = tag_of<R>;
  58. using equal_type = equal_impl<l_tag_type, r_tag_type>;
  59. return equal_type::apply(l, r);
  60. }
  61. }
  62. }
  63. }