unwrap_cv_reference.hpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright Daniel Wallin, David Abrahams 2005.
  2. // Copyright Cromwell D. Enage 2017.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef UNWRAP_CV_REFERENCE_050328_HPP
  7. #define UNWRAP_CV_REFERENCE_050328_HPP
  8. namespace boost {
  9. template <typename T>
  10. class reference_wrapper;
  11. } // namespace boost
  12. #include <boost/parameter/aux_/yesno.hpp>
  13. namespace boost { namespace parameter { namespace aux {
  14. //
  15. // reference_wrapper support -- if perfect forwarding is unsupported,
  16. // then when passing arguments positionally by non-const reference,
  17. // we ask users of named parameter interfaces to use ref(x) to wrap them.
  18. //
  19. template <typename U>
  20. ::boost::parameter::aux::yes_tag
  21. is_cv_reference_wrapper_check(
  22. ::boost::reference_wrapper<U> const volatile*
  23. );
  24. ::boost::parameter::aux::no_tag is_cv_reference_wrapper_check(...);
  25. }}} // namespace boost::parameter::aux
  26. #include <boost/parameter/config.hpp>
  27. #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
  28. #include <functional>
  29. namespace boost { namespace parameter { namespace aux {
  30. // Support for std::ref(x) -- Cromwell D. Enage
  31. template <typename U>
  32. ::boost::parameter::aux::yes_tag
  33. is_cv_reference_wrapper_check(
  34. ::std::reference_wrapper<U> const volatile*
  35. );
  36. }}} // namespace boost::parameter::aux
  37. #endif
  38. #include <boost/parameter/aux_/preprocessor/nullptr.hpp>
  39. #if defined(BOOST_PARAMETER_CAN_USE_MP11) && !( \
  40. BOOST_WORKAROUND(BOOST_MSVC, >= 1900) && \
  41. BOOST_WORKAROUND(BOOST_MSVC, < 1910) \
  42. )
  43. #include <boost/mp11/integral.hpp>
  44. #include <boost/mp11/utility.hpp>
  45. #include <type_traits>
  46. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) || MSVC-14.0
  47. #include <boost/mpl/bool.hpp>
  48. #include <boost/type_traits/remove_reference.hpp>
  49. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
  50. !BOOST_WORKAROUND(BOOST_GCC, < 40000)
  51. #include <boost/mpl/eval_if.hpp>
  52. #endif
  53. #endif // BOOST_PARAMETER_CAN_USE_MP11 && not MSVC-14.0
  54. namespace boost { namespace parameter { namespace aux {
  55. #if defined(BOOST_PARAMETER_CAN_USE_MP11) && !( \
  56. BOOST_WORKAROUND(BOOST_MSVC, >= 1900) && \
  57. BOOST_WORKAROUND(BOOST_MSVC, < 1910) \
  58. )
  59. // This metafunction returns mp11::mp_true if T is of type
  60. // reference_wrapper<U> cv.
  61. template <typename T>
  62. using is_cv_reference_wrapper = ::boost::mp11::mp_bool<
  63. sizeof(
  64. ::boost::parameter::aux::is_cv_reference_wrapper_check(
  65. static_cast<
  66. typename ::std::remove_reference<T>::type*
  67. >(BOOST_PARAMETER_AUX_PP_NULLPTR)
  68. )
  69. ) == sizeof(::boost::parameter::aux::yes_tag)
  70. >;
  71. // Needed for unwrap_cv_reference below. T might be const, so
  72. // mp_eval_if<> might fail because of deriving from T const on EDG.
  73. template <typename T>
  74. using unwrap_cv_reference_impl = typename ::std::remove_reference<T>::type;
  75. // Produces the unwrapped type to hold a reference to in
  76. // tagged_argument<>. Can't use boost::unwrap_reference<> here
  77. // because it doesn't handle the case where T = reference_wrapper<U> cv.
  78. template <typename T>
  79. using unwrap_cv_reference = ::boost::mp11::mp_eval_if<
  80. ::boost::parameter::aux::is_cv_reference_wrapper<T>
  81. , ::boost::parameter::aux::unwrap_cv_reference_impl<T>
  82. , ::std::remove_reference
  83. , T
  84. >;
  85. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) || MSVC-14.0
  86. // This metafunction returns mpl::true_ if T is of type
  87. // reference_wrapper<U> cv.
  88. template <typename T>
  89. struct is_cv_reference_wrapper
  90. {
  91. BOOST_STATIC_CONSTANT(
  92. bool, value = (
  93. sizeof(
  94. ::boost::parameter::aux::is_cv_reference_wrapper_check(
  95. static_cast<
  96. typename ::boost::remove_reference<T>::type*
  97. >(BOOST_PARAMETER_AUX_PP_NULLPTR)
  98. )
  99. ) == sizeof(::boost::parameter::aux::yes_tag)
  100. )
  101. );
  102. typedef boost::mpl::bool_<
  103. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  104. is_cv_reference_wrapper::
  105. #endif
  106. value> type;
  107. };
  108. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) || \
  109. BOOST_WORKAROUND(BOOST_GCC, < 40000)
  110. template <
  111. typename T
  112. , typename = typename ::boost::parameter::aux
  113. ::is_cv_reference_wrapper<T>::type
  114. >
  115. struct unwrap_cv_reference : ::boost::remove_reference<T>
  116. {
  117. };
  118. template <typename T>
  119. struct unwrap_cv_reference<T const,::boost::mpl::false_>
  120. {
  121. typedef T const type;
  122. };
  123. template <typename T>
  124. struct unwrap_cv_reference<T,::boost::mpl::true_> : T
  125. {
  126. };
  127. #else // no Borland or GCC 3- workarounds needed
  128. // Needed for unwrap_cv_reference below. T might be const, so
  129. // eval_if<> might fail because of deriving from T const on EDG.
  130. template <typename T>
  131. struct unwrap_cv_reference_impl : ::boost::remove_reference<T>::type
  132. {
  133. };
  134. // Produces the unwrapped type to hold a reference to in
  135. // tagged_argument<>. Can't use boost::unwrap_reference<> here
  136. // because it doesn't handle the case where T = reference_wrapper<U> cv.
  137. template <typename T>
  138. struct unwrap_cv_reference
  139. : ::boost::mpl::eval_if<
  140. ::boost::parameter::aux::is_cv_reference_wrapper<T>
  141. , ::boost::parameter::aux::unwrap_cv_reference_impl<T>
  142. , ::boost::remove_reference<T>
  143. >
  144. {
  145. };
  146. #endif // Borland or GCC 3- workarounds needed
  147. #endif // BOOST_PARAMETER_CAN_USE_MP11 && not MSVC-14.0
  148. }}} // namespace boost::parameter::aux
  149. #endif // include guard