]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*! |
2 | @file | |
3 | Defines `boost::hana::lexicographical_compare`. | |
4 | ||
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) | |
8 | */ | |
9 | ||
10 | #ifndef BOOST_HANA_LEXICOGRAPHICAL_COMPARE_HPP | |
11 | #define BOOST_HANA_LEXICOGRAPHICAL_COMPARE_HPP | |
12 | ||
13 | #include <boost/hana/fwd/lexicographical_compare.hpp> | |
14 | ||
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> | |
24 | ||
25 | ||
26 | BOOST_HANA_NAMESPACE_BEGIN | |
27 | //! @cond | |
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); | |
31 | } | |
32 | ||
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 | |
41 | ); | |
42 | ||
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"); | |
46 | ||
47 | static_assert(hana::Iterable<It2>::value, | |
48 | "hana::lexicographical_compare(xs, ys, pred) requires 'ys' to be Iterable"); | |
49 | #endif | |
50 | ||
51 | return LexicographicalCompare::apply(xs, ys, pred); | |
52 | } | |
53 | //! @endcond | |
54 | ||
55 | template <typename It, bool condition> | |
56 | struct lexicographical_compare_impl<It, when<condition>> : default_ { | |
57 | template <typename Xs, typename Ys, typename Pred> | |
58 | static constexpr auto | |
59 | helper2(Xs const&, Ys const&, Pred const&, hana::true_) | |
60 | { return hana::false_c; } | |
61 | ||
62 | template <typename Xs, typename Ys, typename Pred> | |
63 | static constexpr auto | |
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); } | |
66 | ||
67 | template <typename Xs, typename Ys, typename Pred> | |
68 | static constexpr auto | |
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); } | |
71 | ||
72 | ||
73 | template <typename Xs, typename Ys, typename Pred> | |
74 | static constexpr auto | |
75 | helper1(Xs const&, Ys const&, Pred const&, hana::true_) | |
76 | { return hana::true_c; } | |
77 | ||
78 | template <typename Xs, typename Ys, typename Pred> | |
79 | static constexpr auto | |
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)); } | |
82 | ||
83 | template <typename Xs, typename Ys, typename Pred> | |
84 | static constexpr auto | |
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)); } | |
87 | ||
88 | ||
89 | template <typename Xs, typename Ys, typename Pred> | |
90 | static constexpr auto | |
91 | helper(Xs const&, Ys const& ys, Pred const&, hana::true_) | |
92 | { return hana::not_(hana::is_empty(ys)); } | |
93 | ||
94 | template <typename Xs, typename Ys, typename Pred> | |
95 | static constexpr auto | |
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)); } | |
98 | ||
99 | ||
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 | |
105 | >); | |
106 | } | |
107 | }; | |
108 | BOOST_HANA_NAMESPACE_END | |
109 | ||
110 | #endif // !BOOST_HANA_LEXICOGRAPHICAL_COMPARE_HPP |