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

source code of include/boost/parameter/aux_/unwrap_cv_reference.hpp