123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- /*!
- @file
- Adapts `std::ratio` for use with Hana.
- @copyright Louis Dionne 2013-2017
- Distributed under the Boost Software License, Version 1.0.
- (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
- */
- #ifndef BOOST_HANA_EXT_STD_RATIO_HPP
- #define BOOST_HANA_EXT_STD_RATIO_HPP
- #include <boost/hana/bool.hpp>
- #include <boost/hana/concept/integral_constant.hpp>
- #include <boost/hana/config.hpp>
- #include <boost/hana/core/when.hpp>
- #include <boost/hana/fwd/core/to.hpp>
- #include <boost/hana/fwd/core/tag_of.hpp>
- #include <boost/hana/fwd/div.hpp>
- #include <boost/hana/fwd/equal.hpp>
- #include <boost/hana/fwd/less.hpp>
- #include <boost/hana/fwd/minus.hpp>
- #include <boost/hana/fwd/mod.hpp>
- #include <boost/hana/fwd/mult.hpp>
- #include <boost/hana/fwd/one.hpp>
- #include <boost/hana/fwd/plus.hpp>
- #include <boost/hana/fwd/zero.hpp>
- #include <cstdint>
- #include <ratio>
- #include <type_traits>
- #ifdef BOOST_HANA_DOXYGEN_INVOKED
- namespace std {
- //! @ingroup group-ext-std
- //! Adaptation of `std::ratio` for Hana.
- //!
- //!
- //! Modeled concepts
- //! ----------------
- //! 1. `Comparable`\n
- //! `std::ratio`s are compared for equality using `std::ratio_equal`.
- //! @include example/ext/std/ratio/comparable.cpp
- //!
- //! 2. `Orderable`\n
- //! `std::ratio`s are ordered using `std::ratio_less`.
- //! @include example/ext/std/ratio/orderable.cpp
- //!
- //! 3. `Monoid`, `Group`, `Ring`, and `EuclideanRing`\n
- //! `std::ratio`s are added, subtracted, multiplied and divided using
- //! `std::ratio_add`, `std::ratio_subtract`, `std::ratio_multiply` and
- //! `std::ratio_divide`, respectively. Furthermore, the neutral element
- //! for the additive operation is `std::ratio<0, 1>{}`, and the neutral
- //! element for the multiplicative operation is `std::ratio<1, 1>{}`.
- //! @include example/ext/std/ratio/arithmetic.cpp
- template <std::intmax_t Num, std::intmax_t Denom>
- class ratio { };
- }
- #endif
- BOOST_HANA_NAMESPACE_BEGIN
- namespace ext { namespace std { struct ratio_tag; }}
- template <std::intmax_t num, std::intmax_t den>
- struct tag_of<std::ratio<num, den>> {
- using type = ext::std::ratio_tag;
- };
- //////////////////////////////////////////////////////////////////////////
- // Conversion from IntegralConstants
- //////////////////////////////////////////////////////////////////////////
- template <typename C>
- struct to_impl<ext::std::ratio_tag, C, when<
- hana::IntegralConstant<C>::value
- >> {
- template <typename N>
- static constexpr auto apply(N const&) {
- return std::ratio<N::value>{};
- }
- };
- //////////////////////////////////////////////////////////////////////////
- // Comparable
- //////////////////////////////////////////////////////////////////////////
- template <>
- struct equal_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
- template <typename R1, typename R2>
- static constexpr auto apply(R1 const&, R2 const&)
- { return hana::bool_c<std::ratio_equal<R1, R2>::value>; }
- };
- //////////////////////////////////////////////////////////////////////////
- // Orderable
- //////////////////////////////////////////////////////////////////////////
- template <>
- struct less_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
- template <typename R1, typename R2>
- static constexpr auto apply(R1 const&, R2 const&)
- { return hana::bool_c<std::ratio_less<R1, R2>::value>; }
- };
- //////////////////////////////////////////////////////////////////////////
- // Monoid
- //////////////////////////////////////////////////////////////////////////
- template <>
- struct plus_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
- template <typename R1, typename R2>
- static constexpr std::ratio_add<R1, R2> apply(R1 const&, R2 const&)
- { return {}; }
- };
- template <>
- struct zero_impl<ext::std::ratio_tag> {
- static constexpr std::ratio<0> apply()
- { return {}; }
- };
- //////////////////////////////////////////////////////////////////////////
- // Group
- //////////////////////////////////////////////////////////////////////////
- template <>
- struct minus_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
- template <typename R1, typename R2>
- static constexpr std::ratio_subtract<R1, R2> apply(R1 const&, R2 const&)
- { return {}; }
- };
- //////////////////////////////////////////////////////////////////////////
- // Ring
- //////////////////////////////////////////////////////////////////////////
- template <>
- struct mult_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
- template <typename R1, typename R2>
- static constexpr std::ratio_multiply<R1, R2> apply(R1 const&, R2 const&)
- { return {}; }
- };
- template <>
- struct one_impl<ext::std::ratio_tag> {
- static constexpr std::ratio<1> apply()
- { return {}; }
- };
- //////////////////////////////////////////////////////////////////////////
- // EuclideanRing
- //////////////////////////////////////////////////////////////////////////
- template <>
- struct div_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
- template <typename R1, typename R2>
- static constexpr std::ratio_divide<R1, R2> apply(R1 const&, R2 const&)
- { return {}; }
- };
- template <>
- struct mod_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
- template <typename R1, typename R2>
- static constexpr std::ratio<0> apply(R1 const&, R2 const&)
- { return {}; }
- };
- BOOST_HANA_NAMESPACE_END
- #endif // !BOOST_HANA_EXT_STD_RATIO_HPP
|