dim.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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_DIM_HPP
  11. #define BOOST_UNITS_DIM_HPP
  12. #include <boost/static_assert.hpp>
  13. #include <boost/type_traits/is_same.hpp>
  14. #include <boost/mpl/arithmetic.hpp>
  15. #include <boost/units/config.hpp>
  16. #include <boost/units/static_rational.hpp>
  17. #include <boost/units/detail/dim_impl.hpp>
  18. /// \file dim.hpp
  19. /// \brief Handling of fundamental dimension/exponent pairs.
  20. namespace boost {
  21. namespace units {
  22. namespace detail {
  23. struct dim_tag { };
  24. }
  25. /// \brief Dimension tag/exponent pair for a single fundamental dimension.
  26. ///
  27. /// \details
  28. /// The dim class represents a single dimension tag/dimension exponent pair.
  29. /// That is, @c dim<tag_type,value_type> is a pair where @c tag_type represents the
  30. /// fundamental dimension being represented and @c value_type represents the
  31. /// exponent of that fundamental dimension as a @c static_rational. @c tag_type must
  32. /// be a derived from a specialization of @c base_dimension.
  33. /// Specialization of the following Boost.MPL metafunctions are provided
  34. ///
  35. /// - @c mpl::plus for two @c dims
  36. /// - @c mpl::minus for two @c dims
  37. /// - @c mpl::negate for a @c dim
  38. ///
  39. /// These metafunctions all operate on the exponent, and require
  40. /// that the @c dim operands have the same base dimension tag.
  41. /// In addition, multiplication and division by @c static_rational
  42. /// is supported.
  43. ///
  44. /// - @c mpl::times for a @c static_rational and a @c dim in either order
  45. /// - @c mpl::divides for a @c static_rational and a @c dim in either order
  46. ///
  47. /// These metafunctions likewise operate on the exponent only.
  48. template<typename T,typename V>
  49. struct dim
  50. {
  51. typedef dim type;
  52. typedef detail::dim_tag tag;
  53. typedef T tag_type;
  54. typedef V value_type;
  55. };
  56. } // namespace units
  57. } // namespace boost
  58. #if BOOST_UNITS_HAS_BOOST_TYPEOF
  59. #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
  60. BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::dim, 2)
  61. #endif
  62. #ifndef BOOST_UNITS_DOXYGEN
  63. namespace boost {
  64. namespace mpl {
  65. // define MPL operators acting on dim<T,V>
  66. template<>
  67. struct plus_impl<boost::units::detail::dim_tag,boost::units::detail::dim_tag>
  68. {
  69. template<class T0, class T1>
  70. struct apply
  71. {
  72. BOOST_STATIC_ASSERT((boost::is_same<typename T0::tag_type,typename T1::tag_type>::value == true));
  73. typedef boost::units::dim<typename T0::tag_type, typename mpl::plus<typename T0::value_type, typename T1::value_type>::type> type;
  74. };
  75. };
  76. template<>
  77. struct minus_impl<boost::units::detail::dim_tag,boost::units::detail::dim_tag>
  78. {
  79. template<class T0, class T1>
  80. struct apply
  81. {
  82. BOOST_STATIC_ASSERT((boost::is_same<typename T0::tag_type,typename T1::tag_type>::value == true));
  83. typedef boost::units::dim<typename T0::tag_type, typename mpl::minus<typename T0::value_type, typename T1::value_type>::type> type;
  84. };
  85. };
  86. template<>
  87. struct times_impl<boost::units::detail::dim_tag,boost::units::detail::static_rational_tag>
  88. {
  89. template<class T0, class T1>
  90. struct apply
  91. {
  92. typedef boost::units::dim<typename T0::tag_type, typename mpl::times<typename T0::value_type, T1>::type> type;
  93. };
  94. };
  95. template<>
  96. struct times_impl<boost::units::detail::static_rational_tag,boost::units::detail::dim_tag>
  97. {
  98. template<class T0, class T1>
  99. struct apply
  100. {
  101. typedef boost::units::dim<typename T1::tag_type, typename mpl::times<T0, typename T1::value_type>::type> type;
  102. };
  103. };
  104. template<>
  105. struct divides_impl<boost::units::detail::dim_tag,boost::units::detail::static_rational_tag>
  106. {
  107. template<class T0, class T1>
  108. struct apply
  109. {
  110. typedef boost::units::dim<typename T0::tag_type, typename mpl::divides<typename T0::value_type, T1>::type> type;
  111. };
  112. };
  113. template<>
  114. struct divides_impl<boost::units::detail::static_rational_tag,boost::units::detail::dim_tag>
  115. {
  116. template<class T0, class T1>
  117. struct apply
  118. {
  119. typedef boost::units::dim<typename T1::tag_type, typename mpl::divides<T0, typename T1::value_type>::type> type;
  120. };
  121. };
  122. template<>
  123. struct negate_impl<boost::units::detail::dim_tag>
  124. {
  125. template<class T0>
  126. struct apply
  127. {
  128. typedef boost::units::dim<typename T0::tag_type,typename mpl::negate<typename T0::value_type>::type> type;
  129. };
  130. };
  131. } // namespace mpl
  132. } // namespace boost
  133. #endif
  134. #endif // BOOST_UNITS_DIM_HPP