composite_pointer_type.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED
  2. #define BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED
  3. //
  4. // Copyright 2015 Peter Dimov
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt
  9. //
  10. #include <boost/type_traits/copy_cv.hpp>
  11. #include <boost/type_traits/remove_cv.hpp>
  12. #include <boost/type_traits/is_same.hpp>
  13. #include <boost/type_traits/is_void.hpp>
  14. #include <boost/type_traits/is_base_of.hpp>
  15. #include <boost/config.hpp>
  16. #include <cstddef>
  17. namespace boost
  18. {
  19. namespace type_traits_detail
  20. {
  21. template<class T, class U> struct composite_pointer_type;
  22. // same type
  23. template<class T> struct composite_pointer_type<T*, T*>
  24. {
  25. typedef T* type;
  26. };
  27. // nullptr_t
  28. #if !defined( BOOST_NO_CXX11_NULLPTR )
  29. #if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
  30. template<class T> struct composite_pointer_type<T*, decltype(nullptr)>
  31. {
  32. typedef T* type;
  33. };
  34. template<class T> struct composite_pointer_type<decltype(nullptr), T*>
  35. {
  36. typedef T* type;
  37. };
  38. template<> struct composite_pointer_type<decltype(nullptr), decltype(nullptr)>
  39. {
  40. typedef decltype(nullptr) type;
  41. };
  42. #else
  43. template<class T> struct composite_pointer_type<T*, std::nullptr_t>
  44. {
  45. typedef T* type;
  46. };
  47. template<class T> struct composite_pointer_type<std::nullptr_t, T*>
  48. {
  49. typedef T* type;
  50. };
  51. template<> struct composite_pointer_type<std::nullptr_t, std::nullptr_t>
  52. {
  53. typedef std::nullptr_t type;
  54. };
  55. #endif
  56. #endif // !defined( BOOST_NO_CXX11_NULLPTR )
  57. namespace detail
  58. {
  59. template<class T, class U> struct has_common_pointee
  60. {
  61. private:
  62. typedef typename boost::remove_cv<T>::type T2;
  63. typedef typename boost::remove_cv<U>::type U2;
  64. public:
  65. BOOST_STATIC_CONSTANT( bool, value =
  66. (boost::is_same<T2, U2>::value)
  67. || boost::is_void<T2>::value
  68. || boost::is_void<U2>::value
  69. || (boost::is_base_of<T2, U2>::value)
  70. || (boost::is_base_of<U2, T2>::value) );
  71. };
  72. template<class T, class U> struct common_pointee
  73. {
  74. private:
  75. typedef typename boost::remove_cv<T>::type T2;
  76. typedef typename boost::remove_cv<U>::type U2;
  77. public:
  78. typedef typename boost::conditional<
  79. boost::is_same<T2, U2>::value || boost::is_void<T2>::value || boost::is_base_of<T2, U2>::value,
  80. typename boost::copy_cv<T, U>::type,
  81. typename boost::copy_cv<U, T>::type
  82. >::type type;
  83. };
  84. template<class T, class U> struct composite_pointer_impl
  85. {
  86. private:
  87. typedef typename boost::remove_cv<T>::type T2;
  88. typedef typename boost::remove_cv<U>::type U2;
  89. public:
  90. typedef typename boost::copy_cv<typename boost::copy_cv<typename composite_pointer_type<T2, U2>::type const, T>::type, U>::type type;
  91. };
  92. //Old compilers like MSVC-7.1 have problems using boost::conditional in
  93. //composite_pointer_type. Partially specializing on has_common_pointee<T, U>::value
  94. //seems to make their life easier
  95. template<class T, class U, bool = has_common_pointee<T, U>::value >
  96. struct composite_pointer_type_dispatch
  97. : common_pointee<T, U>
  98. {};
  99. template<class T, class U>
  100. struct composite_pointer_type_dispatch<T, U, false>
  101. : composite_pointer_impl<T, U>
  102. {};
  103. } // detail
  104. template<class T, class U> struct composite_pointer_type<T*, U*>
  105. {
  106. typedef typename detail::composite_pointer_type_dispatch<T, U>::type* type;
  107. };
  108. } // namespace type_traits_detail
  109. } // namespace boost
  110. #endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED