unwrap_cv_reference.hpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. // Needed for unwrap_cv_reference below. T might be const, so
  39. // eval_if might fail because of deriving from T const on EDG.
  40. template <class T>
  41. struct get_type
  42. {
  43. typedef typename T::type type;
  44. };
  45. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  46. template <class T, class is_reference_wrapper = typename is_cv_reference_wrapper<T>::type>
  47. struct unwrap_cv_reference
  48. {
  49. typedef T type;
  50. };
  51. template <class T>
  52. struct unwrap_cv_reference<T const, mpl::false_>
  53. {
  54. typedef T const type;
  55. };
  56. template <class T>
  57. struct unwrap_cv_reference<T, mpl::true_>
  58. : T
  59. {};
  60. #else
  61. // Produces the unwrapped type to hold a reference to in named<>
  62. // Can't use boost::unwrap_reference<> here because it
  63. // doesn't handle the case where T = reference_wrapper<U> cv
  64. template <class T>
  65. struct unwrap_cv_reference
  66. {
  67. typedef typename mpl::eval_if<
  68. is_cv_reference_wrapper<T>
  69. , get_type<T>
  70. , mpl::identity<T>
  71. >::type type;
  72. };
  73. #endif
  74. }}} // namespace boost::parameter::aux
  75. #endif // UNWRAP_CV_REFERENCE_050328_HPP