3 Defines `boost::hana::lexicographical_compare`.
5 @copyright Louis Dionne 2013-2016
6 Distributed under the Boost Software License, Version 1.0.
7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
10 #ifndef BOOST_HANA_LEXICOGRAPHICAL_COMPARE_HPP
11 #define BOOST_HANA_LEXICOGRAPHICAL_COMPARE_HPP
13 #include <boost/hana/fwd/lexicographical_compare.hpp>
15 #include <boost/hana/bool.hpp>
16 #include <boost/hana/concept/iterable.hpp>
17 #include <boost/hana/config.hpp>
18 #include <boost/hana/core/dispatch.hpp>
19 #include <boost/hana/drop_front.hpp>
20 #include <boost/hana/front.hpp>
21 #include <boost/hana/if.hpp>
22 #include <boost/hana/is_empty.hpp>
23 #include <boost/hana/less.hpp>
26 BOOST_HANA_NAMESPACE_BEGIN
28 template <typename Xs, typename Ys>
29 constexpr auto lexicographical_compare_t::operator()(Xs const& xs, Ys const& ys) const {
30 return hana::lexicographical_compare(xs, ys, hana::less);
33 template <typename Xs, typename Ys, typename Pred>
34 constexpr auto lexicographical_compare_t::operator()(Xs const& xs, Ys const& ys, Pred const& pred) const {
35 using It1 = typename hana::tag_of<Xs>::type;
36 using It2 = typename hana::tag_of<Ys>::type;
37 using LexicographicalCompare = BOOST_HANA_DISPATCH_IF(
38 lexicographical_compare_impl<It1>,
39 hana::Iterable<It1>::value &&
40 hana::Iterable<It2>::value
43 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
44 static_assert(hana::Iterable<It1>::value,
45 "hana::lexicographical_compare(xs, ys, pred) requires 'xs' to be Iterable");
47 static_assert(hana::Iterable<It2>::value,
48 "hana::lexicographical_compare(xs, ys, pred) requires 'ys' to be Iterable");
51 return LexicographicalCompare::apply(xs, ys, pred);
55 template <typename It, bool condition>
56 struct lexicographical_compare_impl<It, when<condition>> : default_ {
57 template <typename Xs, typename Ys, typename Pred>
59 helper2(Xs const&, Ys const&, Pred const&, hana::true_)
60 { return hana::false_c; }
62 template <typename Xs, typename Ys, typename Pred>
64 helper2(Xs const& xs, Ys const& ys, Pred const& pred, hana::false_)
65 { return apply(hana::drop_front(xs), hana::drop_front(ys), pred); }
67 template <typename Xs, typename Ys, typename Pred>
69 helper2(Xs const& xs, Ys const& ys, Pred const& pred, bool is_greater)
70 { return is_greater ? false : apply(hana::drop_front(xs), hana::drop_front(ys), pred); }
73 template <typename Xs, typename Ys, typename Pred>
75 helper1(Xs const&, Ys const&, Pred const&, hana::true_)
76 { return hana::true_c; }
78 template <typename Xs, typename Ys, typename Pred>
80 helper1(Xs const& xs, Ys const& ys, Pred const& pred, hana::false_)
81 { return helper2(xs, ys, pred, hana::if_(pred(hana::front(ys), hana::front(xs)), hana::true_c, hana::false_c)); }
83 template <typename Xs, typename Ys, typename Pred>
85 helper1(Xs const& xs, Ys const& ys, Pred const& pred, bool is_less)
86 { return is_less ? true : helper2(xs, ys, pred, hana::if_(pred(hana::front(ys), hana::front(xs)), hana::true_c, hana::false_c)); }
89 template <typename Xs, typename Ys, typename Pred>
91 helper(Xs const&, Ys const& ys, Pred const&, hana::true_)
92 { return hana::not_(hana::is_empty(ys)); }
94 template <typename Xs, typename Ys, typename Pred>
96 helper(Xs const& xs, Ys const& ys, Pred const& pred, hana::false_)
97 { return helper1(xs, ys, pred, hana::if_(pred(hana::front(xs), hana::front(ys)), hana::true_c, hana::false_c)); }
100 template <typename Xs, typename Ys, typename Pred>
101 static constexpr auto apply(Xs const& xs, Ys const& ys, Pred const& pred) {
102 return helper(xs, ys, pred, hana::bool_c<
103 decltype(hana::is_empty(xs))::value ||
104 decltype(hana::is_empty(ys))::value
108 BOOST_HANA_NAMESPACE_END
110 #endif // !BOOST_HANA_LEXICOGRAPHICAL_COMPARE_HPP