| Home | Libraries | People | FAQ | More

## Reference

### C++0x Recommendation

#### Header `<boost/ratio.hpp>`

This header includes all the ratio related header files

    #include <boost/ratio/ratio.hpp>
    #include <boost/ratio/ratio_io.hpp>
    #include <boost/ratio/rational_constant.hpp>

#### Header `<boost/ratio/ratio_fwd.hpp>`

This header provides forward declarations for the `<boost/ratio/ratio.hpp>` file.

    namespace boost  {

        template <boost::intmax_t N, boost::intmax_t D = 1> class ratio;

        // ratio arithmetic
        template <class R1, class R2> struct ratio_add;
        template <class R1, class R2> struct ratio_subtract;
        template <class R1, class R2> struct ratio_multiply;
        template <class R1, class R2> struct ratio_divide;
        template <class R> struct ratio_negate;
        template <class R> struct ratio_sign;
        template <class R> struct ratio_abs;
        template <class R1, class R2> struct ratio_gcd;
        template <class R1, class R2> struct ratio_lcm;

        // ratio comparison
        template <class R1, class R2> struct ratio_equal;
        template <class R1, class R2> struct ratio_not_equal;
        template <class R1, class R2> struct ratio_less;
        template <class R1, class R2> struct ratio_less_equal;
        template <class R1, class R2> struct ratio_greater;
        template <class R1, class R2> struct ratio_greater_equal;

        // convenience SI typedefs
        typedef ratio<1LL, 1000000000000000000LL> atto;
        typedef ratio<1LL,    1000000000000000LL> femto;
        typedef ratio<1LL,       1000000000000LL> pico;
        typedef ratio<1LL,          1000000000LL> nano;
        typedef ratio<1LL,             1000000LL> micro;
        typedef ratio<1LL,                1000LL> milli;
        typedef ratio<1LL,                 100LL> centi;
        typedef ratio<1LL,                  10LL> deci;
        typedef ratio<                 10LL, 1LL> deca;
        typedef ratio<                100LL, 1LL> hecto;
        typedef ratio<               1000LL, 1LL> kilo;
        typedef ratio<            1000000LL, 1LL> mega;
        typedef ratio<         1000000000LL, 1LL> giga;
        typedef ratio<      1000000000000LL, 1LL> tera;
        typedef ratio<   1000000000000000LL, 1LL> peta;
        typedef ratio<1000000000000000000LL, 1LL> exa;
    }

#### Header `<boost/ratio/ratio.hpp>`

`ratio` is a facility which is useful in specifying compile-time rational constants. Compile-time rational arithmetic is supported with protection against overflow and divide by zero. Such a facility is very handy to efficiently represent 1/3 of a nanosecond, or to specify an inch in terms of meters (for example 254/10000 meters - which `ratio` will reduce to 127/5000 meters).

    // Configuration macros
    #define BOOST_RATIO_USES_STATIC_ASSERT
    #define BOOST_RATIO_USES_MPL_ASSERT
    #define BOOST_RATIO_USES_ARRAY_ASSERT
    #define BOOST_RATIO_EXTENSIONS

##### Configuration Macros

When BOOST_NO_STATIC_ASSERT is defined, the user can select the way static assertions are reported. Define

- BOOST_RATIO_USES_STATIC_ASSERT to use Boost.StaticAssert.
- BOOST_RATIO_USES_MPL_ASSERT to use Boost.MPL static assertions.
- BOOST_RATIO_USES_RATIO_ASSERT to use Boost.Ratio static assertions.

The default behavior is as if BOOST_RATIO_USES_ARRAY_ASSERT is defined.

When BOOST_RATIO_USES_MPL_ASSERT is not defined the following symbols are defined as shown:

    #define BOOST_RATIO_OVERFLOW_IN_ADD "overflow in ratio add"
    #define BOOST_RATIO_OVERFLOW_IN_SUB "overflow in ratio sub"
    #define BOOST_RATIO_OVERFLOW_IN_MUL "overflow in ratio mul"
    #define BOOST_RATIO_OVERFLOW_IN_DIV "overflow in ratio div"
    #define BOOST_RATIO_NUMERATOR_IS_OUT_OF_RANGE "ratio numerator is out of range"
    #define BOOST_RATIO_DIVIDE_BY_0 "ratio divide by 0"
    #define BOOST_RATIO_DENOMINATOR_IS_OUT_OF_RANGE "ratio denominator is out of range"

Depending upon the static assertion system used, a hint as to the failing assertion will appear in some form in the compiler diagnostic output.

When BOOST_RATIO_EXTENSIONS is defined, Boost.Ratio provides in addition some extenion to the C++ standard, see below.

##### Class Template `ratio<>`

    template <boost::intmax_t N, boost::intmax_t D>
    class ratio {
    public:
        static const boost::intmax_t num;
        static const boost::intmax_t den;
        typedef ratio<num, den> type;

        #ifdef BOOST_RATIO_EXTENSIONS
        typedef mpl::rational_c_tag tag;
        typedef boost::rational<boost::intmax_t> value_type;
        typedef boost::intmax_t num_type;
        typedef boost::intmax_t den_type;

        ratio() = default;

        template <intmax_t _N2, intmax_t _D2>
        ratio(const ratio<_N2, _D2>&);

        template <intmax_t _N2, intmax_t _D2>
        ratio& operator=(const ratio<_N2, _D2>&);

        static value_type value();
        value_type operator()() const;
        #endif
    };

A diagnostic will be emitted if `ratio` is instantiated with `D == 0`, or if the absolute value of `N` or `D` cannot be represented. Note: These rules ensure that infinite ratios are avoided and that for any negative input, there exists a representable value of its absolute value which is positive. In a two's complement representation, this excludes the most negative value.

The members num and den will be normalized values of the template arguments N and D computed as follows. Let `gcd` denote the greatest common divisor of `N`'s absolute value and of `D`'s absolute value. Then:

- `num` has the value `sign(N)*sign(D)*abs(N)/gcd`.
- `den` has the value `abs(D)/gcd`.

The nested typedef `type` denotes the normalized form of this `ratio` type. It should be used when the normalized form of the template arguments are required, since the arguments are not necessarily normalized.

Two `ratio` classes ``ratio`<N1,D1>` and ``ratio`<N2,D2>` have the same normalized form if ``ratio`<N1,D1>::type` is the same type as ``ratio`<N2,D2>::type`

###### Construction and Assignment

Included only if BOOST_RATIO_EXTENSIONS is defined.

<h7> Default Constructor </h7>

    ratio()=default;

Effects: Constructs a `ratio` object.

<h7> Copy Constructor </h7>

    template <intmax_t N2, intmax_t D2>
      ratio(const ratio<N2, D2>& r);

Effects: Constructs a `ratio` object.

Remarks: This constructor will not participate in overload resolution unless `r` has the same normalized form as `*this`.

<h7> Assignement </h7>

    template <intmax_t N2, intmax_t D2>
      ratio& operator=(const ratio<N2, D2>& r);

Effects: Assigns a `ratio` object.

Returns: *this.

Remarks: This operator will not participate in overload resolution unless `r` has the same normalized form as `*this`.

###### MPL Numeric Metafunctions

Included only if BOOST_RATIO_EXTENSIONS is defined.

In order to work with Boost.MPL numeric metafunctions as a Rational Constant, the following has beed added:

    typedef mpl::rational_c_tag tag;
    typedef boost::rational<boost::intmax_t> value_type;
    typedef boost::intmax_t num_type;
    typedef boost::intmax_t den_type;

###### Observers

Included only if BOOST_RATIO_EXTENSIONS is defined.

    static value_type value();
    value_type operator()() const;

Returns: value_type(num,den);

##### `ratio` Arithmetic

For each of the class templates in this section, each template parameter refers to a `ratio`. If the implementation is unable to form the indicated `ratio` due to overflow, a diagnostic will be issued.

###### `ratio_add<>`

    template <class R1, class R2> struct ratio_add {
       typedef [/see below] type;
    };

The nested typedef `type` is a synonym for ``ratio`<R1::num * R2::den + R2::num * R1::den, R1::den * R2::den>::type`.

###### `ratio_subtract<>`

    template <class R1, class R2> struct ratio_subtract {
       typedef  [/see below]  type;
    };

The nested typedef `type` is a synonym for ``ratio`<R1::num * R2::den - R2::num * R1::den, R1::den * R2::den>::type`.

###### `ratio_multiply<>`

    template <class R1, class R2> struct ratio_multiply {
       typedef  [/see below]  type;
    };

The nested typedef `type` is a synonym for ``ratio`<R1::num * R2::num, R1::den * R2::den>::type`.

###### `ratio_divide<>`

    template <class R1, class R2> struct ratio_divide {
       typedef  [/see below]  type;
    };

The nested typedef `type` is a synonym for ``ratio`<R1::num * R2::den, R2::num * R1::den>::type`.

###### `ratio_negate<>`

This extension of the C++ standard helps in the definition of some Boost.MPL numeric metafunctions.

    template <class R> struct ratio_negate {
       typedef  [/see below]  type;
    };

The nested typedef `type` is a synonym for ``ratio`<-R::num, R::den>::type`.

###### `ratio_abs<>`

This extension of the C++ standard helps in the definition of some Boost.MPL numeric metafunctions.

    template <class R> struct ratio_abs {
       typedef  [/see below]  type;
    };

The nested typedef `type` is a synonym for ``ratio`<abs_c<intmax_t,R::num>::value, R::den>::type`.

###### `ratio_sign<>`

This extension of the C++ standard helps in the definition of some Boost.MPL numeric metafunctions.

    template <class R> struct ratio_sign {
       typedef  [/see below]  type;
    };

The nested typedef `type` is a synonym for `sign_c<intmax_t,R::num>::type`.

###### `ratio_gcd<>`

This extension of the C++ standard helps in the definition of some Boost.MPL numeric metafunctions.

    template <class R1, class R2> struct ratio_gcd {
       typedef  [/see below]  type;
    };

The nested typedef `type` is a synonym for `ratio<gcd_c<intmax_t, R1::num, R2::num>::value, mpl::lcm_c<intmax_t, R1::den, R2::den>::value>::type`.

###### `ratio_lcm<>`

This extension of the C++ standard helps in the definition of some Boost.MPL numeric metafunctions.

    template <class R1, class R2> struct ratio_lcm {
       typedef  [/see below]  type;
    };

The nested typedef `type` is a synonym for `ratio<lcm_c<intmax_t, R1::num, R2::num>::value, gcd_c<intmax_t, R1::den, R2::den>::value>::type`.

##### `ratio` Comparison

###### `ratio_equal<>`

    template <class R1, class R2>  struct ratio_equal
        : public boost::integral_constant<bool, [/see below] > {};

If R1::num == R2::num && R1::den == R2::den, ratio_equal derives from true_type, else derives from false_type.

###### `ratio_not_equal<>`

    template <class R1, class R2>  struct ratio_not_equal
        : public boost::integral_constant<bool, !ratio_equal<R1, R2>::value> {};

###### `ratio_less<>`

    template <class R1, class R2>
    struct ratio_less
        : public boost::integral_constant<bool, [/see below] > {};

If R1::num * R2::den < R2::num * R1::den, ratio_less derives from true_type, else derives from false_type.

###### `ratio_less_equal<>`

    template <class R1, class R2> struct ratio_less_equal
        : public boost::integral_constant<bool, !ratio_less<R2, R1>::value> {};

###### `ratio_greater<>`

    template <class R1, class R2> struct ratio_greater
        : public boost::integral_constant<bool, ratio_less<R2, R1>::value> {};

###### `ratio_greater_equal<>`

    template <class R1, class R2> struct ratio_greater_equal
        : public boost::integral_constant<bool, !ratio_less<R1, R2>::value> {};

##### SI typedefs

The International System of Units specifies twenty SI prefixes. Boost.Ratio defines all except `yocto`, `zepto`, `zetta`, and `yotta`

    // convenience SI typedefs
    typedef ratio<1LL, 1000000000000000000LL> atto;
    typedef ratio<1LL,    1000000000000000LL> femto;
    typedef ratio<1LL,       1000000000000LL> pico;
    typedef ratio<1LL,          1000000000LL> nano;
    typedef ratio<1LL,             1000000LL> micro;
    typedef ratio<1LL,                1000LL> milli;
    typedef ratio<1LL,                 100LL> centi;
    typedef ratio<1LL,                  10LL> deci;
    typedef ratio<                 10LL, 1LL> deca;
    typedef ratio<                100LL, 1LL> hecto;
    typedef ratio<               1000LL, 1LL> kilo;
    typedef ratio<            1000000LL, 1LL> mega;
    typedef ratio<         1000000000LL, 1LL> giga;
    typedef ratio<      1000000000000LL, 1LL> tera;
    typedef ratio<   1000000000000000LL, 1LL> peta;
    typedef ratio<1000000000000000000LL, 1LL> exa;

##### Limitations

The following are limitations of Boost.Ratio relative to the specification in the C++0x draft standard:

- Four of the SI units typedefs -- `yocto`, `zepto`, `zetta`, and `yotta` -- are to be conditionally supported, if the range of `intmax_t` allows, but are not supported by Boost.Ratio.
- Ratio values should be of type static `constexpr intmax_t` (see Ratio values should be constexpr), but for compiler not supporting `constexpr` today, Boost.Ratio uses `static const intmax_t` instead.
- Rational arithmetic should use template aliases (see Rational Arithmetic should use template aliases), but those are not available in C++03, so inheritance is used instead.

##### Extensions

When `BOOST_RATIO_EXTENSIONS` is defined Boost.Ratio provides the following extensions:

- Extends the requirements of the C++0x draft standard by making the copy constructor and copy assignment operator have the same normalized form (see copy constructor and assignment between ratios having the same normalized form).
- More C++ standard like metafunctions applied to ratio types, like __static_abs or __static_negate.
- An __Boost_Mpl rational constant concept and the associated __Boost_Mpl arithmetic and comparison specializations including __numeric_cast, __plus, __equal_to between others.

### Ratio I/O

#### Header `<boost/ratio/ratio_io.hpp>`

This header provides `ratio_string<>` which can generate a textual representation of a `ratio<>` in the form of a `std::basic_string<>`. These strings can be useful for I/O.

    namespace boost {
        template <class Ratio, class CharT>
        struct ratio_string
        {
            static std::basic_string<CharT> short_name();
            static std::basic_string<CharT> long_name();
        };
    }

### Rational Constant

#### Rational Constant Concept

###### Description

A Rational Constant is a holder class for a compile-time value of a rational type. Every Rational Constant is also a nullary Metafunction, returning itself. A rational constant object is implicitly convertible to the corresponding run-time value of the rational type.

###### Expression requirements

In the following table and subsequent specifications, r is a model of Rational Constant.

Expression | Type | Complexity
--- | --- | ---
`r::tag` | `rational_c_tag` | Constant time
`r::value_type` | A rational type | Constant time
`r::num_type` | An integral type | Constant time
`r::den_type` | An integral type | Constant time
`r::num` | An Integral constant expression | Constant time
`r::den` | An Integral constant expression | Constant time
`r::type` | Rational Constant | Constant time
`r::value_type const c=r()` |  | Constant time

###### Expression semantics

Expression | Semantics
--- | ---
`r::tag` | r's tag type; r::tag::value is r's conversion rank.
`r::value_type` | A cv-unqualified type of `r()`
`r::num_type` | A cv-unqualified type of `r::num`
`r::den_type` | A cv-unqualified type of `r::den`
`r::num` | The numerator of the rational constant
`r::den` | The denominator of the rational constant
`r::type` | equal_to<n::type,n>::value == true.
`r::value_type const c=r()` | `r::value_type const c=r::value_type(r::num,r::den)`

###### Models

- `ratio`<>

#### Header `<boost/ratio/mpl/rational_constant.hpp>`

This header includes all the rational constant related header files

    #include <boost/ratio/mpl/rational_c_tag.hpp>
    #include <boost/ratio/mpl/numeric_cast.hpp>
    #include <boost/ratio/mpl/arithmetic.hpp>
    #include <boost/ratio/mpl/comparison.hpp>

#### Header `<boost/ratio/mpl/rational_c_tag.hpp>`

    namespace boost {
    namespace mpl {

        struct rational_c_tag : int_<10> {};

    }
    }

#### Header `<boost/ratio/mpl/numeric_cast.hpp>`

    namespace boost {
    namespace mpl {

        template<> struct numeric_cast< integral_c_tag,rational_c_tag >;

    }
    }

##### `mpl::numeric_cast<>` Specialization

A Integral Constant is seen as a ratio with numerator the Integral Constant value and denominator 1.

    template<> struct numeric_cast< integral_c_tag,rational_c_tag >
    {
        template< typename N > struct apply
            : ratio< N::value, 1 >
        {
        };
    };

#### Header `<boost/ratio/mpl/arithmetic.hpp>`

This header includes all the rational constant arithmetic MPL specializations.

    #include <boost/ratio/mpl/plus.hpp>
    #include <boost/ratio/mpl/minus.hpp>
    #include <boost/ratio/mpl/times.hpp>
    #include <boost/ratio/mpl/divides.hpp>
    #include <boost/ratio/mpl/negate.hpp>
    #include <boost/ratio/mpl/abs.hpp>
    #include <boost/ratio/mpl/sign.hpp>
    #include <boost/ratio/mpl/gcd.hpp>
    #include <boost/ratio/mpl/lcm.hpp>

#### Header `<boost/ratio/mpl/plus.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct plus_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::plus_impl<>` Specialization

The specialization relays on the `ratio_add` template class.

    template<>
    struct plus_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_add<R1, R2>
        {
        };
    };

#### Header `<boost/ratio/mpl/minus.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct minus_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::minus_impl<>` Specialization

The specialization relays on the `ratio_subtract` template class.

    template<>
    struct plus_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_subtract<R1, R2>
        {
        };
    };

#### Header `<boost/ratio/mpl/times.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct times_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::times_impl<>` Specialization

The specialization relays on the `ratio_multiply` template class.

    template<>
    struct times_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_multiply<R1, R2>
        {
        };
    };

#### Header `<boost/ratio/mpl/divides.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct divides_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::divides_impl<>` Specialization

The specialization relays on the `ratio_divide` template class.

    template<>
    struct divides_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_divide<R1, R2>
        {
        };
    };

#### Header `<boost/ratio/mpl/gcd.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct gcd_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::gcd_impl<>` Specialization

The specialization relays on the `ratio_gcd` template class.

    template<>
    struct gcd_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_gcd<R1, R2>
        {
        };
    };

#### Header `<boost/ratio/mpl/lcm.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct lcm_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::lcm_impl<>` Specialization

The specialization relays on the `ratio_lcm` template class.

    template<>
    struct lcm_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_lcm<R1, R2>
        {
        };
    };

#### Header `<boost/ratio/mpl/negate.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct negate_impl< rational_c_tag >;
    }
    }

##### `mpl::negate_impl<>` Specialization

The specialization relays on the `ratio_negate` template class.

    template<>
    struct negate_impl< rational_c_tag >
    {
        template< typename R > struct apply
            : ratio_negate<R>
        {
        };
    };

#### Header `<boost/ratio/mpl/abs.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct abs_impl< rational_c_tag >;
    }
    }

##### `mpl::abs_impl<>` Specialization

The specialization relays on the `ratio_abs` template class.

    template<>
    struct abs_impl< rational_c_tag >
    {
        template< typename R > struct apply
            : ratio_abs<R>
        {
        };
    };

#### Header `<boost/ratio/mpl/sign.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct sign_impl< rational_c_tag >;
    }
    }

##### `mpl::sign_impl<>` Specialization

The specialization relays on the `ratio_sign` template class.

    template<>
    struct sign_impl< rational_c_tag >
    {
        template< typename R > struct apply
            : ratio_sign<R>
        {
        };
    };

#### Header `<boost/ratio/mpl/comparison.hpp>`

This header includes all the rational constant comparison MPL specializations.

    #include <boost/ratio/mpl/equal_to.hpp>
    #include <boost/ratio/mpl/not_equal_to.hpp>
    #include <boost/ratio/mpl/less.hpp>
    #include <boost/ratio/mpl/less_equal.hpp>
    #include <boost/ratio/mpl/greater.hpp>
    #include <boost/ratio/mpl/greater_equal.hpp>

#### Header `<boost/ratio/mpl/equal_to.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct equal_to_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::equal_to_impl<>` Specialization

The specialization relays on the `ratio_equal` template class.

    template<>
    struct equal_to_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_equal<R1, R2>
        {
        };
    };

#### Header `<boost/ratio/mpl/not_equal_to.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct not_equal_to_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::not_equal_to_impl<>` Specialization

The specialization relays on the `ratio_not_equal` template class.

    template<>
    struct not_equal_to_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_not_equal<R1, R2>
        {
        };
    };

#### Header `<boost/ratio/mpl/less.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct less_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::less_impl<>` Specialization

The specialization relays on the `ratio_less` template class.

    template<>
    struct less_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_less<R1, R2>
        {
        };
    };

#### Header `<boost/ratio/mpl/less_equal.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct less_equal_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::less_equal_impl<>` Specialization

The specialization relays on the `ratio_less_equal` template class.

    template<>
    struct less_equal_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_less_equal<R1, R2>
        {
        };
    };

#### Header `<boost/ratio/mpl/greater.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct greater_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::greater_impl<>` Specialization

The specialization relays on the `ratio_greater` template class.

    template<>
    struct greater_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_greater<R1, R2>
        {
        };
    };

#### Header `<boost/ratio/mpl/greater_equal.hpp>`

    namespace boost {
    namespace mpl {
        template<>
        struct greater_equal_impl< rational_c_tag,rational_c_tag >;
    }
    }

##### `mpl::greater_equal_impl<>` Specialization

The specialization relays on the `ratio_greater_equal` template class.

    template<>
    struct greater_equal_impl< rational_c_tag,rational_c_tag >
    {
        template< typename R1, typename R2 > struct apply
            : ratio_greater_equal<R1, R2>
        {
        };
    };