ratio.hpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*!
  2. @file
  3. Adapts `std::ratio` for use with Hana.
  4. @copyright Louis Dionne 2013-2017
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_EXT_STD_RATIO_HPP
  9. #define BOOST_HANA_EXT_STD_RATIO_HPP
  10. #include <boost/hana/bool.hpp>
  11. #include <boost/hana/concept/integral_constant.hpp>
  12. #include <boost/hana/config.hpp>
  13. #include <boost/hana/core/when.hpp>
  14. #include <boost/hana/fwd/core/to.hpp>
  15. #include <boost/hana/fwd/core/tag_of.hpp>
  16. #include <boost/hana/fwd/div.hpp>
  17. #include <boost/hana/fwd/equal.hpp>
  18. #include <boost/hana/fwd/less.hpp>
  19. #include <boost/hana/fwd/minus.hpp>
  20. #include <boost/hana/fwd/mod.hpp>
  21. #include <boost/hana/fwd/mult.hpp>
  22. #include <boost/hana/fwd/one.hpp>
  23. #include <boost/hana/fwd/plus.hpp>
  24. #include <boost/hana/fwd/zero.hpp>
  25. #include <cstdint>
  26. #include <ratio>
  27. #include <type_traits>
  28. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  29. namespace std {
  30. //! @ingroup group-ext-std
  31. //! Adaptation of `std::ratio` for Hana.
  32. //!
  33. //!
  34. //! Modeled concepts
  35. //! ----------------
  36. //! 1. `Comparable`\n
  37. //! `std::ratio`s are compared for equality using `std::ratio_equal`.
  38. //! @include example/ext/std/ratio/comparable.cpp
  39. //!
  40. //! 2. `Orderable`\n
  41. //! `std::ratio`s are ordered using `std::ratio_less`.
  42. //! @include example/ext/std/ratio/orderable.cpp
  43. //!
  44. //! 3. `Monoid`, `Group`, `Ring`, and `EuclideanRing`\n
  45. //! `std::ratio`s are added, subtracted, multiplied and divided using
  46. //! `std::ratio_add`, `std::ratio_subtract`, `std::ratio_multiply` and
  47. //! `std::ratio_divide`, respectively. Furthermore, the neutral element
  48. //! for the additive operation is `std::ratio<0, 1>{}`, and the neutral
  49. //! element for the multiplicative operation is `std::ratio<1, 1>{}`.
  50. //! @include example/ext/std/ratio/arithmetic.cpp
  51. template <std::intmax_t Num, std::intmax_t Denom>
  52. class ratio { };
  53. }
  54. #endif
  55. BOOST_HANA_NAMESPACE_BEGIN
  56. namespace ext { namespace std { struct ratio_tag; }}
  57. template <std::intmax_t num, std::intmax_t den>
  58. struct tag_of<std::ratio<num, den>> {
  59. using type = ext::std::ratio_tag;
  60. };
  61. //////////////////////////////////////////////////////////////////////////
  62. // Conversion from IntegralConstants
  63. //////////////////////////////////////////////////////////////////////////
  64. template <typename C>
  65. struct to_impl<ext::std::ratio_tag, C, when<
  66. hana::IntegralConstant<C>::value
  67. >> {
  68. template <typename N>
  69. static constexpr auto apply(N const&) {
  70. return std::ratio<N::value>{};
  71. }
  72. };
  73. //////////////////////////////////////////////////////////////////////////
  74. // Comparable
  75. //////////////////////////////////////////////////////////////////////////
  76. template <>
  77. struct equal_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
  78. template <typename R1, typename R2>
  79. static constexpr auto apply(R1 const&, R2 const&)
  80. { return hana::bool_c<std::ratio_equal<R1, R2>::value>; }
  81. };
  82. //////////////////////////////////////////////////////////////////////////
  83. // Orderable
  84. //////////////////////////////////////////////////////////////////////////
  85. template <>
  86. struct less_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
  87. template <typename R1, typename R2>
  88. static constexpr auto apply(R1 const&, R2 const&)
  89. { return hana::bool_c<std::ratio_less<R1, R2>::value>; }
  90. };
  91. //////////////////////////////////////////////////////////////////////////
  92. // Monoid
  93. //////////////////////////////////////////////////////////////////////////
  94. template <>
  95. struct plus_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
  96. template <typename R1, typename R2>
  97. static constexpr std::ratio_add<R1, R2> apply(R1 const&, R2 const&)
  98. { return {}; }
  99. };
  100. template <>
  101. struct zero_impl<ext::std::ratio_tag> {
  102. static constexpr std::ratio<0> apply()
  103. { return {}; }
  104. };
  105. //////////////////////////////////////////////////////////////////////////
  106. // Group
  107. //////////////////////////////////////////////////////////////////////////
  108. template <>
  109. struct minus_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
  110. template <typename R1, typename R2>
  111. static constexpr std::ratio_subtract<R1, R2> apply(R1 const&, R2 const&)
  112. { return {}; }
  113. };
  114. //////////////////////////////////////////////////////////////////////////
  115. // Ring
  116. //////////////////////////////////////////////////////////////////////////
  117. template <>
  118. struct mult_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
  119. template <typename R1, typename R2>
  120. static constexpr std::ratio_multiply<R1, R2> apply(R1 const&, R2 const&)
  121. { return {}; }
  122. };
  123. template <>
  124. struct one_impl<ext::std::ratio_tag> {
  125. static constexpr std::ratio<1> apply()
  126. { return {}; }
  127. };
  128. //////////////////////////////////////////////////////////////////////////
  129. // EuclideanRing
  130. //////////////////////////////////////////////////////////////////////////
  131. template <>
  132. struct div_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
  133. template <typename R1, typename R2>
  134. static constexpr std::ratio_divide<R1, R2> apply(R1 const&, R2 const&)
  135. { return {}; }
  136. };
  137. template <>
  138. struct mod_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
  139. template <typename R1, typename R2>
  140. static constexpr std::ratio<0> apply(R1 const&, R2 const&)
  141. { return {}; }
  142. };
  143. BOOST_HANA_NAMESPACE_END
  144. #endif // !BOOST_HANA_EXT_STD_RATIO_HPP