1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
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
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H
11 #define _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H
12 
13 #include <__config>
14 #include <__functional/binary_function.h>
15 #include <__functional/unary_function.h>
16 #include <type_traits>
17 
18 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19 #  pragma GCC system_header
20 #endif
21 
22 _LIBCPP_BEGIN_NAMESPACE_STD
23 
24 template <class _Tp>
25 struct __has_result_type
26 {
27 private:
28     template <class _Up> static false_type __test(...);
29     template <class _Up> static true_type __test(typename _Up::result_type* = 0);
30 public:
31     static const bool value = decltype(__test<_Tp>(0))::value;
32 };
33 
34 // __weak_result_type
35 
36 template <class _Tp>
37 struct __derives_from_unary_function
38 {
39 private:
40     struct __two {char __lx; char __lxx;};
41     static __two __test(...);
42     template <class _Ap, class _Rp>
43         static __unary_function<_Ap, _Rp>
44         __test(const volatile __unary_function<_Ap, _Rp>*);
45 
46 public:
47     static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
48     typedef decltype(__test((_Tp*)0)) type;
49 };
50 
51 template <class _Tp>
52 struct __derives_from_binary_function
53 {
54 private:
55     struct __two {char __lx; char __lxx;};
56     static __two __test(...);
57     template <class _A1, class _A2, class _Rp>
58         static __binary_function<_A1, _A2, _Rp>
59         __test(const volatile __binary_function<_A1, _A2, _Rp>*);
60 
61 public:
62     static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
63     typedef decltype(__test((_Tp*)0)) type;
64 };
65 
66 template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
67 struct __maybe_derive_from_unary_function  // bool is true
68     : public __derives_from_unary_function<_Tp>::type
69 {
70 };
71 
72 template <class _Tp>
73 struct __maybe_derive_from_unary_function<_Tp, false>
74 {
75 };
76 
77 template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
78 struct __maybe_derive_from_binary_function  // bool is true
79     : public __derives_from_binary_function<_Tp>::type
80 {
81 };
82 
83 template <class _Tp>
84 struct __maybe_derive_from_binary_function<_Tp, false>
85 {
86 };
87 
88 template <class _Tp, bool = __has_result_type<_Tp>::value>
89 struct __weak_result_type_imp // bool is true
90     : public __maybe_derive_from_unary_function<_Tp>,
91       public __maybe_derive_from_binary_function<_Tp>
92 {
93 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
94     using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type;
95 #endif
96 };
97 
98 template <class _Tp>
99 struct __weak_result_type_imp<_Tp, false>
100     : public __maybe_derive_from_unary_function<_Tp>,
101       public __maybe_derive_from_binary_function<_Tp>
102 {
103 };
104 
105 template <class _Tp>
106 struct __weak_result_type
107     : public __weak_result_type_imp<_Tp>
108 {
109 };
110 
111 // 0 argument case
112 
113 template <class _Rp>
114 struct __weak_result_type<_Rp ()>
115 {
116 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
117     using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
118 #endif
119 };
120 
121 template <class _Rp>
122 struct __weak_result_type<_Rp (&)()>
123 {
124 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
125     using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
126 #endif
127 };
128 
129 template <class _Rp>
130 struct __weak_result_type<_Rp (*)()>
131 {
132 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
133     using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
134 #endif
135 };
136 
137 // 1 argument case
138 
139 template <class _Rp, class _A1>
140 struct __weak_result_type<_Rp (_A1)>
141     : public __unary_function<_A1, _Rp>
142 {
143 };
144 
145 template <class _Rp, class _A1>
146 struct __weak_result_type<_Rp (&)(_A1)>
147     : public __unary_function<_A1, _Rp>
148 {
149 };
150 
151 template <class _Rp, class _A1>
152 struct __weak_result_type<_Rp (*)(_A1)>
153     : public __unary_function<_A1, _Rp>
154 {
155 };
156 
157 template <class _Rp, class _Cp>
158 struct __weak_result_type<_Rp (_Cp::*)()>
159     : public __unary_function<_Cp*, _Rp>
160 {
161 };
162 
163 template <class _Rp, class _Cp>
164 struct __weak_result_type<_Rp (_Cp::*)() const>
165     : public __unary_function<const _Cp*, _Rp>
166 {
167 };
168 
169 template <class _Rp, class _Cp>
170 struct __weak_result_type<_Rp (_Cp::*)() volatile>
171     : public __unary_function<volatile _Cp*, _Rp>
172 {
173 };
174 
175 template <class _Rp, class _Cp>
176 struct __weak_result_type<_Rp (_Cp::*)() const volatile>
177     : public __unary_function<const volatile _Cp*, _Rp>
178 {
179 };
180 
181 // 2 argument case
182 
183 template <class _Rp, class _A1, class _A2>
184 struct __weak_result_type<_Rp (_A1, _A2)>
185     : public __binary_function<_A1, _A2, _Rp>
186 {
187 };
188 
189 template <class _Rp, class _A1, class _A2>
190 struct __weak_result_type<_Rp (*)(_A1, _A2)>
191     : public __binary_function<_A1, _A2, _Rp>
192 {
193 };
194 
195 template <class _Rp, class _A1, class _A2>
196 struct __weak_result_type<_Rp (&)(_A1, _A2)>
197     : public __binary_function<_A1, _A2, _Rp>
198 {
199 };
200 
201 template <class _Rp, class _Cp, class _A1>
202 struct __weak_result_type<_Rp (_Cp::*)(_A1)>
203     : public __binary_function<_Cp*, _A1, _Rp>
204 {
205 };
206 
207 template <class _Rp, class _Cp, class _A1>
208 struct __weak_result_type<_Rp (_Cp::*)(_A1) const>
209     : public __binary_function<const _Cp*, _A1, _Rp>
210 {
211 };
212 
213 template <class _Rp, class _Cp, class _A1>
214 struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
215     : public __binary_function<volatile _Cp*, _A1, _Rp>
216 {
217 };
218 
219 template <class _Rp, class _Cp, class _A1>
220 struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
221     : public __binary_function<const volatile _Cp*, _A1, _Rp>
222 {
223 };
224 
225 // 3 or more arguments
226 
227 template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
228 struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)>
229 {
230 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
231     using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
232 #endif
233 };
234 
235 template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
236 struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)>
237 {
238 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
239     using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
240 #endif
241 };
242 
243 template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
244 struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)>
245 {
246 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
247     using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
248 #endif
249 };
250 
251 template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
252 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)>
253 {
254 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
255     using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
256 #endif
257 };
258 
259 template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
260 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const>
261 {
262 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
263     using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
264 #endif
265 };
266 
267 template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
268 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile>
269 {
270 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
271     using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
272 #endif
273 };
274 
275 template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
276 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
277 {
278 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
279     using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
280 #endif
281 };
282 
283 template <class _Tp, class ..._Args>
284 struct __invoke_return
285 {
286     typedef decltype(_VSTD::__invoke(declval<_Tp>(), declval<_Args>()...)) type;
287 };
288 
289 _LIBCPP_END_NAMESPACE_STD
290 
291 #endif // _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H
292