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