cv_traits.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // (C) Copyright Tobias Schwinger
  2. //
  3. // Use modification and distribution are subject to the boost Software License,
  4. // Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
  5. //------------------------------------------------------------------------------
  6. #ifndef BOOST_FT_DETAIL_CV_TRAITS_HPP_INCLUDED
  7. #define BOOST_FT_DETAIL_CV_TRAITS_HPP_INCLUDED
  8. #include <cstddef>
  9. #include <boost/detail/workaround.hpp>
  10. #if BOOST_WORKAROUND(__BORLANDC__, <= 0x582)
  11. # include <boost/type_traits/remove_cv.hpp>
  12. # include <boost/type_traits/remove_pointer.hpp>
  13. # include <boost/type_traits/remove_reference.hpp>
  14. #endif
  15. #include <boost/function_types/property_tags.hpp>
  16. namespace boost { namespace function_types { namespace detail {
  17. #if !BOOST_WORKAROUND(__BORLANDC__, <= 0x582)
  18. template<typename T> struct cv_traits
  19. { typedef non_cv tag; typedef T type; };
  20. template<typename T> struct cv_traits<T &>
  21. { typedef non_cv tag; typedef T type; };
  22. template<typename T> struct cv_traits<T *>
  23. { typedef non_cv tag; typedef T type; };
  24. template<typename T> struct cv_traits<T * const>
  25. { typedef non_cv tag; typedef T type; };
  26. template<typename T> struct cv_traits<T * volatile>
  27. { typedef non_cv tag; typedef T type; };
  28. template<typename T> struct cv_traits<T * const volatile>
  29. { typedef non_cv tag; typedef T type; };
  30. template<typename T> struct cv_traits<T const>
  31. { typedef const_non_volatile tag; typedef T type; };
  32. template<typename T> struct cv_traits<T const &>
  33. { typedef const_non_volatile tag; typedef T type; };
  34. template<typename T> struct cv_traits<T const *>
  35. { typedef const_non_volatile tag; typedef T type; };
  36. template<typename T> struct cv_traits<T const * const>
  37. { typedef const_non_volatile tag; typedef T type; };
  38. template<typename T> struct cv_traits<T const * volatile>
  39. { typedef const_non_volatile tag; typedef T type; };
  40. template<typename T> struct cv_traits<T const * const volatile>
  41. { typedef const_non_volatile tag; typedef T type; };
  42. template<typename T> struct cv_traits<T volatile>
  43. { typedef volatile_non_const tag; typedef T type; };
  44. template<typename T> struct cv_traits<T volatile &>
  45. { typedef volatile_non_const tag; typedef T type; };
  46. template<typename T> struct cv_traits<T volatile *>
  47. { typedef volatile_non_const tag; typedef T type; };
  48. template<typename T> struct cv_traits<T volatile * const>
  49. { typedef volatile_non_const tag; typedef T type; };
  50. template<typename T> struct cv_traits<T volatile * volatile>
  51. { typedef volatile_non_const tag; typedef T type; };
  52. template<typename T> struct cv_traits<T volatile * const volatile>
  53. { typedef volatile_non_const tag; typedef T type; };
  54. template<typename T> struct cv_traits<T const volatile>
  55. { typedef cv_qualified tag; typedef T type; };
  56. template<typename T> struct cv_traits<T const volatile &>
  57. { typedef cv_qualified tag; typedef T type; };
  58. template<typename T> struct cv_traits<T const volatile *>
  59. { typedef cv_qualified tag; typedef T type; };
  60. template<typename T> struct cv_traits<T const volatile * const>
  61. { typedef cv_qualified tag; typedef T type; };
  62. template<typename T> struct cv_traits<T const volatile * volatile>
  63. { typedef cv_qualified tag; typedef T type; };
  64. template<typename T> struct cv_traits<T const volatile * const volatile>
  65. { typedef cv_qualified tag; typedef T type; };
  66. #else
  67. template<std::size_t> struct cv_tag_impl;
  68. template<> struct cv_tag_impl<1> { typedef non_cv type;};
  69. template<> struct cv_tag_impl<2> { typedef const_non_volatile type; };
  70. template<> struct cv_tag_impl<3> { typedef volatile_non_const type; };
  71. template<> struct cv_tag_impl<4> { typedef cv_qualified type; };
  72. typedef char (& case_1)[1];
  73. typedef char (& case_2)[2];
  74. typedef char (& case_3)[3];
  75. typedef char (& case_4)[4];
  76. template<typename T> case_1 switch_cv(T *);
  77. template<typename T> case_2 switch_cv(T const *);
  78. template<typename T> case_3 switch_cv(T volatile *);
  79. template<typename T> case_4 switch_cv(T const volatile *);
  80. template<typename T> T * ref_to_ptr(T &);
  81. template<typename T> T const * ref_to_ptr(T const &);
  82. template<typename T> T volatile * ref_to_ptr(T volatile &);
  83. template<typename T> T const volatile * ref_to_ptr(T const volatile &);
  84. template<typename T> T * ref_to_ptr(T * const volatile &);
  85. template<typename T>
  86. struct cv_code
  87. {
  88. static T _t;
  89. BOOST_STATIC_CONSTANT(std::size_t, value =
  90. sizeof(::boost::function_types::detail::switch_cv(
  91. ::boost::function_types::detail::ref_to_ptr(_t) ) ));
  92. };
  93. template<typename T> struct cv_traits
  94. {
  95. typedef typename boost::function_types::detail::cv_tag_impl<
  96. ::boost::function_types::detail::cv_code<T>::value >::type
  97. tag;
  98. // may require Boost.TypeTraits broken compiler specializations
  99. // to work
  100. typedef typename boost::remove_cv<
  101. typename boost::remove_pointer<
  102. typename boost::remove_reference<T>::type
  103. >::type
  104. >::type type;
  105. };
  106. #endif
  107. } } } // namespace boost::function_types::detail
  108. #endif