]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/include/boost/hana/less.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / less.hpp
CommitLineData
7c673cae
FG
1/*!
2@file
3Defines `boost::hana::less`.
4
5@copyright Louis Dionne 2013-2016
6Distributed 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_LESS_HPP
11#define BOOST_HANA_LESS_HPP
12
13#include <boost/hana/fwd/less.hpp>
14
15#include <boost/hana/and.hpp>
16#include <boost/hana/bool.hpp>
17#include <boost/hana/concept/constant.hpp>
18#include <boost/hana/concept/orderable.hpp>
19#include <boost/hana/concept/product.hpp>
20#include <boost/hana/concept/sequence.hpp>
21#include <boost/hana/config.hpp>
22#include <boost/hana/core/common.hpp>
23#include <boost/hana/core/to.hpp>
24#include <boost/hana/core/dispatch.hpp>
25#include <boost/hana/detail/concepts.hpp>
26#include <boost/hana/detail/has_common_embedding.hpp>
27#include <boost/hana/detail/nested_than.hpp> // required by fwd decl
28#include <boost/hana/equal.hpp>
29#include <boost/hana/first.hpp>
30#include <boost/hana/if.hpp>
31#include <boost/hana/less_equal.hpp>
32#include <boost/hana/lexicographical_compare.hpp>
33#include <boost/hana/or.hpp>
34#include <boost/hana/second.hpp>
35#include <boost/hana/value.hpp>
36
37
38BOOST_HANA_NAMESPACE_BEGIN
39 //! @cond
40 template <typename X, typename Y>
41 constexpr auto less_t::operator()(X&& x, Y&& y) const {
42 using T = typename hana::tag_of<X>::type;
43 using U = typename hana::tag_of<Y>::type;
44 using Less = BOOST_HANA_DISPATCH_IF(decltype(less_impl<T, U>{}),
45 hana::Orderable<T>::value &&
46 hana::Orderable<U>::value &&
47 !is_default<less_impl<T, U>>::value
48 );
49
50 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
51 static_assert(hana::Orderable<T>::value,
52 "hana::less(x, y) requires 'x' to be Orderable");
53
54 static_assert(hana::Orderable<U>::value,
55 "hana::less(x, y) requires 'y' to be Orderable");
56
57 static_assert(!is_default<less_impl<T, U>>::value,
58 "hana::less(x, y) requires 'x' and 'y' to be embeddable "
59 "in a common Orderable");
60 #endif
61
62 return Less::apply(static_cast<X&&>(x), static_cast<Y&&>(y));
63 }
64 //! @endcond
65
66 template <typename T, typename U, bool condition>
67 struct less_impl<T, U, when<condition>> : default_ {
68 template <typename ...Args>
69 static constexpr auto apply(Args&& ...) = delete;
70 };
71
72 // Cross-type overload
73 template <typename T, typename U>
74 struct less_impl<T, U, when<
75 detail::has_nontrivial_common_embedding<Orderable, T, U>::value &&
76 !detail::LessThanComparable<T, U>::value
77 >> {
78 using C = typename hana::common<T, U>::type;
79 template <typename X, typename Y>
80 static constexpr decltype(auto) apply(X&& x, Y&& y) {
81 return hana::less(hana::to<C>(static_cast<X&&>(x)),
82 hana::to<C>(static_cast<Y&&>(y)));
83 }
84 };
85
86 //////////////////////////////////////////////////////////////////////////
87 // Model for LessThanComparable data types
88 //////////////////////////////////////////////////////////////////////////
89 template <typename T, typename U>
90 struct less_impl<T, U, when<detail::LessThanComparable<T, U>::value>> {
91 template <typename X, typename Y>
92 static constexpr decltype(auto) apply(X&& x, Y&& y)
93 { return static_cast<X&&>(x) < static_cast<Y&&>(y); }
94 };
95
96 //////////////////////////////////////////////////////////////////////////
97 // Model for Constants wrapping an Orderable
98 //////////////////////////////////////////////////////////////////////////
99 template <typename C>
100 struct less_impl<C, C, when<
101 hana::Constant<C>::value &&
102 Orderable<typename C::value_type>::value
103 >> {
104 template <typename X, typename Y>
105 static constexpr auto apply(X const&, Y const&) {
106 constexpr auto less = hana::less(hana::value<X>(), hana::value<Y>());
107 constexpr bool truth_value = hana::if_(less, true, false);
108 return hana::bool_c<truth_value>;
109 }
110 };
111
112 //////////////////////////////////////////////////////////////////////////
113 // Model for Products
114 //////////////////////////////////////////////////////////////////////////
115 template <typename T, typename U>
116 struct less_impl<T, U, when<hana::Product<T>::value && hana::Product<U>::value>> {
117 template <typename X, typename Y>
118 static constexpr decltype(auto) apply(X const& x, Y const& y) {
119 return hana::or_(
120 hana::less(hana::first(x), hana::first(y)),
121 hana::and_(
122 hana::less_equal(hana::first(x), hana::first(y)),
123 hana::less(hana::second(x), hana::second(y))
124 )
125 );
126 }
127 };
128
129 //////////////////////////////////////////////////////////////////////////
130 // Model for Sequences
131 //////////////////////////////////////////////////////////////////////////
132 template <typename T, typename U>
133 struct less_impl<T, U, when<
134 hana::Sequence<T>::value && hana::Sequence<U>::value
135 >> {
136 template <typename Xs, typename Ys>
137 static constexpr auto apply(Xs const& xs, Ys const& ys)
138 { return hana::lexicographical_compare(xs, ys); }
139 };
140BOOST_HANA_NAMESPACE_END
141
142#endif // !BOOST_HANA_LESS_HPP