operators.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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) 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_OPERATORS_HPP
  11. #define BOOST_UNITS_OPERATORS_HPP
  12. ///
  13. /// \file
  14. /// \brief Compile time operators and typeof helper classes.
  15. /// \details
  16. /// These operators declare the compile-time operators needed to support dimensional
  17. /// analysis algebra. They require the use of Boost.Typeof, emulation or native.
  18. /// Typeof helper classes define result type for heterogeneous operators on value types.
  19. /// These must be defined through specialization for powers and roots.
  20. ///
  21. #include <boost/static_assert.hpp>
  22. #include <boost/type_traits/is_same.hpp>
  23. #include <boost/units/config.hpp>
  24. namespace boost {
  25. namespace units {
  26. #if BOOST_UNITS_HAS_TYPEOF
  27. #ifndef BOOST_UNITS_DOXYGEN
  28. // to avoid need for default constructor and eliminate divide by zero errors.
  29. namespace typeof_ {
  30. /// INTERNAL ONLY
  31. template<class T> T make();
  32. } // namespace typeof_
  33. #endif
  34. #if (BOOST_UNITS_HAS_BOOST_TYPEOF)
  35. template<typename X> struct unary_plus_typeof_helper
  36. {
  37. BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (+typeof_::make<X>()))
  38. typedef typename nested::type type;
  39. };
  40. template<typename X> struct unary_minus_typeof_helper
  41. {
  42. BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (-typeof_::make<X>()))
  43. typedef typename nested::type type;
  44. };
  45. template<typename X,typename Y> struct add_typeof_helper
  46. {
  47. BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()+typeof_::make<Y>()))
  48. typedef typename nested::type type;
  49. };
  50. template<typename X,typename Y> struct subtract_typeof_helper
  51. {
  52. BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()-typeof_::make<Y>()))
  53. typedef typename nested::type type;
  54. };
  55. template<typename X,typename Y> struct multiply_typeof_helper
  56. {
  57. BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()*typeof_::make<Y>()))
  58. typedef typename nested::type type;
  59. };
  60. template<typename X,typename Y> struct divide_typeof_helper
  61. {
  62. BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()/typeof_::make<Y>()))
  63. typedef typename nested::type type;
  64. };
  65. #elif (BOOST_UNITS_HAS_MWERKS_TYPEOF)
  66. template<typename X> struct unary_plus_typeof_helper { typedef __typeof__((+typeof_::make<X>())) type; };
  67. template<typename X> struct unary_minus_typeof_helper { typedef __typeof__((-typeof_::make<X>())) type; };
  68. template<typename X,typename Y> struct add_typeof_helper { typedef __typeof__((typeof_::make<X>()+typeof_::make<Y>())) type; };
  69. template<typename X,typename Y> struct subtract_typeof_helper { typedef __typeof__((typeof_::make<X>()-typeof_::make<Y>())) type; };
  70. template<typename X,typename Y> struct multiply_typeof_helper { typedef __typeof__((typeof_::make<X>()*typeof_::make<Y>())) type; };
  71. template<typename X,typename Y> struct divide_typeof_helper { typedef __typeof__((typeof_::make<X>()/typeof_::make<Y>())) type; };
  72. #elif (BOOST_UNITS_HAS_GNU_TYPEOF) || defined(BOOST_UNITS_DOXYGEN)
  73. template<typename X> struct unary_plus_typeof_helper { typedef typeof((+typeof_::make<X>())) type; };
  74. template<typename X> struct unary_minus_typeof_helper { typedef typeof((-typeof_::make<X>())) type; };
  75. template<typename X,typename Y> struct add_typeof_helper { typedef typeof((typeof_::make<X>()+typeof_::make<Y>())) type; };
  76. template<typename X,typename Y> struct subtract_typeof_helper { typedef typeof((typeof_::make<X>()-typeof_::make<Y>())) type; };
  77. template<typename X,typename Y> struct multiply_typeof_helper { typedef typeof((typeof_::make<X>()*typeof_::make<Y>())) type; };
  78. template<typename X,typename Y> struct divide_typeof_helper { typedef typeof((typeof_::make<X>()/typeof_::make<Y>())) type; };
  79. #endif
  80. #else // BOOST_UNITS_HAS_TYPEOF
  81. template<typename X> struct unary_plus_typeof_helper { typedef X type; };
  82. template<typename X> struct unary_minus_typeof_helper { typedef X type; };
  83. template<typename X,typename Y> struct add_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };
  84. template<typename X,typename Y> struct subtract_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };
  85. template<typename X,typename Y> struct multiply_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };
  86. template<typename X,typename Y> struct divide_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };
  87. #endif // BOOST_UNITS_HAS_TYPEOF
  88. template<typename X,typename Y> struct power_typeof_helper;
  89. template<typename X,typename Y> struct root_typeof_helper;
  90. #ifdef BOOST_UNITS_DOXYGEN
  91. /// A helper used by @c pow to raise
  92. /// a runtime object to a compile time
  93. /// known exponent. This template is intended to
  94. /// be specialized. All specializations must
  95. /// conform to the interface shown here.
  96. /// @c Exponent will be either the exponent
  97. /// passed to @c pow or @c static_rational<N>
  98. /// for and integer argument, N.
  99. template<typename BaseType, typename Exponent>
  100. struct power_typeof_helper
  101. {
  102. /// specifies the result type
  103. typedef detail::unspecified type;
  104. /// Carries out the runtime calculation.
  105. static BOOST_CONSTEXPR type value(const BaseType& base);
  106. };
  107. /// A helper used by @c root to take a root
  108. /// of a runtime object using a compile time
  109. /// known index. This template is intended to
  110. /// be specialized. All specializations must
  111. /// conform to the interface shown here.
  112. /// @c Index will be either the type
  113. /// passed to @c pow or @c static_rational<N>
  114. /// for and integer argument, N.
  115. template<typename Radicand, typename Index>
  116. struct root_typeof_helper
  117. {
  118. /// specifies the result type
  119. typedef detail::unspecified type;
  120. /// Carries out the runtime calculation.
  121. static BOOST_CONSTEXPR type value(const Radicand& base);
  122. };
  123. #endif
  124. } // namespace units
  125. } // namespace boost
  126. #endif // BOOST_UNITS_OPERATORS_HPP