]> git.sesse.net Git - casparcg/blob - dependencies64/boost/boost/ratio/ratio.hpp
Updated boost. Separate commit from the code changes. (So this revision will not...
[casparcg] / dependencies64 / boost / 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