annotate DEPENDENCIES/generic/include/boost/units/static_rational.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // Boost.Units - A C++ library for zero-overhead dimensional analysis and
Chris@16 2 // unit/quantity manipulation and conversion
Chris@16 3 //
Chris@16 4 // Copyright (C) 2003-2008 Matthias Christian Schabel
Chris@16 5 // Copyright (C) 2008 Steven Watanabe
Chris@16 6 //
Chris@16 7 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 8 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 9 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 10
Chris@16 11 #ifndef BOOST_UNITS_STATIC_RATIONAL_HPP
Chris@16 12 #define BOOST_UNITS_STATIC_RATIONAL_HPP
Chris@16 13
Chris@101 14 #include <boost/integer/common_factor_ct.hpp>
Chris@16 15 #include <boost/mpl/less.hpp>
Chris@16 16 #include <boost/mpl/arithmetic.hpp>
Chris@16 17
Chris@16 18 #ifdef __BORLANDC__
Chris@16 19 #include <boost/mpl/eval_if.hpp>
Chris@16 20 #include <boost/mpl/integral_c.hpp>
Chris@16 21 #include <boost/mpl/identity.hpp>
Chris@16 22 #endif
Chris@16 23
Chris@16 24 #include <boost/units/config.hpp>
Chris@16 25 #include <boost/units/operators.hpp>
Chris@16 26
Chris@16 27 /// \file
Chris@16 28 /// \brief Compile-time rational numbers and operators.
Chris@16 29
Chris@16 30 namespace boost {
Chris@16 31
Chris@16 32 namespace units {
Chris@16 33
Chris@16 34 namespace detail {
Chris@16 35
Chris@16 36 struct static_rational_tag {};
Chris@16 37
Chris@16 38 }
Chris@16 39
Chris@16 40 typedef long integer_type;
Chris@16 41
Chris@16 42 /// Compile time absolute value.
Chris@16 43 template<integer_type Value>
Chris@16 44 struct static_abs
Chris@16 45 {
Chris@16 46 BOOST_STATIC_CONSTANT(integer_type,value = Value < 0 ? -Value : Value);
Chris@16 47 };
Chris@16 48
Chris@16 49 // Compile time rational number.
Chris@16 50 /**
Chris@16 51 This is an implementation of a compile time rational number, where @c static_rational<N,D> represents
Chris@16 52 a rational number with numerator @c N and denominator @c D. Because of the potential for ambiguity arising
Chris@16 53 from multiple equivalent values of @c static_rational (e.g. @c static_rational<6,2>==static_rational<3>),
Chris@16 54 static rationals should always be accessed through @c static_rational<N,D>::type. Template specialization
Chris@16 55 prevents instantiation of zero denominators (i.e. @c static_rational<N,0>). The following compile-time
Chris@16 56 arithmetic operators are provided for static_rational variables only (no operators are defined between
Chris@16 57 long and static_rational):
Chris@16 58 - @c mpl::negate
Chris@16 59 - @c mpl::plus
Chris@16 60 - @c mpl::minus
Chris@16 61 - @c mpl::times
Chris@16 62 - @c mpl::divides
Chris@16 63
Chris@16 64 Neither @c static_power nor @c static_root are defined for @c static_rational. This is because template types
Chris@16 65 may not be floating point values, while powers and roots of rational numbers can produce floating point
Chris@16 66 values.
Chris@16 67 */
Chris@16 68 #ifdef __BORLANDC__
Chris@16 69
Chris@16 70 template<integer_type X>
Chris@16 71 struct make_integral_c {
Chris@16 72 typedef boost::mpl::integral_c<integer_type, X> type;
Chris@16 73 };
Chris@16 74
Chris@16 75 template<integer_type N,integer_type D = 1>
Chris@16 76 class static_rational
Chris@16 77 {
Chris@16 78 public:
Chris@16 79
Chris@16 80 typedef static_rational this_type;
Chris@16 81
Chris@16 82 typedef boost::mpl::integral_c<integer_type, N> N_type;
Chris@16 83 typedef boost::mpl::integral_c<integer_type, D> D_type;
Chris@16 84
Chris@16 85 typedef typename make_integral_c<
Chris@101 86 (::boost::integer::static_gcd<
Chris@16 87 ::boost::units::static_abs<N>::value,
Chris@16 88 ::boost::units::static_abs<D>::value
Chris@16 89 >::value)>::type gcd_type;
Chris@16 90 typedef typename boost::mpl::eval_if<
Chris@16 91 boost::mpl::less<
Chris@16 92 D_type,
Chris@16 93 boost::mpl::integral_c<integer_type, 0>
Chris@16 94 >,
Chris@16 95 boost::mpl::negate<gcd_type>,
Chris@16 96 gcd_type
Chris@16 97 >::type den_type;
Chris@16 98
Chris@16 99 public:
Chris@16 100 // for mpl arithmetic support
Chris@16 101 typedef detail::static_rational_tag tag;
Chris@16 102
Chris@16 103 BOOST_STATIC_CONSTANT(integer_type, Numerator =
Chris@16 104 (::boost::mpl::divides<N_type, den_type>::value));
Chris@16 105 BOOST_STATIC_CONSTANT(integer_type, Denominator =
Chris@16 106 (::boost::mpl::divides<D_type, den_type>::value));
Chris@16 107
Chris@16 108 /// INTERNAL ONLY
Chris@16 109 typedef static_rational<N,D> this_type;
Chris@16 110
Chris@16 111 /// static_rational<N,D> reduced by GCD
Chris@16 112 typedef static_rational<
Chris@16 113 (::boost::mpl::divides<N_type, den_type>::value),
Chris@16 114 (::boost::mpl::divides<D_type, den_type>::value)
Chris@16 115 > type;
Chris@16 116
Chris@16 117 static integer_type numerator() { return Numerator; }
Chris@16 118 static integer_type denominator() { return Denominator; }
Chris@16 119
Chris@16 120 // INTERNAL ONLY
Chris@16 121 static_rational() { }
Chris@16 122 //~static_rational() { }
Chris@16 123 };
Chris@16 124 #else
Chris@16 125 template<integer_type N,integer_type D = 1>
Chris@16 126 class static_rational
Chris@16 127 {
Chris@16 128 private:
Chris@16 129
Chris@16 130 static const integer_type nabs = static_abs<N>::value,
Chris@16 131 dabs = static_abs<D>::value;
Chris@16 132
Chris@16 133 /// greatest common divisor of N and D
Chris@16 134 // need cast to signed because static_gcd returns unsigned long
Chris@16 135 static const integer_type den =
Chris@101 136 static_cast<integer_type>(boost::integer::static_gcd<nabs,dabs>::value) * ((D < 0) ? -1 : 1);
Chris@16 137
Chris@16 138 public:
Chris@16 139 // for mpl arithmetic support
Chris@16 140 typedef detail::static_rational_tag tag;
Chris@16 141
Chris@16 142 static const integer_type Numerator = N/den,
Chris@16 143 Denominator = D/den;
Chris@16 144
Chris@16 145 /// INTERNAL ONLY
Chris@16 146 typedef static_rational<N,D> this_type;
Chris@16 147
Chris@16 148 /// static_rational<N,D> reduced by GCD
Chris@16 149 typedef static_rational<Numerator,Denominator> type;
Chris@16 150
Chris@16 151 static integer_type numerator() { return Numerator; }
Chris@16 152 static integer_type denominator() { return Denominator; }
Chris@16 153
Chris@16 154 // INTERNAL ONLY
Chris@16 155 static_rational() { }
Chris@16 156 //~static_rational() { }
Chris@16 157 };
Chris@16 158 #endif
Chris@16 159
Chris@16 160 }
Chris@16 161
Chris@16 162 }
Chris@16 163
Chris@16 164 #if BOOST_UNITS_HAS_BOOST_TYPEOF
Chris@16 165
Chris@16 166 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
Chris@16 167
Chris@16 168 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::static_rational, (long)(long))
Chris@16 169
Chris@16 170 #endif
Chris@16 171
Chris@16 172 namespace boost {
Chris@16 173
Chris@16 174 namespace units {
Chris@16 175
Chris@16 176 // prohibit zero denominator
Chris@16 177 template<integer_type N> class static_rational<N,0>;
Chris@16 178
Chris@16 179 /// get decimal value of @c static_rational
Chris@16 180 template<class T,integer_type N,integer_type D>
Chris@16 181 inline typename divide_typeof_helper<T,T>::type
Chris@16 182 value(const static_rational<N,D>&)
Chris@16 183 {
Chris@16 184 return T(N)/T(D);
Chris@16 185 }
Chris@16 186
Chris@16 187 } // namespace units
Chris@16 188
Chris@16 189 #ifndef BOOST_UNITS_DOXYGEN
Chris@16 190
Chris@16 191 namespace mpl {
Chris@16 192
Chris@16 193 #ifdef __BORLANDC__
Chris@16 194
Chris@16 195 template<>
Chris@16 196 struct plus_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
Chris@16 197 {
Chris@16 198 template<class T0, class T1>
Chris@16 199 struct apply {
Chris@16 200 typedef typename boost::units::static_rational<
Chris@16 201 ::boost::mpl::plus<
Chris@16 202 boost::mpl::times<typename T0::N_type, typename T1::D_type>,
Chris@16 203 boost::mpl::times<typename T1::N_type, typename T0::D_type>
Chris@16 204 >::value,
Chris@16 205 ::boost::mpl::times<typename T0::D_type, typename T1::D_type>::value
Chris@16 206 >::type type;
Chris@16 207 };
Chris@16 208 };
Chris@16 209
Chris@16 210 template<>
Chris@16 211 struct minus_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
Chris@16 212 {
Chris@16 213 template<class T0, class T1>
Chris@16 214 struct apply {
Chris@16 215 typedef typename boost::units::static_rational<
Chris@16 216 ::boost::mpl::minus<
Chris@16 217 boost::mpl::times<typename T0::N_type, typename T1::D_type>,
Chris@16 218 boost::mpl::times<typename T1::N_type, typename T0::D_type>
Chris@16 219 >::value,
Chris@16 220 ::boost::mpl::times<typename T0::D_type, typename T1::D_type>::value
Chris@16 221 >::type type;
Chris@16 222 };
Chris@16 223 };
Chris@16 224
Chris@16 225 template<>
Chris@16 226 struct times_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
Chris@16 227 {
Chris@16 228 template<class T0, class T1>
Chris@16 229 struct apply {
Chris@16 230 typedef typename boost::units::static_rational<
Chris@16 231 ::boost::mpl::times<typename T0::N_type, typename T1::N_type>::value,
Chris@16 232 ::boost::mpl::times<typename T0::D_type, typename T1::D_type>::value
Chris@16 233 >::type type;
Chris@16 234 };
Chris@16 235 };
Chris@16 236
Chris@16 237 template<>
Chris@16 238 struct divides_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
Chris@16 239 {
Chris@16 240 template<class T0, class T1>
Chris@16 241 struct apply {
Chris@16 242 typedef typename boost::units::static_rational<
Chris@16 243 ::boost::mpl::times<typename T0::N_type, typename T1::D_type>::value,
Chris@16 244 ::boost::mpl::times<typename T0::D_type, typename T1::N_type>::value
Chris@16 245 >::type type;
Chris@16 246 };
Chris@16 247 };
Chris@16 248
Chris@16 249 template<>
Chris@16 250 struct negate_impl<boost::units::detail::static_rational_tag>
Chris@16 251 {
Chris@16 252 template<class T0>
Chris@16 253 struct apply {
Chris@16 254 typedef typename boost::units::static_rational<
Chris@16 255 ::boost::mpl::negate<typename T0::N_type>::value,
Chris@16 256 ::boost::mpl::identity<T0>::type::Denominator
Chris@16 257 >::type type;
Chris@16 258 };
Chris@16 259 };
Chris@16 260
Chris@16 261 template<>
Chris@16 262 struct less_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
Chris@16 263 {
Chris@16 264 template<class T0, class T1>
Chris@16 265 struct apply
Chris@16 266 {
Chris@16 267 typedef mpl::bool_<((mpl::minus<T0, T1>::type::Numerator) < 0)> type;
Chris@16 268 };
Chris@16 269 };
Chris@16 270
Chris@16 271 #else
Chris@16 272
Chris@16 273 template<>
Chris@16 274 struct plus_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
Chris@16 275 {
Chris@16 276 template<class T0, class T1>
Chris@16 277 struct apply {
Chris@16 278 typedef typename boost::units::static_rational<
Chris@16 279 T0::Numerator*T1::Denominator+T1::Numerator*T0::Denominator,
Chris@16 280 T0::Denominator*T1::Denominator
Chris@16 281 >::type type;
Chris@16 282 };
Chris@16 283 };
Chris@16 284
Chris@16 285 template<>
Chris@16 286 struct minus_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
Chris@16 287 {
Chris@16 288 template<class T0, class T1>
Chris@16 289 struct apply {
Chris@16 290 typedef typename boost::units::static_rational<
Chris@16 291 T0::Numerator*T1::Denominator-T1::Numerator*T0::Denominator,
Chris@16 292 T0::Denominator*T1::Denominator
Chris@16 293 >::type type;
Chris@16 294 };
Chris@16 295 };
Chris@16 296
Chris@16 297 template<>
Chris@16 298 struct times_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
Chris@16 299 {
Chris@16 300 template<class T0, class T1>
Chris@16 301 struct apply {
Chris@16 302 typedef typename boost::units::static_rational<
Chris@16 303 T0::Numerator*T1::Numerator,
Chris@16 304 T0::Denominator*T1::Denominator
Chris@16 305 >::type type;
Chris@16 306 };
Chris@16 307 };
Chris@16 308
Chris@16 309 template<>
Chris@16 310 struct divides_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
Chris@16 311 {
Chris@16 312 template<class T0, class T1>
Chris@16 313 struct apply {
Chris@16 314 typedef typename boost::units::static_rational<
Chris@16 315 T0::Numerator*T1::Denominator,
Chris@16 316 T0::Denominator*T1::Numerator
Chris@16 317 >::type type;
Chris@16 318 };
Chris@16 319 };
Chris@16 320
Chris@16 321 template<>
Chris@16 322 struct negate_impl<boost::units::detail::static_rational_tag>
Chris@16 323 {
Chris@16 324 template<class T0>
Chris@16 325 struct apply {
Chris@16 326 typedef typename boost::units::static_rational<-T0::Numerator,T0::Denominator>::type type;
Chris@16 327 };
Chris@16 328 };
Chris@16 329
Chris@16 330 template<>
Chris@16 331 struct less_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
Chris@16 332 {
Chris@16 333 template<class T0, class T1>
Chris@16 334 struct apply
Chris@16 335 {
Chris@16 336 typedef mpl::bool_<((mpl::minus<T0, T1>::type::Numerator) < 0)> type;
Chris@16 337 };
Chris@16 338 };
Chris@16 339
Chris@16 340 #endif
Chris@16 341
Chris@16 342
Chris@16 343 }
Chris@16 344
Chris@16 345 #endif
Chris@16 346
Chris@16 347 } // namespace boost
Chris@16 348
Chris@16 349 #endif // BOOST_UNITS_STATIC_RATIONAL_HPP