]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/ratio/include/boost/ratio/ratio.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / ratio / include / boost / ratio / ratio.hpp
1 // ratio.hpp ---------------------------------------------------------------//
2
3 // Copyright 2008 Howard Hinnant
4 // Copyright 2008 Beman Dawes
5 // Copyright 2009 Vicente J. Botet Escriba
6
7 // Distributed under the Boost Software License, Version 1.0.
8 // See http://www.boost.org/LICENSE_1_0.txt
9
10 /*
11
12 This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
13 Many thanks to Howard for making his code available under the Boost license.
14 The original code was modified to conform to Boost conventions and to section
15 20.4 Compile-time rational arithmetic [ratio], of the C++ committee working
16 paper N2798.
17 See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
18
19 time2_demo contained this comment:
20
21 Much thanks to Andrei Alexandrescu,
22 Walter Brown,
23 Peter Dimov,
24 Jeff Garland,
25 Terry Golubiewski,
26 Daniel Krugler,
27 Anthony Williams.
28 */
29
30 // The way overflow is managed for ratio_less is taken from llvm/libcxx/include/ratio
31
32 #ifndef BOOST_RATIO_RATIO_HPP
33 #define BOOST_RATIO_RATIO_HPP
34
35 #include <boost/ratio/config.hpp>
36 #include <boost/ratio/detail/mpl/abs.hpp>
37 #include <boost/ratio/detail/mpl/sign.hpp>
38 #include <boost/ratio/detail/mpl/gcd.hpp>
39 #include <boost/ratio/detail/mpl/lcm.hpp>
40 #include <cstdlib>
41 #include <climits>
42 #include <limits>
43 #include <boost/cstdint.hpp>
44 #include <boost/type_traits/integral_constant.hpp>
45 #include <boost/core/enable_if.hpp>
46 #include <boost/integer_traits.hpp>
47 #include <boost/ratio/ratio_fwd.hpp>
48 #include <boost/ratio/detail/overflow_helpers.hpp>
49 #ifdef BOOST_RATIO_EXTENSIONS
50 #include <boost/rational.hpp>
51 #include <boost/ratio/mpl/rational_c_tag.hpp>
52 #endif
53
54 //
55 // We simply cannot include this header on gcc without getting copious warnings of the kind:
56 //
57 // boost/integer.hpp:77:30: warning: use of C99 long long integer constant
58 //
59 // And yet there is no other reasonable implementation, so we declare this a system header
60 // to suppress these warnings.
61 //
62 #if defined(__GNUC__) && (__GNUC__ >= 4)
63 #pragma GCC system_header
64 #endif
65
66 namespace boost
67 {
68
69
70 //----------------------------------------------------------------------------//
71 // //
72 // 20.6.1 Class template ratio [ratio.ratio] //
73 // //
74 //----------------------------------------------------------------------------//
75
76 template <boost::intmax_t N, boost::intmax_t D>
77 class ratio
78 {
79 static const boost::intmax_t ABS_N = mpl::abs_c<boost::intmax_t, N>::value;
80 static const boost::intmax_t ABS_D = mpl::abs_c<boost::intmax_t, D>::value;
81 BOOST_RATIO_STATIC_ASSERT(ABS_N >= 0, BOOST_RATIO_NUMERATOR_IS_OUT_OF_RANGE, ());
82 BOOST_RATIO_STATIC_ASSERT(ABS_D > 0, BOOST_RATIO_DENOMINATOR_IS_OUT_OF_RANGE, ());
83 BOOST_RATIO_STATIC_ASSERT(D != 0, BOOST_RATIO_DIVIDE_BY_0 , ());
84 static const boost::intmax_t SIGN_N = mpl::sign_c<boost::intmax_t,N>::value
85 * mpl::sign_c<boost::intmax_t,D>::value;
86 static const boost::intmax_t GCD = mpl::gcd_c<boost::intmax_t, ABS_N, ABS_D>::value;
87 public:
88 BOOST_STATIC_CONSTEXPR boost::intmax_t num = SIGN_N * ABS_N / GCD;
89 BOOST_STATIC_CONSTEXPR boost::intmax_t den = ABS_D / GCD;
90
91 #ifdef BOOST_RATIO_EXTENSIONS
92 typedef mpl::rational_c_tag tag;
93 typedef boost::rational<boost::intmax_t> value_type;
94 typedef boost::intmax_t num_type;
95 typedef boost::intmax_t den_type;
96 ratio()
97 {}
98 template <boost::intmax_t _N2, boost::intmax_t _D2>
99 ratio(const ratio<_N2, _D2>&,
100 typename enable_if_c
101 <
102 (ratio<_N2, _D2>::num == num &&
103 ratio<_N2, _D2>::den == den)
104 >::type* = 0)
105 {}
106
107 template <boost::intmax_t _N2, boost::intmax_t _D2>
108 typename enable_if_c
109 <
110 (ratio<_N2, _D2>::num == num &&
111 ratio<_N2, _D2>::den == den),
112 ratio&
113 >::type
114 operator=(const ratio<_N2, _D2>&) {return *this;}
115
116 static value_type value() {return value_type(num,den);}
117 value_type operator()() const {return value();}
118 #endif
119 typedef ratio<num, den> type;
120 };
121
122 #if defined(BOOST_NO_CXX11_CONSTEXPR)
123 template <boost::intmax_t N, boost::intmax_t D>
124 const boost::intmax_t ratio<N, D>::num;
125 template <boost::intmax_t N, boost::intmax_t D>
126 const boost::intmax_t ratio<N, D>::den;
127 #endif
128
129 //----------------------------------------------------------------------------//
130 // //
131 // 20.6.2 Arithmetic on ratio types [ratio.arithmetic] //
132 // //
133 //----------------------------------------------------------------------------//
134
135 template <class R1, class R2>
136 struct ratio_add
137 : boost::ratio_detail::ratio_add<R1, R2>::type
138 {
139 };
140
141 template <class R1, class R2>
142 struct ratio_subtract
143 : boost::ratio_detail::ratio_subtract<R1, R2>::type
144 {
145 };
146
147 template <class R1, class R2>
148 struct ratio_multiply
149 : boost::ratio_detail::ratio_multiply<R1, R2>::type
150 {
151 };
152
153 template <class R1, class R2>
154 struct ratio_divide
155 : boost::ratio_detail::ratio_divide<R1, R2>::type
156 {
157 };
158
159 //----------------------------------------------------------------------------//
160 // //
161 // 20.6.3 Comparision of ratio types [ratio.comparison] //
162 // //
163 //----------------------------------------------------------------------------//
164
165 // ratio_equal
166
167 template <class R1, class R2>
168 struct ratio_equal
169 : public boost::integral_constant<bool,
170 (R1::num == R2::num && R1::den == R2::den)>
171 {};
172
173 template <class R1, class R2>
174 struct ratio_not_equal
175 : public boost::integral_constant<bool, !ratio_equal<R1, R2>::value>
176 {};
177
178 // ratio_less
179
180 template <class R1, class R2>
181 struct ratio_less
182 : boost::integral_constant<bool, boost::ratio_detail::ratio_less<R1, R2>::value>
183 {};
184
185 template <class R1, class R2>
186 struct ratio_less_equal
187 : boost::integral_constant<bool, !ratio_less<R2, R1>::value>
188 {};
189
190 template <class R1, class R2>
191 struct ratio_greater
192 : boost::integral_constant<bool, ratio_less<R2, R1>::value>
193 {};
194
195 template <class R1, class R2>
196 struct ratio_greater_equal
197 : boost::integral_constant<bool, !ratio_less<R1, R2>::value>
198 {};
199
200 template <class R1, class R2>
201 struct ratio_gcd :
202 ratio<mpl::gcd_c<boost::intmax_t, R1::num, R2::num>::value,
203 mpl::lcm_c<boost::intmax_t, R1::den, R2::den>::value>::type
204 {
205 };
206
207 //----------------------------------------------------------------------------//
208 // //
209 // More arithmetic on ratio types [ratio.arithmetic] //
210 // //
211 //----------------------------------------------------------------------------//
212
213 #ifdef BOOST_RATIO_EXTENSIONS
214 template <class R>
215 struct ratio_negate
216 : ratio<-R::num, R::den>::type
217 {
218 };
219 template <class R>
220 struct ratio_abs
221 : ratio<mpl::abs_c<boost::intmax_t, R::num>::value, R::den>::type
222 {
223 };
224 template <class R>
225 struct ratio_sign
226 : mpl::sign_c<boost::intmax_t, R::num>
227 {
228 };
229
230 template <class R>
231 struct ratio_inverse
232 : ratio<R::den, R::num>::type
233 {
234 };
235
236
237 template <class R1, class R2>
238 struct ratio_lcm :
239 ratio<mpl::lcm_c<boost::intmax_t, R1::num, R2::num>::value,
240 mpl::gcd_c<boost::intmax_t, R1::den, R2::den>::value>::type
241 {
242 };
243
244 template <class R1, class R2>
245 struct ratio_modulo :
246 ratio<(R1::num * R2::den) % (R2::num * R1::den), R1::den * R2::den>::type
247 {
248 };
249
250 namespace detail {
251 template <class R1, class R2, bool r1ltr2>
252 struct ratio_min : R1 {};
253 template <class R1, class R2>
254 struct ratio_min<R1,R2,false> : R2 {};
255
256 template <class R1, class R2, bool r1ltr2>
257 struct ratio_max : R2 {};
258 template <class R1, class R2>
259 struct ratio_max<R1,R2,false> : R1 {};
260 }
261
262 template <class R1, class R2>
263 struct ratio_min : detail::ratio_min<R1, R2, ratio_less<R1,R2>::value>::type
264 {
265 };
266
267 template <class R1, class R2>
268 struct ratio_max : detail::ratio_max<R1, R2, ratio_less<R1,R2>::value>::type
269 {
270 };
271
272 template<typename R, int p>
273 struct ratio_power :
274 ratio_multiply<
275 typename ratio_power<R, p%2>::type,
276 typename ratio_power<typename ratio_multiply<R, R>::type, p/2>::type
277 >::type
278 {};
279
280 template<typename R>
281 struct ratio_power<R, 0> : ratio<1>::type {};
282
283 template<typename R>
284 struct ratio_power<R, 1> : R {};
285
286 template<typename R>
287 struct ratio_power<R, -1> : ratio_divide<ratio<1>, R>::type {};
288
289 #endif
290 } // namespace boost
291
292
293 #endif // BOOST_RATIO_RATIO_HPP