2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
11 #define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
14 #include <__functional/weak_result_type.h>
15 #include <__memory/addressof.h>
16 #include <__utility/forward.h>
17 #include <type_traits>
19 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20 #pragma GCC system_header
23 _LIBCPP_BEGIN_NAMESPACE_STD
26 class _LIBCPP_TEMPLATE_VIS reference_wrapper
27 #if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
28 : public __weak_result_type
<_Tp
>
37 #ifndef _LIBCPP_CXX03_LANG
38 static void __fun(_Tp
&) _NOEXCEPT
;
39 static void __fun(_Tp
&&) = delete;
43 // construct/copy/destroy
44 #ifdef _LIBCPP_CXX03_LANG
45 _LIBCPP_INLINE_VISIBILITY
46 reference_wrapper(type
& __f
) _NOEXCEPT
47 : __f_(_VSTD::addressof(__f
)) {}
49 template <class _Up
, class = __enable_if_t
<!__is_same_uncvref
<_Up
, reference_wrapper
>::value
, decltype(__fun(declval
<_Up
>())) >>
50 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51 reference_wrapper(_Up
&& __u
) _NOEXCEPT_(noexcept(__fun(declval
<_Up
>()))) {
52 type
& __f
= static_cast<_Up
&&>(__u
);
53 __f_
= _VSTD::addressof(__f
);
58 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
59 operator type
&() const _NOEXCEPT
{return *__f_
;}
60 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
61 type
& get() const _NOEXCEPT
{return *__f_
;}
63 #ifndef _LIBCPP_CXX03_LANG
65 template <class... _ArgTypes
>
66 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
67 typename __invoke_of
<type
&, _ArgTypes
...>::type
68 operator() (_ArgTypes
&&... __args
) const {
69 return _VSTD::__invoke(get(), _VSTD::forward
<_ArgTypes
>(__args
)...);
73 _LIBCPP_INLINE_VISIBILITY
74 typename __invoke_return
<type
>::type
76 return _VSTD::__invoke(get());
80 _LIBCPP_INLINE_VISIBILITY
81 typename __invoke_return0
<type
, _A0
>::type
82 operator() (_A0
& __a0
) const {
83 return _VSTD::__invoke(get(), __a0
);
87 _LIBCPP_INLINE_VISIBILITY
88 typename __invoke_return0
<type
, _A0
const>::type
89 operator() (_A0
const& __a0
) const {
90 return _VSTD::__invoke(get(), __a0
);
93 template <class _A0
, class _A1
>
94 _LIBCPP_INLINE_VISIBILITY
95 typename __invoke_return1
<type
, _A0
, _A1
>::type
96 operator() (_A0
& __a0
, _A1
& __a1
) const {
97 return _VSTD::__invoke(get(), __a0
, __a1
);
100 template <class _A0
, class _A1
>
101 _LIBCPP_INLINE_VISIBILITY
102 typename __invoke_return1
<type
, _A0
const, _A1
>::type
103 operator() (_A0
const& __a0
, _A1
& __a1
) const {
104 return _VSTD::__invoke(get(), __a0
, __a1
);
107 template <class _A0
, class _A1
>
108 _LIBCPP_INLINE_VISIBILITY
109 typename __invoke_return1
<type
, _A0
, _A1
const>::type
110 operator() (_A0
& __a0
, _A1
const& __a1
) const {
111 return _VSTD::__invoke(get(), __a0
, __a1
);
114 template <class _A0
, class _A1
>
115 _LIBCPP_INLINE_VISIBILITY
116 typename __invoke_return1
<type
, _A0
const, _A1
const>::type
117 operator() (_A0
const& __a0
, _A1
const& __a1
) const {
118 return _VSTD::__invoke(get(), __a0
, __a1
);
121 template <class _A0
, class _A1
, class _A2
>
122 _LIBCPP_INLINE_VISIBILITY
123 typename __invoke_return2
<type
, _A0
, _A1
, _A2
>::type
124 operator() (_A0
& __a0
, _A1
& __a1
, _A2
& __a2
) const {
125 return _VSTD::__invoke(get(), __a0
, __a1
, __a2
);
128 template <class _A0
, class _A1
, class _A2
>
129 _LIBCPP_INLINE_VISIBILITY
130 typename __invoke_return2
<type
, _A0
const, _A1
, _A2
>::type
131 operator() (_A0
const& __a0
, _A1
& __a1
, _A2
& __a2
) const {
132 return _VSTD::__invoke(get(), __a0
, __a1
, __a2
);
135 template <class _A0
, class _A1
, class _A2
>
136 _LIBCPP_INLINE_VISIBILITY
137 typename __invoke_return2
<type
, _A0
, _A1
const, _A2
>::type
138 operator() (_A0
& __a0
, _A1
const& __a1
, _A2
& __a2
) const {
139 return _VSTD::__invoke(get(), __a0
, __a1
, __a2
);
142 template <class _A0
, class _A1
, class _A2
>
143 _LIBCPP_INLINE_VISIBILITY
144 typename __invoke_return2
<type
, _A0
, _A1
, _A2
const>::type
145 operator() (_A0
& __a0
, _A1
& __a1
, _A2
const& __a2
) const {
146 return _VSTD::__invoke(get(), __a0
, __a1
, __a2
);
149 template <class _A0
, class _A1
, class _A2
>
150 _LIBCPP_INLINE_VISIBILITY
151 typename __invoke_return2
<type
, _A0
const, _A1
const, _A2
>::type
152 operator() (_A0
const& __a0
, _A1
const& __a1
, _A2
& __a2
) const {
153 return _VSTD::__invoke(get(), __a0
, __a1
, __a2
);
156 template <class _A0
, class _A1
, class _A2
>
157 _LIBCPP_INLINE_VISIBILITY
158 typename __invoke_return2
<type
, _A0
const, _A1
, _A2
const>::type
159 operator() (_A0
const& __a0
, _A1
& __a1
, _A2
const& __a2
) const {
160 return _VSTD::__invoke(get(), __a0
, __a1
, __a2
);
163 template <class _A0
, class _A1
, class _A2
>
164 _LIBCPP_INLINE_VISIBILITY
165 typename __invoke_return2
<type
, _A0
, _A1
const, _A2
const>::type
166 operator() (_A0
& __a0
, _A1
const& __a1
, _A2
const& __a2
) const {
167 return _VSTD::__invoke(get(), __a0
, __a1
, __a2
);
170 template <class _A0
, class _A1
, class _A2
>
171 _LIBCPP_INLINE_VISIBILITY
172 typename __invoke_return2
<type
, _A0
const, _A1
const, _A2
const>::type
173 operator() (_A0
const& __a0
, _A1
const& __a1
, _A2
const& __a2
) const {
174 return _VSTD::__invoke(get(), __a0
, __a1
, __a2
);
176 #endif // _LIBCPP_CXX03_LANG
179 #if _LIBCPP_STD_VER >= 17
181 reference_wrapper(_Tp
&) -> reference_wrapper
<_Tp
>;
185 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
186 reference_wrapper
<_Tp
>
187 ref(_Tp
& __t
) _NOEXCEPT
189 return reference_wrapper
<_Tp
>(__t
);
193 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
194 reference_wrapper
<_Tp
>
195 ref(reference_wrapper
<_Tp
> __t
) _NOEXCEPT
197 return _VSTD::ref(__t
.get());
201 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
202 reference_wrapper
<const _Tp
>
203 cref(const _Tp
& __t
) _NOEXCEPT
205 return reference_wrapper
<const _Tp
>(__t
);
209 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
210 reference_wrapper
<const _Tp
>
211 cref(reference_wrapper
<_Tp
> __t
) _NOEXCEPT
213 return _VSTD::cref(__t
.get());
216 #ifndef _LIBCPP_CXX03_LANG
217 template <class _Tp
> void ref(const _Tp
&&) = delete;
218 template <class _Tp
> void cref(const _Tp
&&) = delete;
221 _LIBCPP_END_NAMESPACE_STD
223 #endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H