Warning, file /include/boost/units/static_rational.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_UNITS_STATIC_RATIONAL_HPP
0012 #define BOOST_UNITS_STATIC_RATIONAL_HPP
0013
0014 #include <boost/integer/common_factor_ct.hpp>
0015 #include <boost/mpl/less.hpp>
0016 #include <boost/mpl/arithmetic.hpp>
0017
0018 #ifdef BOOST_BORLANDC
0019 #include <boost/mpl/eval_if.hpp>
0020 #include <boost/mpl/integral_c.hpp>
0021 #include <boost/mpl/identity.hpp>
0022 #endif
0023
0024 #include <boost/units/config.hpp>
0025 #include <boost/units/operators.hpp>
0026
0027
0028
0029
0030 namespace boost {
0031
0032 namespace units {
0033
0034 namespace detail {
0035
0036 struct static_rational_tag {};
0037
0038 }
0039
0040 typedef long integer_type;
0041
0042
0043 template<integer_type Value>
0044 struct static_abs
0045 {
0046 BOOST_STATIC_CONSTANT(integer_type,value = Value < 0 ? -Value : Value);
0047 };
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 #ifdef BOOST_BORLANDC
0069
0070 template<integer_type X>
0071 struct make_integral_c {
0072 typedef boost::mpl::integral_c<integer_type, X> type;
0073 };
0074
0075 template<integer_type N,integer_type D = 1>
0076 class static_rational
0077 {
0078 public:
0079
0080 typedef static_rational this_type;
0081
0082 typedef boost::mpl::integral_c<integer_type, N> N_type;
0083 typedef boost::mpl::integral_c<integer_type, D> D_type;
0084
0085 typedef typename make_integral_c<
0086 (::boost::integer::static_gcd<
0087 ::boost::units::static_abs<N>::value,
0088 ::boost::units::static_abs<D>::value
0089 >::value)>::type gcd_type;
0090 typedef typename boost::mpl::eval_if<
0091 boost::mpl::less<
0092 D_type,
0093 boost::mpl::integral_c<integer_type, 0>
0094 >,
0095 boost::mpl::negate<gcd_type>,
0096 gcd_type
0097 >::type den_type;
0098
0099 public:
0100
0101 typedef detail::static_rational_tag tag;
0102
0103 BOOST_STATIC_CONSTANT(integer_type, Numerator =
0104 (::boost::mpl::divides<N_type, den_type>::value));
0105 BOOST_STATIC_CONSTANT(integer_type, Denominator =
0106 (::boost::mpl::divides<D_type, den_type>::value));
0107
0108
0109 typedef static_rational<N,D> this_type;
0110
0111
0112 typedef static_rational<
0113 (::boost::mpl::divides<N_type, den_type>::value),
0114 (::boost::mpl::divides<D_type, den_type>::value)
0115 > type;
0116
0117 static BOOST_CONSTEXPR integer_type numerator() { return Numerator; }
0118 static BOOST_CONSTEXPR integer_type denominator() { return Denominator; }
0119
0120
0121 BOOST_CONSTEXPR static_rational() { }
0122
0123 };
0124 #else
0125 template<integer_type N,integer_type D = 1>
0126 class static_rational
0127 {
0128 private:
0129
0130 BOOST_STATIC_CONSTEXPR integer_type nabs = static_abs<N>::value,
0131 dabs = static_abs<D>::value;
0132
0133
0134
0135 BOOST_STATIC_CONSTEXPR integer_type den =
0136 static_cast<integer_type>(boost::integer::static_gcd<nabs,dabs>::value) * ((D < 0) ? -1 : 1);
0137
0138 public:
0139
0140 typedef detail::static_rational_tag tag;
0141
0142 BOOST_STATIC_CONSTEXPR integer_type Numerator = N/den,
0143 Denominator = D/den;
0144
0145
0146 typedef static_rational<N,D> this_type;
0147
0148
0149 typedef static_rational<Numerator,Denominator> type;
0150
0151 static BOOST_CONSTEXPR integer_type numerator() { return Numerator; }
0152 static BOOST_CONSTEXPR integer_type denominator() { return Denominator; }
0153
0154
0155 BOOST_CONSTEXPR static_rational() { }
0156
0157 };
0158 #endif
0159
0160 }
0161
0162 }
0163
0164 #if BOOST_UNITS_HAS_BOOST_TYPEOF
0165
0166 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
0167
0168 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::static_rational, (long)(long))
0169
0170 #endif
0171
0172 namespace boost {
0173
0174 namespace units {
0175
0176
0177 template<integer_type N> class static_rational<N,0>;
0178
0179
0180 template<class T,integer_type N,integer_type D>
0181 inline BOOST_CONSTEXPR typename divide_typeof_helper<T,T>::type
0182 value(const static_rational<N,D>&)
0183 {
0184 return T(N)/T(D);
0185 }
0186
0187 }
0188
0189 #ifndef BOOST_UNITS_DOXYGEN
0190
0191 namespace mpl {
0192
0193 #ifdef BOOST_BORLANDC
0194
0195 template<>
0196 struct plus_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
0197 {
0198 template<class T0, class T1>
0199 struct apply {
0200 typedef typename boost::units::static_rational<
0201 ::boost::mpl::plus<
0202 boost::mpl::times<typename T0::N_type, typename T1::D_type>,
0203 boost::mpl::times<typename T1::N_type, typename T0::D_type>
0204 >::value,
0205 ::boost::mpl::times<typename T0::D_type, typename T1::D_type>::value
0206 >::type type;
0207 };
0208 };
0209
0210 template<>
0211 struct minus_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
0212 {
0213 template<class T0, class T1>
0214 struct apply {
0215 typedef typename boost::units::static_rational<
0216 ::boost::mpl::minus<
0217 boost::mpl::times<typename T0::N_type, typename T1::D_type>,
0218 boost::mpl::times<typename T1::N_type, typename T0::D_type>
0219 >::value,
0220 ::boost::mpl::times<typename T0::D_type, typename T1::D_type>::value
0221 >::type type;
0222 };
0223 };
0224
0225 template<>
0226 struct times_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
0227 {
0228 template<class T0, class T1>
0229 struct apply {
0230 typedef typename boost::units::static_rational<
0231 ::boost::mpl::times<typename T0::N_type, typename T1::N_type>::value,
0232 ::boost::mpl::times<typename T0::D_type, typename T1::D_type>::value
0233 >::type type;
0234 };
0235 };
0236
0237 template<>
0238 struct divides_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
0239 {
0240 template<class T0, class T1>
0241 struct apply {
0242 typedef typename boost::units::static_rational<
0243 ::boost::mpl::times<typename T0::N_type, typename T1::D_type>::value,
0244 ::boost::mpl::times<typename T0::D_type, typename T1::N_type>::value
0245 >::type type;
0246 };
0247 };
0248
0249 template<>
0250 struct negate_impl<boost::units::detail::static_rational_tag>
0251 {
0252 template<class T0>
0253 struct apply {
0254 typedef typename boost::units::static_rational<
0255 ::boost::mpl::negate<typename T0::N_type>::value,
0256 ::boost::mpl::identity<T0>::type::Denominator
0257 >::type type;
0258 };
0259 };
0260
0261 template<>
0262 struct less_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
0263 {
0264 template<class T0, class T1>
0265 struct apply
0266 {
0267 typedef mpl::bool_<((mpl::minus<T0, T1>::type::Numerator) < 0)> type;
0268 };
0269 };
0270
0271 #else
0272
0273 template<>
0274 struct plus_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
0275 {
0276 template<class T0, class T1>
0277 struct apply {
0278 typedef typename boost::units::static_rational<
0279 T0::Numerator*T1::Denominator+T1::Numerator*T0::Denominator,
0280 T0::Denominator*T1::Denominator
0281 >::type type;
0282 };
0283 };
0284
0285 template<>
0286 struct minus_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
0287 {
0288 template<class T0, class T1>
0289 struct apply {
0290 typedef typename boost::units::static_rational<
0291 T0::Numerator*T1::Denominator-T1::Numerator*T0::Denominator,
0292 T0::Denominator*T1::Denominator
0293 >::type type;
0294 };
0295 };
0296
0297 template<>
0298 struct times_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
0299 {
0300 template<class T0, class T1>
0301 struct apply {
0302 typedef typename boost::units::static_rational<
0303 T0::Numerator*T1::Numerator,
0304 T0::Denominator*T1::Denominator
0305 >::type type;
0306 };
0307 };
0308
0309 template<>
0310 struct divides_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
0311 {
0312 template<class T0, class T1>
0313 struct apply {
0314 typedef typename boost::units::static_rational<
0315 T0::Numerator*T1::Denominator,
0316 T0::Denominator*T1::Numerator
0317 >::type type;
0318 };
0319 };
0320
0321 template<>
0322 struct negate_impl<boost::units::detail::static_rational_tag>
0323 {
0324 template<class T0>
0325 struct apply {
0326 typedef typename boost::units::static_rational<-T0::Numerator,T0::Denominator>::type type;
0327 };
0328 };
0329
0330 template<>
0331 struct less_impl<boost::units::detail::static_rational_tag, boost::units::detail::static_rational_tag>
0332 {
0333 template<class T0, class T1>
0334 struct apply
0335 {
0336 typedef mpl::bool_<((mpl::minus<T0, T1>::type::Numerator) < 0)> type;
0337 };
0338 };
0339
0340 #endif
0341
0342
0343 }
0344
0345 #endif
0346
0347 }
0348
0349 #endif