common_type.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // common_type.hpp ---------------------------------------------------------//
  2. // Copyright 2008 Howard Hinnant
  3. // Copyright 2008 Beman Dawes
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // See http://www.boost.org/LICENSE_1_0.txt
  6. #ifndef BOOST_EX_TYPE_TRAITS_EXT_COMMON_TYPE_HPP
  7. #define BOOST_EX_TYPE_TRAITS_EXT_COMMON_TYPE_HPP
  8. #include <boost/config.hpp>
  9. //----------------------------------------------------------------------------//
  10. #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  11. #define BOOST_EX_COMMON_TYPE_ARITY 3
  12. #endif
  13. //----------------------------------------------------------------------------//
  14. #if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_EX_COMMON_TYPE_DONT_USE_TYPEOF)
  15. #define BOOST_TYPEOF_SILENT
  16. #include <boost/typeof/typeof.hpp> // boost wonders never cease!
  17. #endif
  18. //----------------------------------------------------------------------------//
  19. #ifndef BOOST_NO_CXX11_STATIC_ASSERT
  20. #define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG)
  21. #elif defined(BOOST_EX_COMMON_TYPE_USES_STATIC_ASSERT)
  22. #include <boost/static_assert.hpp>
  23. #define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) BOOST_STATIC_ASSERT(CND)
  24. #elif defined(BOOST_EX_COMMON_TYPE_USES_MPL_ASSERT)
  25. #include <boost/mpl/assert.hpp>
  26. #include <boost/mpl/bool.hpp>
  27. #define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) \
  28. BOOST_MPL_ASSERT_MSG(boost::mpl::bool_< (CND) >::type::value, MSG, TYPES)
  29. #else
  30. //~ #elif defined(BOOST_EX_COMMON_TYPE_USES_ARRAY_ASSERT)
  31. #define BOOST_EX_COMMON_TYPE_CONCAT(A,B) A##B
  32. #define BOOST_EX_COMMON_TYPE_NAME(A,B) BOOST_EX_COMMON_TYPE_CONCAT(A,B)
  33. #define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) static char BOOST_EX_COMMON_TYPE_NAME(__boost_common_type_test_,__LINE__)[(CND)?1:-1]
  34. //~ #define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES)
  35. #endif
  36. #if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || !defined(BOOST_EX_COMMON_TYPE_USES_MPL_ASSERT)
  37. #define BOOST_EX_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE "must be complete type"
  38. #endif
  39. #if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_EX_COMMON_TYPE_DONT_USE_TYPEOF)
  40. #include "detail/common_type.hpp"
  41. #include <boost/type_traits/remove_cv.hpp>
  42. #endif
  43. #include <boost/mpl/if.hpp>
  44. #include "declval.hpp"
  45. //----------------------------------------------------------------------------//
  46. // //
  47. // C++03 implementation of //
  48. // 20.6.7 Other transformations [meta.trans.other] //
  49. // Written by Howard Hinnant //
  50. // Adapted for Boost by Beman Dawes, Vicente Botet and Jeffrey Hellrung //
  51. // //
  52. //----------------------------------------------------------------------------//
  53. namespace boost_ex {
  54. // prototype
  55. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  56. template<typename... T>
  57. struct common_type;
  58. #else // or no specialization
  59. template <class T, class U = void, class V = void>
  60. struct common_type
  61. {
  62. public:
  63. typedef typename common_type<typename common_type<T, U>::type, V>::type type;
  64. };
  65. #endif
  66. // 1 arg
  67. template<typename T>
  68. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  69. struct common_type<T>
  70. #else
  71. struct common_type<T, void, void>
  72. #endif
  73. {
  74. BOOST_EX_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_EX_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T));
  75. public:
  76. typedef T type;
  77. };
  78. // 2 args
  79. namespace type_traits_detail {
  80. template <class T, class U>
  81. struct common_type_2
  82. {
  83. private:
  84. BOOST_EX_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_EX_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T));
  85. BOOST_EX_COMMON_TYPE_STATIC_ASSERT(sizeof(U) > 0, BOOST_EX_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (U));
  86. static bool declval_bool(); // workaround gcc bug; not required by std
  87. static typename add_rvalue_reference<T>::type declval_T(); // workaround gcc bug; not required by std
  88. static typename add_rvalue_reference<U>::type declval_U(); // workaround gcc bug; not required by std
  89. #if !defined(BOOST_NO_CXX11_DECLTYPE)
  90. public:
  91. typedef decltype(declval<bool>() ? declval<T>() : declval<U>()) type;
  92. #elif defined(BOOST_EX_COMMON_TYPE_DONT_USE_TYPEOF)
  93. public:
  94. typedef typename detail_type_traits_common_type::common_type_impl<
  95. typename remove_cv<T>::type,
  96. typename remove_cv<U>::type
  97. >::type type;
  98. #else
  99. public:
  100. //~ typedef BOOST_TYPEOF_TPL(declval_bool() ? declval_T() : declval_U()) type;
  101. typedef BOOST_TYPEOF_TPL(declval<bool>() ? declval<T>() : declval<U>()) type;
  102. #endif
  103. };
  104. template <class T>
  105. struct common_type_2<T, T>
  106. {
  107. typedef T type;
  108. };
  109. }
  110. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  111. template <class T, class U>
  112. struct common_type<T, U>
  113. #else
  114. template <class T, class U>
  115. struct common_type<T, U, void>
  116. #endif
  117. : type_traits_detail::common_type_2<T,U>
  118. { };
  119. // 3 or more args
  120. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  121. template<typename T, typename U, typename... V>
  122. struct common_type<T, U, V...> {
  123. public:
  124. typedef typename common_type<typename common_type<T, U>::type, V...>::type type;
  125. };
  126. #endif
  127. } // namespace boost_ex
  128. #endif // BOOST_TYPE_TRAITS_EXT_COMMON_TYPE_HPP