lexicographical_compare.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*!
  2. @file
  3. Defines `boost::hana::lexicographical_compare`.
  4. @copyright Louis Dionne 2013-2017
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_LEXICOGRAPHICAL_COMPARE_HPP
  9. #define BOOST_HANA_LEXICOGRAPHICAL_COMPARE_HPP
  10. #include <boost/hana/fwd/lexicographical_compare.hpp>
  11. #include <boost/hana/bool.hpp>
  12. #include <boost/hana/concept/iterable.hpp>
  13. #include <boost/hana/config.hpp>
  14. #include <boost/hana/core/dispatch.hpp>
  15. #include <boost/hana/drop_front.hpp>
  16. #include <boost/hana/front.hpp>
  17. #include <boost/hana/if.hpp>
  18. #include <boost/hana/is_empty.hpp>
  19. #include <boost/hana/less.hpp>
  20. BOOST_HANA_NAMESPACE_BEGIN
  21. //! @cond
  22. template <typename Xs, typename Ys>
  23. constexpr auto lexicographical_compare_t::operator()(Xs const& xs, Ys const& ys) const {
  24. return hana::lexicographical_compare(xs, ys, hana::less);
  25. }
  26. template <typename Xs, typename Ys, typename Pred>
  27. constexpr auto lexicographical_compare_t::operator()(Xs const& xs, Ys const& ys, Pred const& pred) const {
  28. using It1 = typename hana::tag_of<Xs>::type;
  29. using It2 = typename hana::tag_of<Ys>::type;
  30. using LexicographicalCompare = BOOST_HANA_DISPATCH_IF(
  31. lexicographical_compare_impl<It1>,
  32. hana::Iterable<It1>::value &&
  33. hana::Iterable<It2>::value
  34. );
  35. #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
  36. static_assert(hana::Iterable<It1>::value,
  37. "hana::lexicographical_compare(xs, ys, pred) requires 'xs' to be Iterable");
  38. static_assert(hana::Iterable<It2>::value,
  39. "hana::lexicographical_compare(xs, ys, pred) requires 'ys' to be Iterable");
  40. #endif
  41. return LexicographicalCompare::apply(xs, ys, pred);
  42. }
  43. //! @endcond
  44. template <typename It, bool condition>
  45. struct lexicographical_compare_impl<It, when<condition>> : default_ {
  46. template <typename Xs, typename Ys, typename Pred>
  47. static constexpr auto
  48. helper2(Xs const&, Ys const&, Pred const&, hana::true_)
  49. { return hana::false_c; }
  50. template <typename Xs, typename Ys, typename Pred>
  51. static constexpr auto
  52. helper2(Xs const& xs, Ys const& ys, Pred const& pred, hana::false_)
  53. { return apply(hana::drop_front(xs), hana::drop_front(ys), pred); }
  54. template <typename Xs, typename Ys, typename Pred>
  55. static constexpr auto
  56. helper2(Xs const& xs, Ys const& ys, Pred const& pred, bool is_greater)
  57. { return is_greater ? false : apply(hana::drop_front(xs), hana::drop_front(ys), pred); }
  58. template <typename Xs, typename Ys, typename Pred>
  59. static constexpr auto
  60. helper1(Xs const&, Ys const&, Pred const&, hana::true_)
  61. { return hana::true_c; }
  62. template <typename Xs, typename Ys, typename Pred>
  63. static constexpr auto
  64. helper1(Xs const& xs, Ys const& ys, Pred const& pred, hana::false_)
  65. { return helper2(xs, ys, pred, hana::if_(pred(hana::front(ys), hana::front(xs)), hana::true_c, hana::false_c)); }
  66. template <typename Xs, typename Ys, typename Pred>
  67. static constexpr auto
  68. helper1(Xs const& xs, Ys const& ys, Pred const& pred, bool is_less)
  69. { return is_less ? true : helper2(xs, ys, pred, hana::if_(pred(hana::front(ys), hana::front(xs)), hana::true_c, hana::false_c)); }
  70. template <typename Xs, typename Ys, typename Pred>
  71. static constexpr auto
  72. helper(Xs const&, Ys const& ys, Pred const&, hana::true_)
  73. { return hana::not_(hana::is_empty(ys)); }
  74. template <typename Xs, typename Ys, typename Pred>
  75. static constexpr auto
  76. helper(Xs const& xs, Ys const& ys, Pred const& pred, hana::false_)
  77. { return helper1(xs, ys, pred, hana::if_(pred(hana::front(xs), hana::front(ys)), hana::true_c, hana::false_c)); }
  78. template <typename Xs, typename Ys, typename Pred>
  79. static constexpr auto apply(Xs const& xs, Ys const& ys, Pred const& pred) {
  80. return helper(xs, ys, pred, hana::bool_c<
  81. decltype(hana::is_empty(xs))::value ||
  82. decltype(hana::is_empty(ys))::value
  83. >);
  84. }
  85. };
  86. BOOST_HANA_NAMESPACE_END
  87. #endif // !BOOST_HANA_LEXICOGRAPHICAL_COMPARE_HPP