Chris@16: // ratio.hpp ---------------------------------------------------------------// Chris@16: Chris@16: // Copyright 2008 Howard Hinnant Chris@16: // Copyright 2008 Beman Dawes Chris@16: // Copyright 2009 Vicente J. Botet Escriba Chris@16: Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // See http://www.boost.org/LICENSE_1_0.txt Chris@16: Chris@16: /* Chris@16: Chris@16: This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. Chris@16: Many thanks to Howard for making his code available under the Boost license. Chris@16: The original code was modified to conform to Boost conventions and to section Chris@16: 20.4 Compile-time rational arithmetic [ratio], of the C++ committee working Chris@16: paper N2798. Chris@16: See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. Chris@16: Chris@16: time2_demo contained this comment: Chris@16: Chris@16: Much thanks to Andrei Alexandrescu, Chris@16: Walter Brown, Chris@16: Peter Dimov, Chris@16: Jeff Garland, Chris@16: Terry Golubiewski, Chris@16: Daniel Krugler, Chris@16: Anthony Williams. Chris@16: */ Chris@16: Chris@16: // The way overflow is managed for ratio_less is taken from llvm/libcxx/include/ratio Chris@16: Chris@16: #ifndef BOOST_RATIO_RATIO_HPP Chris@16: #define BOOST_RATIO_RATIO_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #ifdef BOOST_RATIO_EXTENSIONS Chris@16: #include Chris@16: #include Chris@16: #endif Chris@16: Chris@16: // Chris@16: // We simply cannot include this header on gcc without getting copious warnings of the kind: Chris@16: // Chris@16: // boost/integer.hpp:77:30: warning: use of C99 long long integer constant Chris@16: // Chris@16: // And yet there is no other reasonable implementation, so we declare this a system header Chris@16: // to suppress these warnings. Chris@16: // Chris@16: #if defined(__GNUC__) && (__GNUC__ >= 4) Chris@16: #pragma GCC system_header Chris@16: #endif Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // // Chris@16: // 20.6.1 Class template ratio [ratio.ratio] // Chris@16: // // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: template Chris@16: class ratio Chris@16: { Chris@16: static const boost::intmax_t ABS_N = mpl::abs_c::value; Chris@16: static const boost::intmax_t ABS_D = mpl::abs_c::value; Chris@16: BOOST_RATIO_STATIC_ASSERT(ABS_N >= 0, BOOST_RATIO_NUMERATOR_IS_OUT_OF_RANGE, ()); Chris@16: BOOST_RATIO_STATIC_ASSERT(ABS_D > 0, BOOST_RATIO_DENOMINATOR_IS_OUT_OF_RANGE, ()); Chris@16: BOOST_RATIO_STATIC_ASSERT(D != 0, BOOST_RATIO_DIVIDE_BY_0 , ()); Chris@16: static const boost::intmax_t SIGN_N = mpl::sign_c::value Chris@16: * mpl::sign_c::value; Chris@16: static const boost::intmax_t GCD = mpl::gcd_c::value; Chris@16: public: Chris@16: BOOST_STATIC_CONSTEXPR boost::intmax_t num = SIGN_N * ABS_N / GCD; Chris@16: BOOST_STATIC_CONSTEXPR boost::intmax_t den = ABS_D / GCD; Chris@16: Chris@16: #ifdef BOOST_RATIO_EXTENSIONS Chris@16: typedef mpl::rational_c_tag tag; Chris@16: typedef boost::rational value_type; Chris@16: typedef boost::intmax_t num_type; Chris@16: typedef boost::intmax_t den_type; Chris@16: ratio() Chris@16: {} Chris@16: template Chris@16: ratio(const ratio<_N2, _D2>&, Chris@16: typename enable_if_c Chris@16: < Chris@16: (ratio<_N2, _D2>::num == num && Chris@16: ratio<_N2, _D2>::den == den) Chris@16: >::type* = 0) Chris@16: {} Chris@16: Chris@16: template Chris@16: typename enable_if_c Chris@16: < Chris@16: (ratio<_N2, _D2>::num == num && Chris@16: ratio<_N2, _D2>::den == den), Chris@16: ratio& Chris@16: >::type Chris@16: operator=(const ratio<_N2, _D2>&) {return *this;} Chris@16: Chris@16: static value_type value() {return value_type(num,den);} Chris@16: value_type operator()() const {return value();} Chris@16: #endif Chris@16: typedef ratio type; Chris@16: }; Chris@16: Chris@16: #if defined(BOOST_NO_CXX11_CONSTEXPR) Chris@16: template Chris@16: const boost::intmax_t ratio::num; Chris@16: template Chris@16: const boost::intmax_t ratio::den; Chris@16: #endif Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // // Chris@101: // 20.6.2 Arithmetic on ratio types [ratio.arithmetic] // Chris@16: // // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: template Chris@16: struct ratio_add Chris@16: : boost::ratio_detail::ratio_add::type Chris@16: { Chris@16: }; Chris@16: Chris@16: template Chris@16: struct ratio_subtract Chris@16: : boost::ratio_detail::ratio_subtract::type Chris@16: { Chris@16: }; Chris@16: Chris@16: template Chris@16: struct ratio_multiply Chris@16: : boost::ratio_detail::ratio_multiply::type Chris@16: { Chris@16: }; Chris@16: Chris@16: template Chris@16: struct ratio_divide Chris@16: : boost::ratio_detail::ratio_divide::type Chris@16: { Chris@16: }; Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // // Chris@101: // 20.6.3 Comparision of ratio types [ratio.comparison] // Chris@16: // // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: // ratio_equal Chris@16: Chris@16: template Chris@16: struct ratio_equal Chris@16: : public boost::integral_constant Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct ratio_not_equal Chris@16: : public boost::integral_constant::value> Chris@16: {}; Chris@16: Chris@16: // ratio_less Chris@16: Chris@16: template Chris@16: struct ratio_less Chris@16: : boost::integral_constant::value> Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct ratio_less_equal Chris@16: : boost::integral_constant::value> Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct ratio_greater Chris@16: : boost::integral_constant::value> Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct ratio_greater_equal Chris@16: : boost::integral_constant::value> Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct ratio_gcd : Chris@16: ratio::value, Chris@16: mpl::lcm_c::value>::type Chris@16: { Chris@16: }; Chris@16: Chris@101: //----------------------------------------------------------------------------// Chris@101: // // Chris@101: // More arithmetic on ratio types [ratio.arithmetic] // Chris@101: // // Chris@101: //----------------------------------------------------------------------------// Chris@101: Chris@16: #ifdef BOOST_RATIO_EXTENSIONS Chris@16: template Chris@16: struct ratio_negate Chris@16: : ratio<-R::num, R::den>::type Chris@16: { Chris@16: }; Chris@16: template Chris@16: struct ratio_abs Chris@16: : ratio::value, R::den>::type Chris@16: { Chris@16: }; Chris@16: template Chris@16: struct ratio_sign Chris@16: : mpl::sign_c Chris@16: { Chris@16: }; Chris@101: Chris@101: template Chris@101: struct ratio_inverse Chris@101: : ratio::type Chris@101: { Chris@101: }; Chris@101: Chris@101: Chris@16: template Chris@16: struct ratio_lcm : Chris@16: ratio::value, Chris@16: mpl::gcd_c::value>::type Chris@16: { Chris@16: }; Chris@101: Chris@101: template Chris@101: struct ratio_modulo : Chris@101: ratio<(R1::num * R2::den) % (R2::num * R1::den), R1::den * R2::den>::type Chris@101: { Chris@101: }; Chris@101: Chris@101: namespace detail { Chris@101: template Chris@101: struct ratio_min : R1 {}; Chris@101: template Chris@101: struct ratio_min : R2 {}; Chris@101: Chris@101: template Chris@101: struct ratio_max : R2 {}; Chris@101: template Chris@101: struct ratio_max : R1 {}; Chris@101: } Chris@101: Chris@101: template Chris@101: struct ratio_min : detail::ratio_min::value>::type Chris@101: { Chris@101: }; Chris@101: Chris@101: template Chris@101: struct ratio_max : detail::ratio_max::value>::type Chris@101: { Chris@101: }; Chris@101: Chris@101: template Chris@101: struct ratio_power : Chris@101: ratio_multiply< Chris@101: typename ratio_power::type, Chris@101: typename ratio_power::type, p/2>::type Chris@101: >::type Chris@101: {}; Chris@101: Chris@101: template Chris@101: struct ratio_power : ratio<1>::type {}; Chris@101: Chris@101: template Chris@101: struct ratio_power : R {}; Chris@101: Chris@101: template Chris@101: struct ratio_power : ratio_divide, R>::type {}; Chris@101: Chris@16: #endif Chris@16: } // namespace boost Chris@16: Chris@16: Chris@16: #endif // BOOST_RATIO_RATIO_HPP