unwrap_cv_reference.hpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and
  2. // distribution is subject to the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef UNWRAP_CV_REFERENCE_050328_HPP
  6. #define UNWRAP_CV_REFERENCE_050328_HPP
  7. #include <boost/parameter/aux_/yesno.hpp>
  8. #include <boost/mpl/bool.hpp>
  9. #include <boost/mpl/identity.hpp>
  10. #include <boost/mpl/eval_if.hpp>
  11. namespace boost { template<class T> class reference_wrapper; }
  12. namespace boost { namespace parameter { namespace aux {
  13. //
  14. // reference_wrapper support -- because of the forwarding problem,
  15. // when passing arguments positionally by non-const reference, we
  16. // ask users of named parameter interfaces to use ref(x) to wrap
  17. // them.
  18. //
  19. // is_cv_reference_wrapper returns mpl::true_ if T is of type
  20. // reference_wrapper<U> cv
  21. template <class U>
  22. yes_tag is_cv_reference_wrapper_check(reference_wrapper<U> const volatile*);
  23. no_tag is_cv_reference_wrapper_check(...);
  24. template <class T>
  25. struct is_cv_reference_wrapper
  26. {
  27. BOOST_STATIC_CONSTANT(
  28. bool, value = (
  29. sizeof(is_cv_reference_wrapper_check((T*)0)) == sizeof(yes_tag)
  30. )
  31. );
  32. typedef mpl::bool_<
  33. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  34. is_cv_reference_wrapper::
  35. #endif
  36. value> type;
  37. };
  38. #if BOOST_WORKAROUND(MSVC, == 1200)
  39. template <>
  40. struct is_cv_reference_wrapper<int>
  41. : mpl::false_ {};
  42. #endif
  43. // Needed for unwrap_cv_reference below. T might be const, so
  44. // eval_if might fail because of deriving from T const on EDG.
  45. template <class T>
  46. struct get_type
  47. {
  48. typedef typename T::type type;
  49. };
  50. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  51. template <class T, class is_reference_wrapper = typename is_cv_reference_wrapper<T>::type>
  52. struct unwrap_cv_reference
  53. {
  54. typedef T type;
  55. };
  56. template <class T>
  57. struct unwrap_cv_reference<T const, mpl::false_>
  58. {
  59. typedef T const type;
  60. };
  61. template <class T>
  62. struct unwrap_cv_reference<T, mpl::true_>
  63. : T
  64. {};
  65. #else
  66. // Produces the unwrapped type to hold a reference to in named<>
  67. // Can't use boost::unwrap_reference<> here because it
  68. // doesn't handle the case where T = reference_wrapper<U> cv
  69. template <class T>
  70. struct unwrap_cv_reference
  71. {
  72. typedef typename mpl::eval_if<
  73. is_cv_reference_wrapper<T>
  74. , get_type<T>
  75. , mpl::identity<T>
  76. >::type type;
  77. };
  78. #endif
  79. }}} // namespace boost::parameter::aux
  80. #endif // UNWRAP_CV_REFERENCE_050328_HPP