1 // Implementation of std::reference_wrapper -*- C++ -*-
3 // Copyright (C) 2004-2018 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file include/bits/refwrap.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{functional}
30 #ifndef _GLIBCXX_REFWRAP_H
31 #define _GLIBCXX_REFWRAP_H 1
33 #pragma GCC system_header
35 #if __cplusplus < 201103L
36 # include <bits/c++0x_warning.h>
39 #include <bits/move.h>
40 #include <bits/invoke.h>
41 #include <bits/stl_function.h> // for unary_function and binary_function
43 namespace std
_GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
48 * Derives from @c unary_function or @c binary_function, or perhaps
49 * nothing, depending on the number of arguments provided. The
50 * primary template is the basis case, which derives nothing.
52 template<typename _Res
, typename
... _ArgTypes
>
53 struct _Maybe_unary_or_binary_function
{ };
55 /// Derives from @c unary_function, as appropriate.
56 template<typename _Res
, typename _T1
>
57 struct _Maybe_unary_or_binary_function
<_Res
, _T1
>
58 : std::unary_function
<_T1
, _Res
> { };
60 /// Derives from @c binary_function, as appropriate.
61 template<typename _Res
, typename _T1
, typename _T2
>
62 struct _Maybe_unary_or_binary_function
<_Res
, _T1
, _T2
>
63 : std::binary_function
<_T1
, _T2
, _Res
> { };
65 template<typename _Signature
>
66 struct _Mem_fn_traits
;
68 template<typename _Res
, typename _Class
, typename
... _ArgTypes
>
69 struct _Mem_fn_traits_base
71 using __result_type
= _Res
;
73 = _Maybe_unary_or_binary_function
<_Res
, _Class
*, _ArgTypes
...>;
74 using __arity
= integral_constant
<size_t, sizeof...(_ArgTypes
)>;
77 #define _GLIBCXX_MEM_FN_TRAITS2(_CV, _REF, _LVAL, _RVAL) \
78 template<typename _Res, typename _Class, typename... _ArgTypes> \
79 struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) _CV _REF> \
80 : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \
82 using __vararg = false_type; \
84 template<typename _Res, typename _Class, typename... _ArgTypes> \
85 struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes... ...) _CV _REF> \
86 : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \
88 using __vararg = true_type; \
91 #define _GLIBCXX_MEM_FN_TRAITS(_REF, _LVAL, _RVAL) \
92 _GLIBCXX_MEM_FN_TRAITS2( , _REF, _LVAL, _RVAL) \
93 _GLIBCXX_MEM_FN_TRAITS2(const , _REF, _LVAL, _RVAL) \
94 _GLIBCXX_MEM_FN_TRAITS2(volatile , _REF, _LVAL, _RVAL) \
95 _GLIBCXX_MEM_FN_TRAITS2(const volatile, _REF, _LVAL, _RVAL)
97 _GLIBCXX_MEM_FN_TRAITS( , true_type
, true_type
)
98 _GLIBCXX_MEM_FN_TRAITS(&, true_type
, false_type
)
99 _GLIBCXX_MEM_FN_TRAITS(&&, false_type
, true_type
)
101 #if __cplusplus > 201402L
102 _GLIBCXX_MEM_FN_TRAITS(noexcept
, true_type
, true_type
)
103 _GLIBCXX_MEM_FN_TRAITS(& noexcept
, true_type
, false_type
)
104 _GLIBCXX_MEM_FN_TRAITS(&& noexcept
, false_type
, true_type
)
107 #undef _GLIBCXX_MEM_FN_TRAITS
108 #undef _GLIBCXX_MEM_FN_TRAITS2
110 /// If we have found a result_type, extract it.
111 template<typename _Functor
, typename
= __void_t
<>>
112 struct _Maybe_get_result_type
115 template<typename _Functor
>
116 struct _Maybe_get_result_type
<_Functor
,
117 __void_t
<typename
_Functor::result_type
>>
118 { typedef typename
_Functor::result_type result_type
; };
121 * Base class for any function object that has a weak result type, as
122 * defined in 20.8.2 [func.require] of C++11.
124 template<typename _Functor
>
125 struct _Weak_result_type_impl
126 : _Maybe_get_result_type
<_Functor
>
129 /// Retrieve the result type for a function type.
130 template<typename _Res
, typename
... _ArgTypes _GLIBCXX_NOEXCEPT_PARM
>
131 struct _Weak_result_type_impl
<_Res(_ArgTypes
...) _GLIBCXX_NOEXCEPT_QUAL
>
132 { typedef _Res result_type
; };
134 /// Retrieve the result type for a varargs function type.
135 template<typename _Res
, typename
... _ArgTypes _GLIBCXX_NOEXCEPT_PARM
>
136 struct _Weak_result_type_impl
<_Res(_ArgTypes
......) _GLIBCXX_NOEXCEPT_QUAL
>
137 { typedef _Res result_type
; };
139 /// Retrieve the result type for a function pointer.
140 template<typename _Res
, typename
... _ArgTypes _GLIBCXX_NOEXCEPT_PARM
>
141 struct _Weak_result_type_impl
<_Res(*)(_ArgTypes
...) _GLIBCXX_NOEXCEPT_QUAL
>
142 { typedef _Res result_type
; };
144 /// Retrieve the result type for a varargs function pointer.
145 template<typename _Res
, typename
... _ArgTypes _GLIBCXX_NOEXCEPT_PARM
>
147 _Weak_result_type_impl
<_Res(*)(_ArgTypes
......) _GLIBCXX_NOEXCEPT_QUAL
>
148 { typedef _Res result_type
; };
150 // Let _Weak_result_type_impl perform the real work.
151 template<typename _Functor
,
152 bool = is_member_function_pointer
<_Functor
>::value
>
153 struct _Weak_result_type_memfun
154 : _Weak_result_type_impl
<_Functor
>
157 // A pointer to member function has a weak result type.
158 template<typename _MemFunPtr
>
159 struct _Weak_result_type_memfun
<_MemFunPtr
, true>
161 using result_type
= typename _Mem_fn_traits
<_MemFunPtr
>::__result_type
;
164 // A pointer to data member doesn't have a weak result type.
165 template<typename _Func
, typename _Class
>
166 struct _Weak_result_type_memfun
<_Func
_Class::*, false>
170 * Strip top-level cv-qualifiers from the function object and let
171 * _Weak_result_type_memfun perform the real work.
173 template<typename _Functor
>
174 struct _Weak_result_type
175 : _Weak_result_type_memfun
<typename remove_cv
<_Functor
>::type
>
178 // Detect nested argument_type.
179 template<typename _Tp
, typename
= __void_t
<>>
180 struct _Refwrap_base_arg1
183 // Nested argument_type.
184 template<typename _Tp
>
185 struct _Refwrap_base_arg1
<_Tp
,
186 __void_t
<typename
_Tp::argument_type
>>
188 typedef typename
_Tp::argument_type argument_type
;
191 // Detect nested first_argument_type and second_argument_type.
192 template<typename _Tp
, typename
= __void_t
<>>
193 struct _Refwrap_base_arg2
196 // Nested first_argument_type and second_argument_type.
197 template<typename _Tp
>
198 struct _Refwrap_base_arg2
<_Tp
,
199 __void_t
<typename
_Tp::first_argument_type
,
200 typename
_Tp::second_argument_type
>>
202 typedef typename
_Tp::first_argument_type first_argument_type
;
203 typedef typename
_Tp::second_argument_type second_argument_type
;
207 * Derives from unary_function or binary_function when it
208 * can. Specializations handle all of the easy cases. The primary
209 * template determines what to do with a class type, which may
210 * derive from both unary_function and binary_function.
212 template<typename _Tp
>
213 struct _Reference_wrapper_base
214 : _Weak_result_type
<_Tp
>, _Refwrap_base_arg1
<_Tp
>, _Refwrap_base_arg2
<_Tp
>
217 // - a function type (unary)
218 template<typename _Res
, typename _T1 _GLIBCXX_NOEXCEPT_PARM
>
219 struct _Reference_wrapper_base
<_Res(_T1
) _GLIBCXX_NOEXCEPT_QUAL
>
220 : unary_function
<_T1
, _Res
>
223 template<typename _Res
, typename _T1
>
224 struct _Reference_wrapper_base
<_Res(_T1
) const>
225 : unary_function
<_T1
, _Res
>
228 template<typename _Res
, typename _T1
>
229 struct _Reference_wrapper_base
<_Res(_T1
) volatile>
230 : unary_function
<_T1
, _Res
>
233 template<typename _Res
, typename _T1
>
234 struct _Reference_wrapper_base
<_Res(_T1
) const volatile>
235 : unary_function
<_T1
, _Res
>
238 // - a function type (binary)
239 template<typename _Res
, typename _T1
, typename _T2 _GLIBCXX_NOEXCEPT_PARM
>
240 struct _Reference_wrapper_base
<_Res(_T1
, _T2
) _GLIBCXX_NOEXCEPT_QUAL
>
241 : binary_function
<_T1
, _T2
, _Res
>
244 template<typename _Res
, typename _T1
, typename _T2
>
245 struct _Reference_wrapper_base
<_Res(_T1
, _T2
) const>
246 : binary_function
<_T1
, _T2
, _Res
>
249 template<typename _Res
, typename _T1
, typename _T2
>
250 struct _Reference_wrapper_base
<_Res(_T1
, _T2
) volatile>
251 : binary_function
<_T1
, _T2
, _Res
>
254 template<typename _Res
, typename _T1
, typename _T2
>
255 struct _Reference_wrapper_base
<_Res(_T1
, _T2
) const volatile>
256 : binary_function
<_T1
, _T2
, _Res
>
259 // - a function pointer type (unary)
260 template<typename _Res
, typename _T1 _GLIBCXX_NOEXCEPT_PARM
>
261 struct _Reference_wrapper_base
<_Res(*)(_T1
) _GLIBCXX_NOEXCEPT_QUAL
>
262 : unary_function
<_T1
, _Res
>
265 // - a function pointer type (binary)
266 template<typename _Res
, typename _T1
, typename _T2 _GLIBCXX_NOEXCEPT_PARM
>
267 struct _Reference_wrapper_base
<_Res(*)(_T1
, _T2
) _GLIBCXX_NOEXCEPT_QUAL
>
268 : binary_function
<_T1
, _T2
, _Res
>
271 template<typename _Tp
, bool = is_member_function_pointer
<_Tp
>::value
>
272 struct _Reference_wrapper_base_memfun
273 : _Reference_wrapper_base
<_Tp
>
276 template<typename _MemFunPtr
>
277 struct _Reference_wrapper_base_memfun
<_MemFunPtr
, true>
278 : _Mem_fn_traits
<_MemFunPtr
>::__maybe_type
280 using result_type
= typename _Mem_fn_traits
<_MemFunPtr
>::__result_type
;
284 * @brief Primary class template for reference_wrapper.
288 template<typename _Tp
>
289 class reference_wrapper
290 : public _Reference_wrapper_base_memfun
<typename remove_cv
<_Tp
>::type
>
297 reference_wrapper(_Tp
& __indata
) noexcept
298 : _M_data(std::__addressof(__indata
))
301 reference_wrapper(_Tp
&&) = delete;
303 reference_wrapper(const reference_wrapper
&) = default;
306 operator=(const reference_wrapper
&) = default;
308 operator _Tp
&() const noexcept
309 { return this->get(); }
315 template<typename
... _Args
>
316 typename result_of
<_Tp
&(_Args
&&...)>::type
317 operator()(_Args
&&... __args
) const
319 return std::__invoke(get(), std::forward
<_Args
>(__args
)...);
324 /// Denotes a reference should be taken to a variable.
325 template<typename _Tp
>
326 inline reference_wrapper
<_Tp
>
327 ref(_Tp
& __t
) noexcept
328 { return reference_wrapper
<_Tp
>(__t
); }
330 /// Denotes a const reference should be taken to a variable.
331 template<typename _Tp
>
332 inline reference_wrapper
<const _Tp
>
333 cref(const _Tp
& __t
) noexcept
334 { return reference_wrapper
<const _Tp
>(__t
); }
336 template<typename _Tp
>
337 void ref(const _Tp
&&) = delete;
339 template<typename _Tp
>
340 void cref(const _Tp
&&) = delete;
342 /// std::ref overload to prevent wrapping a reference_wrapper
343 template<typename _Tp
>
344 inline reference_wrapper
<_Tp
>
345 ref(reference_wrapper
<_Tp
> __t
) noexcept
348 /// std::cref overload to prevent wrapping a reference_wrapper
349 template<typename _Tp
>
350 inline reference_wrapper
<const _Tp
>
351 cref(reference_wrapper
<_Tp
> __t
) noexcept
352 { return { __t
.get() }; }
356 _GLIBCXX_END_NAMESPACE_VERSION
361 #endif // _GLIBCXX_REFWRAP_H