Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:57

0001 /*!
0002 @file
0003 Adapts `std::ratio` for use with Hana.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
0008  */
0009 
0010 #ifndef BOOST_HANA_EXT_STD_RATIO_HPP
0011 #define BOOST_HANA_EXT_STD_RATIO_HPP
0012 
0013 #include <boost/hana/bool.hpp>
0014 #include <boost/hana/concept/integral_constant.hpp>
0015 #include <boost/hana/config.hpp>
0016 #include <boost/hana/core/when.hpp>
0017 #include <boost/hana/fwd/core/to.hpp>
0018 #include <boost/hana/fwd/core/tag_of.hpp>
0019 #include <boost/hana/fwd/div.hpp>
0020 #include <boost/hana/fwd/equal.hpp>
0021 #include <boost/hana/fwd/less.hpp>
0022 #include <boost/hana/fwd/minus.hpp>
0023 #include <boost/hana/fwd/mod.hpp>
0024 #include <boost/hana/fwd/mult.hpp>
0025 #include <boost/hana/fwd/one.hpp>
0026 #include <boost/hana/fwd/plus.hpp>
0027 #include <boost/hana/fwd/zero.hpp>
0028 
0029 #include <cstdint>
0030 #include <ratio>
0031 #include <type_traits>
0032 
0033 
0034 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0035 namespace std {
0036     //! @ingroup group-ext-std
0037     //! Adaptation of `std::ratio` for Hana.
0038     //!
0039     //!
0040     //! Modeled concepts
0041     //! ----------------
0042     //! 1. `Comparable`\n
0043     //! `std::ratio`s are compared for equality using `std::ratio_equal`.
0044     //! @include example/ext/std/ratio/comparable.cpp
0045     //!
0046     //! 2. `Orderable`\n
0047     //! `std::ratio`s are ordered using `std::ratio_less`.
0048     //! @include example/ext/std/ratio/orderable.cpp
0049     //!
0050     //! 3. `Monoid`, `Group`, `Ring`, and `EuclideanRing`\n
0051     //! `std::ratio`s are added, subtracted, multiplied and divided using
0052     //! `std::ratio_add`, `std::ratio_subtract`, `std::ratio_multiply` and
0053     //! `std::ratio_divide`, respectively. Furthermore, the neutral element
0054     //! for the additive operation is `std::ratio<0, 1>{}`, and the neutral
0055     //! element for the multiplicative operation is `std::ratio<1, 1>{}`.
0056     //! @include example/ext/std/ratio/arithmetic.cpp
0057     template <std::intmax_t Num, std::intmax_t Denom>
0058     class ratio { };
0059 }
0060 #endif
0061 
0062 
0063 namespace boost { namespace hana {
0064     namespace ext { namespace std { struct ratio_tag; }}
0065 
0066     template <std::intmax_t num, std::intmax_t den>
0067     struct tag_of<std::ratio<num, den>> {
0068         using type = ext::std::ratio_tag;
0069     };
0070 
0071     //////////////////////////////////////////////////////////////////////////
0072     // Conversion from IntegralConstants
0073     //////////////////////////////////////////////////////////////////////////
0074     template <typename C>
0075     struct to_impl<ext::std::ratio_tag, C, when<
0076         hana::IntegralConstant<C>::value
0077     >> {
0078         template <typename N>
0079         static constexpr auto apply(N const&) {
0080             return std::ratio<N::value>{};
0081         }
0082     };
0083 
0084     //////////////////////////////////////////////////////////////////////////
0085     // Comparable
0086     //////////////////////////////////////////////////////////////////////////
0087     template <>
0088     struct equal_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
0089         template <typename R1, typename R2>
0090         static constexpr auto apply(R1 const&, R2 const&)
0091         { return hana::bool_c<std::ratio_equal<R1, R2>::value>; }
0092     };
0093 
0094     //////////////////////////////////////////////////////////////////////////
0095     // Orderable
0096     //////////////////////////////////////////////////////////////////////////
0097     template <>
0098     struct less_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
0099         template <typename R1, typename R2>
0100         static constexpr auto apply(R1 const&, R2 const&)
0101         { return hana::bool_c<std::ratio_less<R1, R2>::value>; }
0102     };
0103 
0104     //////////////////////////////////////////////////////////////////////////
0105     // Monoid
0106     //////////////////////////////////////////////////////////////////////////
0107     template <>
0108     struct plus_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
0109         template <typename R1, typename R2>
0110         static constexpr std::ratio_add<R1, R2> apply(R1 const&, R2 const&)
0111         { return {}; }
0112     };
0113 
0114     template <>
0115     struct zero_impl<ext::std::ratio_tag> {
0116         static constexpr std::ratio<0> apply()
0117         { return {}; }
0118     };
0119 
0120     //////////////////////////////////////////////////////////////////////////
0121     // Group
0122     //////////////////////////////////////////////////////////////////////////
0123     template <>
0124     struct minus_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
0125         template <typename R1, typename R2>
0126         static constexpr std::ratio_subtract<R1, R2> apply(R1 const&, R2 const&)
0127         { return {}; }
0128     };
0129 
0130     //////////////////////////////////////////////////////////////////////////
0131     // Ring
0132     //////////////////////////////////////////////////////////////////////////
0133     template <>
0134     struct mult_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
0135         template <typename R1, typename R2>
0136         static constexpr std::ratio_multiply<R1, R2> apply(R1 const&, R2 const&)
0137         { return {}; }
0138     };
0139 
0140     template <>
0141     struct one_impl<ext::std::ratio_tag> {
0142         static constexpr std::ratio<1> apply()
0143         { return {}; }
0144     };
0145 
0146     //////////////////////////////////////////////////////////////////////////
0147     // EuclideanRing
0148     //////////////////////////////////////////////////////////////////////////
0149     template <>
0150     struct div_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
0151         template <typename R1, typename R2>
0152         static constexpr std::ratio_divide<R1, R2> apply(R1 const&, R2 const&)
0153         { return {}; }
0154     };
0155 
0156     template <>
0157     struct mod_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
0158         template <typename R1, typename R2>
0159         static constexpr std::ratio<0> apply(R1 const&, R2 const&)
0160         { return {}; }
0161     };
0162 }} // end namespace boost::hana
0163 
0164 #endif // !BOOST_HANA_EXT_STD_RATIO_HPP