]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/test/_include/support/numeric.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / hana / test / _include / support / numeric.hpp
1 // Copyright Louis Dionne 2013-2016
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4
5 #ifndef TEST_SUPPORT_NUMERIC_HPP
6 #define TEST_SUPPORT_NUMERIC_HPP
7
8 #include <boost/hana/core/tag_of.hpp>
9 #include <boost/hana/eval.hpp>
10 #include <boost/hana/fwd/div.hpp>
11 #include <boost/hana/fwd/equal.hpp>
12 #include <boost/hana/fwd/eval_if.hpp>
13 #include <boost/hana/fwd/less.hpp>
14 #include <boost/hana/fwd/minus.hpp>
15 #include <boost/hana/fwd/mod.hpp>
16 #include <boost/hana/fwd/mult.hpp>
17 #include <boost/hana/fwd/negate.hpp>
18 #include <boost/hana/fwd/not.hpp>
19 #include <boost/hana/fwd/one.hpp>
20 #include <boost/hana/fwd/plus.hpp>
21 #include <boost/hana/fwd/while.hpp>
22 #include <boost/hana/fwd/zero.hpp>
23
24
25 struct numeric_type {
26 constexpr explicit numeric_type(int v) : value(v) { }
27 int value;
28 constexpr operator int() const { return value; }
29 };
30
31 using Numeric = boost::hana::tag_of_t<numeric_type>;
32
33 struct numeric_t {
34 constexpr numeric_type operator()(int x) const {
35 return numeric_type{x};
36 }
37 };
38 constexpr numeric_t numeric{};
39
40
41 namespace boost { namespace hana {
42 //////////////////////////////////////////////////////////////////////////
43 // Comparable
44 //////////////////////////////////////////////////////////////////////////
45 template <>
46 struct equal_impl<Numeric, Numeric> {
47 template <typename X, typename Y>
48 static constexpr auto apply(X x, Y y)
49 { return numeric(x.value == y.value); }
50 };
51
52 //////////////////////////////////////////////////////////////////////////
53 // Orderable
54 //////////////////////////////////////////////////////////////////////////
55 template <>
56 struct less_impl<Numeric, Numeric> {
57 template <typename X, typename Y>
58 static constexpr auto apply(X x, Y y) {
59 // Workaround a _weird_ GCC bug:
60 // error: parse error in template argument list
61 // bool cmp = (x.value < y.value);
62 // ^
63 int xv = x.value, yv = y.value;
64 return numeric(xv < yv);
65 }
66 };
67
68 //////////////////////////////////////////////////////////////////////////
69 // Logical
70 //////////////////////////////////////////////////////////////////////////
71 template <>
72 struct eval_if_impl<Numeric> {
73 template <typename C, typename T, typename E>
74 static constexpr auto apply(C const& c, T&& t, E&& e) {
75 return c.value ? hana::eval(static_cast<T&&>(t))
76 : hana::eval(static_cast<E&&>(e));
77 }
78 };
79
80 template <>
81 struct not_impl<Numeric> {
82 template <typename X>
83 static constexpr auto apply(X x)
84 { return numeric(!x.value); }
85 };
86
87 template <>
88 struct while_impl<Numeric> {
89 template <typename Pred, typename State, typename F>
90 static constexpr auto apply(Pred pred, State state, F f)
91 -> decltype(true ? f(state) : state)
92 {
93 if (pred(state))
94 return hana::while_(pred, f(state), f);
95 else
96 return state;
97 }
98 };
99
100 //////////////////////////////////////////////////////////////////////////
101 // Monoid
102 //////////////////////////////////////////////////////////////////////////
103 template <>
104 struct plus_impl<Numeric, Numeric> {
105 template <typename X, typename Y>
106 static constexpr auto apply(X x, Y y)
107 { return numeric(x.value + y.value); }
108 };
109
110 template <>
111 struct zero_impl<Numeric> {
112 static constexpr auto apply()
113 { return numeric(0); }
114 };
115
116 //////////////////////////////////////////////////////////////////////////
117 // Group
118 //
119 // Define either one to select which MCD is used:
120 // BOOST_HANA_TEST_GROUP_NEGATE_MCD
121 // BOOST_HANA_TEST_GROUP_MINUS_MCD
122 //
123 // If neither is defined, the MCD used is unspecified.
124 //////////////////////////////////////////////////////////////////////////
125 #if defined(BOOST_HANA_TEST_GROUP_NEGATE_MCD)
126 template <>
127 struct negate_impl<Numeric> {
128 template <typename X>
129 static constexpr auto apply(X x)
130 { return numeric(-x.value); }
131 };
132 #else
133 template <>
134 struct minus_impl<Numeric, Numeric> {
135 template <typename X, typename Y>
136 static constexpr auto apply(X x, Y y)
137 { return numeric(x.value - y.value); }
138 };
139 #endif
140
141 //////////////////////////////////////////////////////////////////////////
142 // Ring
143 //////////////////////////////////////////////////////////////////////////
144 template <>
145 struct mult_impl<Numeric, Numeric> {
146 template <typename X, typename Y>
147 static constexpr auto apply(X x, Y y)
148 { return numeric(x.value * y.value); }
149 };
150
151 template <>
152 struct one_impl<Numeric> {
153 static constexpr auto apply()
154 { return numeric(1); }
155 };
156
157 //////////////////////////////////////////////////////////////////////////
158 // EuclideanRing
159 //////////////////////////////////////////////////////////////////////////
160 template <>
161 struct div_impl<Numeric, Numeric> {
162 template <typename X, typename Y>
163 static constexpr auto apply(X x, Y y)
164 { return numeric(x.value / y.value); }
165 };
166
167 template <>
168 struct mod_impl<Numeric, Numeric> {
169 template <typename X, typename Y>
170 static constexpr auto apply(X x, Y y)
171 { return numeric(x.value % y.value); }
172 };
173 }} // end namespace boost::hana
174
175 #endif //! TEST_SUPPORT_NUMERIC_HPP