unscale.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. // Boost.Units - A C++ library for zero-overhead dimensional analysis and
  2. // unit/quantity manipulation and conversion
  3. //
  4. // Copyright (C) 2003-2008 Matthias Christian Schabel
  5. // Copyright (C) 2007-2008 Steven Watanabe
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See
  8. // accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_UNITS_DETAIL_UNSCALE_HPP_INCLUDED
  11. #define BOOST_UNITS_DETAIL_UNSCALE_HPP_INCLUDED
  12. #include <string>
  13. #include <boost/mpl/bool.hpp>
  14. #include <boost/mpl/size.hpp>
  15. #include <boost/mpl/begin.hpp>
  16. #include <boost/mpl/next.hpp>
  17. #include <boost/mpl/deref.hpp>
  18. #include <boost/mpl/plus.hpp>
  19. #include <boost/mpl/times.hpp>
  20. #include <boost/mpl/negate.hpp>
  21. #include <boost/mpl/less.hpp>
  22. #include <boost/units/config.hpp>
  23. #include <boost/units/dimension.hpp>
  24. #include <boost/units/scale.hpp>
  25. #include <boost/units/static_rational.hpp>
  26. #include <boost/units/units_fwd.hpp>
  27. #include <boost/units/detail/one.hpp>
  28. namespace boost {
  29. namespace units {
  30. template<class T>
  31. struct heterogeneous_system;
  32. template<class T, class D, class Scale>
  33. struct heterogeneous_system_impl;
  34. template<class T, class E>
  35. struct heterogeneous_system_dim;
  36. template<class S, class Scale>
  37. struct scaled_base_unit;
  38. /// removes all scaling from a unit or a base unit.
  39. template<class T>
  40. struct unscale
  41. {
  42. #ifndef BOOST_UNITS_DOXYGEN
  43. typedef T type;
  44. #else
  45. typedef detail::unspecified type;
  46. #endif
  47. };
  48. /// INTERNAL ONLY
  49. template<class S, class Scale>
  50. struct unscale<scaled_base_unit<S, Scale> >
  51. {
  52. typedef typename unscale<S>::type type;
  53. };
  54. /// INTERNAL ONLY
  55. template<class D, class S>
  56. struct unscale<unit<D, S> >
  57. {
  58. typedef unit<D, typename unscale<S>::type> type;
  59. };
  60. /// INTERNAL ONLY
  61. template<class Scale>
  62. struct scale_list_dim;
  63. /// INTERNAL ONLY
  64. template<class T>
  65. struct get_scale_list
  66. {
  67. typedef dimensionless_type type;
  68. };
  69. /// INTERNAL ONLY
  70. template<class S, class Scale>
  71. struct get_scale_list<scaled_base_unit<S, Scale> >
  72. {
  73. typedef typename mpl::times<list<scale_list_dim<Scale>, dimensionless_type>, typename get_scale_list<S>::type>::type type;
  74. };
  75. /// INTERNAL ONLY
  76. template<class D, class S>
  77. struct get_scale_list<unit<D, S> >
  78. {
  79. typedef typename get_scale_list<S>::type type;
  80. };
  81. /// INTERNAL ONLY
  82. struct scale_dim_tag {};
  83. /// INTERNAL ONLY
  84. template<class Scale>
  85. struct scale_list_dim : Scale
  86. {
  87. typedef scale_dim_tag tag;
  88. typedef scale_list_dim type;
  89. };
  90. } // namespace units
  91. #ifndef BOOST_UNITS_DOXYGEN
  92. namespace mpl {
  93. /// INTERNAL ONLY
  94. template<>
  95. struct less_impl<boost::units::scale_dim_tag, boost::units::scale_dim_tag>
  96. {
  97. template<class T0, class T1>
  98. struct apply : mpl::bool_<((T0::base) < (T1::base))> {};
  99. };
  100. }
  101. #endif
  102. namespace units {
  103. namespace detail {
  104. template<class Scale>
  105. struct is_empty_dim<scale_list_dim<Scale> > : mpl::false_ {};
  106. template<long N>
  107. struct is_empty_dim<scale_list_dim<scale<N, static_rational<0, 1> > > > : mpl::true_ {};
  108. template<int N>
  109. struct eval_scale_list_impl
  110. {
  111. template<class Begin>
  112. struct apply
  113. {
  114. typedef typename eval_scale_list_impl<N-1>::template apply<typename Begin::next> next_iteration;
  115. typedef typename multiply_typeof_helper<typename next_iteration::type, typename Begin::item::value_type>::type type;
  116. static BOOST_CONSTEXPR type value()
  117. {
  118. return(next_iteration::value() * Begin::item::value());
  119. }
  120. };
  121. };
  122. template<>
  123. struct eval_scale_list_impl<0>
  124. {
  125. template<class Begin>
  126. struct apply
  127. {
  128. typedef one type;
  129. static BOOST_CONSTEXPR one value()
  130. {
  131. return(one());
  132. }
  133. };
  134. };
  135. }
  136. /// INTERNAL ONLY
  137. template<class T>
  138. struct eval_scale_list : detail::eval_scale_list_impl<T::size::value>::template apply<T> {};
  139. } // namespace units
  140. #ifndef BOOST_UNITS_DOXYGEN
  141. namespace mpl {
  142. /// INTERNAL ONLY
  143. template<>
  144. struct plus_impl<boost::units::scale_dim_tag, boost::units::scale_dim_tag>
  145. {
  146. template<class T0, class T1>
  147. struct apply
  148. {
  149. typedef boost::units::scale_list_dim<
  150. boost::units::scale<
  151. (T0::base),
  152. typename mpl::plus<typename T0::exponent, typename T1::exponent>::type
  153. >
  154. > type;
  155. };
  156. };
  157. /// INTERNAL ONLY
  158. template<>
  159. struct negate_impl<boost::units::scale_dim_tag>
  160. {
  161. template<class T0>
  162. struct apply
  163. {
  164. typedef boost::units::scale_list_dim<
  165. boost::units::scale<
  166. (T0::base),
  167. typename mpl::negate<typename T0::exponent>::type
  168. >
  169. > type;
  170. };
  171. };
  172. /// INTERNAL ONLY
  173. template<>
  174. struct times_impl<boost::units::scale_dim_tag, boost::units::detail::static_rational_tag>
  175. {
  176. template<class T0, class T1>
  177. struct apply
  178. {
  179. typedef boost::units::scale_list_dim<
  180. boost::units::scale<
  181. (T0::base),
  182. typename mpl::times<typename T0::exponent, T1>::type
  183. >
  184. > type;
  185. };
  186. };
  187. /// INTERNAL ONLY
  188. template<>
  189. struct divides_impl<boost::units::scale_dim_tag, boost::units::detail::static_rational_tag>
  190. {
  191. template<class T0, class T1>
  192. struct apply
  193. {
  194. typedef boost::units::scale_list_dim<
  195. boost::units::scale<
  196. (T0::base),
  197. typename mpl::divides<typename T0::exponent, T1>::type
  198. >
  199. > type;
  200. };
  201. };
  202. } // namespace mpl
  203. #endif
  204. } // namespace boost
  205. #endif