File indexing completed on 2025-01-18 09:38:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_LEXICOGRAPHICAL_COMPARE_HPP
0011 #define BOOST_HANA_LEXICOGRAPHICAL_COMPARE_HPP
0012
0013 #include <boost/hana/fwd/lexicographical_compare.hpp>
0014
0015 #include <boost/hana/bool.hpp>
0016 #include <boost/hana/concept/iterable.hpp>
0017 #include <boost/hana/config.hpp>
0018 #include <boost/hana/core/dispatch.hpp>
0019 #include <boost/hana/drop_front.hpp>
0020 #include <boost/hana/front.hpp>
0021 #include <boost/hana/if.hpp>
0022 #include <boost/hana/is_empty.hpp>
0023 #include <boost/hana/less.hpp>
0024
0025
0026 namespace boost { namespace hana {
0027
0028 template <typename Xs, typename Ys>
0029 constexpr auto lexicographical_compare_t::operator()(Xs const& xs, Ys const& ys) const {
0030 return hana::lexicographical_compare(xs, ys, hana::less);
0031 }
0032
0033 template <typename Xs, typename Ys, typename Pred>
0034 constexpr auto lexicographical_compare_t::operator()(Xs const& xs, Ys const& ys, Pred const& pred) const {
0035 using It1 = typename hana::tag_of<Xs>::type;
0036 using It2 = typename hana::tag_of<Ys>::type;
0037 using LexicographicalCompare = BOOST_HANA_DISPATCH_IF(
0038 lexicographical_compare_impl<It1>,
0039 hana::Iterable<It1>::value &&
0040 hana::Iterable<It2>::value
0041 );
0042
0043 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0044 static_assert(hana::Iterable<It1>::value,
0045 "hana::lexicographical_compare(xs, ys, pred) requires 'xs' to be Iterable");
0046
0047 static_assert(hana::Iterable<It2>::value,
0048 "hana::lexicographical_compare(xs, ys, pred) requires 'ys' to be Iterable");
0049 #endif
0050
0051 return LexicographicalCompare::apply(xs, ys, pred);
0052 }
0053
0054
0055 template <typename It, bool condition>
0056 struct lexicographical_compare_impl<It, when<condition>> : default_ {
0057 template <typename Xs, typename Ys, typename Pred>
0058 static constexpr auto
0059 helper2(Xs const&, Ys const&, Pred const&, hana::true_)
0060 { return hana::false_c; }
0061
0062 template <typename Xs, typename Ys, typename Pred>
0063 static constexpr auto
0064 helper2(Xs const& xs, Ys const& ys, Pred const& pred, hana::false_)
0065 { return apply(hana::drop_front(xs), hana::drop_front(ys), pred); }
0066
0067 template <typename Xs, typename Ys, typename Pred>
0068 static constexpr auto
0069 helper2(Xs const& xs, Ys const& ys, Pred const& pred, bool is_greater)
0070 { return is_greater ? false : apply(hana::drop_front(xs), hana::drop_front(ys), pred); }
0071
0072
0073 template <typename Xs, typename Ys, typename Pred>
0074 static constexpr auto
0075 helper1(Xs const&, Ys const&, Pred const&, hana::true_)
0076 { return hana::true_c; }
0077
0078 template <typename Xs, typename Ys, typename Pred>
0079 static constexpr auto
0080 helper1(Xs const& xs, Ys const& ys, Pred const& pred, hana::false_)
0081 { return helper2(xs, ys, pred, hana::if_(pred(hana::front(ys), hana::front(xs)), hana::true_c, hana::false_c)); }
0082
0083 template <typename Xs, typename Ys, typename Pred>
0084 static constexpr auto
0085 helper1(Xs const& xs, Ys const& ys, Pred const& pred, bool is_less)
0086 { return is_less ? true : helper2(xs, ys, pred, hana::if_(pred(hana::front(ys), hana::front(xs)), hana::true_c, hana::false_c)); }
0087
0088
0089 template <typename Xs, typename Ys, typename Pred>
0090 static constexpr auto
0091 helper(Xs const&, Ys const& ys, Pred const&, hana::true_)
0092 { return hana::not_(hana::is_empty(ys)); }
0093
0094 template <typename Xs, typename Ys, typename Pred>
0095 static constexpr auto
0096 helper(Xs const& xs, Ys const& ys, Pred const& pred, hana::false_)
0097 { return helper1(xs, ys, pred, hana::if_(pred(hana::front(xs), hana::front(ys)), hana::true_c, hana::false_c)); }
0098
0099
0100 template <typename Xs, typename Ys, typename Pred>
0101 static constexpr auto apply(Xs const& xs, Ys const& ys, Pred const& pred) {
0102 return helper(xs, ys, pred, hana::bool_c<
0103 decltype(hana::is_empty(xs))::value ||
0104 decltype(hana::is_empty(ys))::value
0105 >);
0106 }
0107 };
0108 }}
0109
0110 #endif