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_BASE |
11 | #define _LIBCPP_FUNCTIONAL_BASE |
12 | |
13 | #include <__config> |
14 | #include <type_traits> |
15 | #include <typeinfo> |
16 | #include <exception> |
17 | #include <new> |
18 | #include <utility> |
19 | |
20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
21 | #pragma GCC system_header |
22 | #endif |
23 | |
24 | _LIBCPP_BEGIN_NAMESPACE_STD |
25 | |
26 | template <class _Arg1, class _Arg2, class _Result> |
27 | struct _LIBCPP_TEMPLATE_VIS binary_function |
28 | { |
29 | typedef _Arg1 first_argument_type; |
30 | typedef _Arg2 second_argument_type; |
31 | typedef _Result result_type; |
32 | }; |
33 | |
34 | template <class _Tp> |
35 | struct __has_result_type |
36 | { |
37 | private: |
38 | struct __two {char __lx; char __lxx;}; |
39 | template <class _Up> static __two __test(...); |
40 | template <class _Up> static char __test(typename _Up::result_type* = 0); |
41 | public: |
42 | static const bool value = sizeof(__test<_Tp>(0)) == 1; |
43 | }; |
44 | |
45 | #if _LIBCPP_STD_VER > 11 |
46 | template <class _Tp = void> |
47 | #else |
48 | template <class _Tp> |
49 | #endif |
50 | struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool> |
51 | { |
52 | _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY |
53 | bool operator()(const _Tp& __x, const _Tp& __y) const |
54 | {return __x < __y;} |
55 | }; |
56 | |
57 | #if _LIBCPP_STD_VER > 11 |
58 | template <> |
59 | struct _LIBCPP_TEMPLATE_VIS less<void> |
60 | { |
61 | template <class _T1, class _T2> |
62 | _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY |
63 | auto operator()(_T1&& __t, _T2&& __u) const |
64 | _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))) |
65 | -> decltype (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)) |
66 | { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); } |
67 | typedef void is_transparent; |
68 | }; |
69 | #endif |
70 | |
71 | // __weak_result_type |
72 | |
73 | template <class _Tp> |
74 | struct __derives_from_unary_function |
75 | { |
76 | private: |
77 | struct __two {char __lx; char __lxx;}; |
78 | static __two __test(...); |
79 | template <class _Ap, class _Rp> |
80 | static unary_function<_Ap, _Rp> |
81 | __test(const volatile unary_function<_Ap, _Rp>*); |
82 | public: |
83 | static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; |
84 | typedef decltype(__test((_Tp*)0)) type; |
85 | }; |
86 | |
87 | template <class _Tp> |
88 | struct __derives_from_binary_function |
89 | { |
90 | private: |
91 | struct __two {char __lx; char __lxx;}; |
92 | static __two __test(...); |
93 | template <class _A1, class _A2, class _Rp> |
94 | static binary_function<_A1, _A2, _Rp> |
95 | __test(const volatile binary_function<_A1, _A2, _Rp>*); |
96 | public: |
97 | static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; |
98 | typedef decltype(__test((_Tp*)0)) type; |
99 | }; |
100 | |
101 | template <class _Tp, bool = __derives_from_unary_function<_Tp>::value> |
102 | struct __maybe_derive_from_unary_function // bool is true |
103 | : public __derives_from_unary_function<_Tp>::type |
104 | { |
105 | }; |
106 | |
107 | template <class _Tp> |
108 | struct __maybe_derive_from_unary_function<_Tp, false> |
109 | { |
110 | }; |
111 | |
112 | template <class _Tp, bool = __derives_from_binary_function<_Tp>::value> |
113 | struct __maybe_derive_from_binary_function // bool is true |
114 | : public __derives_from_binary_function<_Tp>::type |
115 | { |
116 | }; |
117 | |
118 | template <class _Tp> |
119 | struct __maybe_derive_from_binary_function<_Tp, false> |
120 | { |
121 | }; |
122 | |
123 | template <class _Tp, bool = __has_result_type<_Tp>::value> |
124 | struct __weak_result_type_imp // bool is true |
125 | : public __maybe_derive_from_unary_function<_Tp>, |
126 | public __maybe_derive_from_binary_function<_Tp> |
127 | { |
128 | typedef _LIBCPP_NODEBUG_TYPE typename _Tp::result_type result_type; |
129 | }; |
130 | |
131 | template <class _Tp> |
132 | struct __weak_result_type_imp<_Tp, false> |
133 | : public __maybe_derive_from_unary_function<_Tp>, |
134 | public __maybe_derive_from_binary_function<_Tp> |
135 | { |
136 | }; |
137 | |
138 | template <class _Tp> |
139 | struct __weak_result_type |
140 | : public __weak_result_type_imp<_Tp> |
141 | { |
142 | }; |
143 | |
144 | // 0 argument case |
145 | |
146 | template <class _Rp> |
147 | struct __weak_result_type<_Rp ()> |
148 | { |
149 | typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; |
150 | }; |
151 | |
152 | template <class _Rp> |
153 | struct __weak_result_type<_Rp (&)()> |
154 | { |
155 | typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; |
156 | }; |
157 | |
158 | template <class _Rp> |
159 | struct __weak_result_type<_Rp (*)()> |
160 | { |
161 | typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; |
162 | }; |
163 | |
164 | // 1 argument case |
165 | |
166 | template <class _Rp, class _A1> |
167 | struct __weak_result_type<_Rp (_A1)> |
168 | : public unary_function<_A1, _Rp> |
169 | { |
170 | }; |
171 | |
172 | template <class _Rp, class _A1> |
173 | struct __weak_result_type<_Rp (&)(_A1)> |
174 | : public unary_function<_A1, _Rp> |
175 | { |
176 | }; |
177 | |
178 | template <class _Rp, class _A1> |
179 | struct __weak_result_type<_Rp (*)(_A1)> |
180 | : public unary_function<_A1, _Rp> |
181 | { |
182 | }; |
183 | |
184 | template <class _Rp, class _Cp> |
185 | struct __weak_result_type<_Rp (_Cp::*)()> |
186 | : public unary_function<_Cp*, _Rp> |
187 | { |
188 | }; |
189 | |
190 | template <class _Rp, class _Cp> |
191 | struct __weak_result_type<_Rp (_Cp::*)() const> |
192 | : public unary_function<const _Cp*, _Rp> |
193 | { |
194 | }; |
195 | |
196 | template <class _Rp, class _Cp> |
197 | struct __weak_result_type<_Rp (_Cp::*)() volatile> |
198 | : public unary_function<volatile _Cp*, _Rp> |
199 | { |
200 | }; |
201 | |
202 | template <class _Rp, class _Cp> |
203 | struct __weak_result_type<_Rp (_Cp::*)() const volatile> |
204 | : public unary_function<const volatile _Cp*, _Rp> |
205 | { |
206 | }; |
207 | |
208 | // 2 argument case |
209 | |
210 | template <class _Rp, class _A1, class _A2> |
211 | struct __weak_result_type<_Rp (_A1, _A2)> |
212 | : public binary_function<_A1, _A2, _Rp> |
213 | { |
214 | }; |
215 | |
216 | template <class _Rp, class _A1, class _A2> |
217 | struct __weak_result_type<_Rp (*)(_A1, _A2)> |
218 | : public binary_function<_A1, _A2, _Rp> |
219 | { |
220 | }; |
221 | |
222 | template <class _Rp, class _A1, class _A2> |
223 | struct __weak_result_type<_Rp (&)(_A1, _A2)> |
224 | : public binary_function<_A1, _A2, _Rp> |
225 | { |
226 | }; |
227 | |
228 | template <class _Rp, class _Cp, class _A1> |
229 | struct __weak_result_type<_Rp (_Cp::*)(_A1)> |
230 | : public binary_function<_Cp*, _A1, _Rp> |
231 | { |
232 | }; |
233 | |
234 | template <class _Rp, class _Cp, class _A1> |
235 | struct __weak_result_type<_Rp (_Cp::*)(_A1) const> |
236 | : public binary_function<const _Cp*, _A1, _Rp> |
237 | { |
238 | }; |
239 | |
240 | template <class _Rp, class _Cp, class _A1> |
241 | struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> |
242 | : public binary_function<volatile _Cp*, _A1, _Rp> |
243 | { |
244 | }; |
245 | |
246 | template <class _Rp, class _Cp, class _A1> |
247 | struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> |
248 | : public binary_function<const volatile _Cp*, _A1, _Rp> |
249 | { |
250 | }; |
251 | |
252 | |
253 | #ifndef _LIBCPP_CXX03_LANG |
254 | // 3 or more arguments |
255 | |
256 | template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> |
257 | struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> |
258 | { |
259 | typedef _Rp result_type; |
260 | }; |
261 | |
262 | template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> |
263 | struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> |
264 | { |
265 | typedef _Rp result_type; |
266 | }; |
267 | |
268 | template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> |
269 | struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> |
270 | { |
271 | typedef _Rp result_type; |
272 | }; |
273 | |
274 | template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> |
275 | struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> |
276 | { |
277 | typedef _Rp result_type; |
278 | }; |
279 | |
280 | template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> |
281 | struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> |
282 | { |
283 | typedef _Rp result_type; |
284 | }; |
285 | |
286 | template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> |
287 | struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> |
288 | { |
289 | typedef _Rp result_type; |
290 | }; |
291 | |
292 | template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> |
293 | struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> |
294 | { |
295 | typedef _Rp result_type; |
296 | }; |
297 | |
298 | template <class _Tp, class ..._Args> |
299 | struct __invoke_return |
300 | { |
301 | typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type; |
302 | }; |
303 | |
304 | #else // defined(_LIBCPP_CXX03_LANG) |
305 | |
306 | #include <__functional_base_03> |
307 | |
308 | #endif // !defined(_LIBCPP_CXX03_LANG) |
309 | |
310 | |
311 | template <class _Ret> |
312 | struct __invoke_void_return_wrapper |
313 | { |
314 | #ifndef _LIBCPP_CXX03_LANG |
315 | template <class ..._Args> |
316 | static _Ret __call(_Args&&... __args) { |
317 | return __invoke(_VSTD::forward<_Args>(__args)...); |
318 | } |
319 | #else |
320 | template <class _Fn> |
321 | static _Ret __call(_Fn __f) { |
322 | return __invoke(__f); |
323 | } |
324 | |
325 | template <class _Fn, class _A0> |
326 | static _Ret __call(_Fn __f, _A0& __a0) { |
327 | return __invoke(__f, __a0); |
328 | } |
329 | |
330 | template <class _Fn, class _A0, class _A1> |
331 | static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) { |
332 | return __invoke(__f, __a0, __a1); |
333 | } |
334 | |
335 | template <class _Fn, class _A0, class _A1, class _A2> |
336 | static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){ |
337 | return __invoke(__f, __a0, __a1, __a2); |
338 | } |
339 | #endif |
340 | }; |
341 | |
342 | template <> |
343 | struct __invoke_void_return_wrapper<void> |
344 | { |
345 | #ifndef _LIBCPP_CXX03_LANG |
346 | template <class ..._Args> |
347 | static void __call(_Args&&... __args) { |
348 | __invoke(_VSTD::forward<_Args>(__args)...); |
349 | } |
350 | #else |
351 | template <class _Fn> |
352 | static void __call(_Fn __f) { |
353 | __invoke(__f); |
354 | } |
355 | |
356 | template <class _Fn, class _A0> |
357 | static void __call(_Fn __f, _A0& __a0) { |
358 | __invoke(__f, __a0); |
359 | } |
360 | |
361 | template <class _Fn, class _A0, class _A1> |
362 | static void __call(_Fn __f, _A0& __a0, _A1& __a1) { |
363 | __invoke(__f, __a0, __a1); |
364 | } |
365 | |
366 | template <class _Fn, class _A0, class _A1, class _A2> |
367 | static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) { |
368 | __invoke(__f, __a0, __a1, __a2); |
369 | } |
370 | #endif |
371 | }; |
372 | |
373 | template <class _Tp> |
374 | class _LIBCPP_TEMPLATE_VIS reference_wrapper |
375 | : public __weak_result_type<_Tp> |
376 | { |
377 | public: |
378 | // types |
379 | typedef _Tp type; |
380 | private: |
381 | type* __f_; |
382 | |
383 | public: |
384 | // construct/copy/destroy |
385 | _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT |
386 | : __f_(_VSTD::addressof(__f)) {} |
387 | #ifndef _LIBCPP_CXX03_LANG |
388 | private: reference_wrapper(type&&); public: // = delete; // do not bind to temps |
389 | #endif |
390 | |
391 | // access |
392 | _LIBCPP_INLINE_VISIBILITY operator type& () const _NOEXCEPT {return *__f_;} |
393 | _LIBCPP_INLINE_VISIBILITY type& get() const _NOEXCEPT {return *__f_;} |
394 | |
395 | #ifndef _LIBCPP_CXX03_LANG |
396 | // invoke |
397 | template <class... _ArgTypes> |
398 | _LIBCPP_INLINE_VISIBILITY |
399 | typename __invoke_of<type&, _ArgTypes...>::type |
400 | operator() (_ArgTypes&&... __args) const { |
401 | return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...); |
402 | } |
403 | #else |
404 | |
405 | _LIBCPP_INLINE_VISIBILITY |
406 | typename __invoke_return<type>::type |
407 | operator() () const { |
408 | return __invoke(get()); |
409 | } |
410 | |
411 | template <class _A0> |
412 | _LIBCPP_INLINE_VISIBILITY |
413 | typename __invoke_return0<type, _A0>::type |
414 | operator() (_A0& __a0) const { |
415 | return __invoke(get(), __a0); |
416 | } |
417 | |
418 | template <class _A0> |
419 | _LIBCPP_INLINE_VISIBILITY |
420 | typename __invoke_return0<type, _A0 const>::type |
421 | operator() (_A0 const& __a0) const { |
422 | return __invoke(get(), __a0); |
423 | } |
424 | |
425 | template <class _A0, class _A1> |
426 | _LIBCPP_INLINE_VISIBILITY |
427 | typename __invoke_return1<type, _A0, _A1>::type |
428 | operator() (_A0& __a0, _A1& __a1) const { |
429 | return __invoke(get(), __a0, __a1); |
430 | } |
431 | |
432 | template <class _A0, class _A1> |
433 | _LIBCPP_INLINE_VISIBILITY |
434 | typename __invoke_return1<type, _A0 const, _A1>::type |
435 | operator() (_A0 const& __a0, _A1& __a1) const { |
436 | return __invoke(get(), __a0, __a1); |
437 | } |
438 | |
439 | template <class _A0, class _A1> |
440 | _LIBCPP_INLINE_VISIBILITY |
441 | typename __invoke_return1<type, _A0, _A1 const>::type |
442 | operator() (_A0& __a0, _A1 const& __a1) const { |
443 | return __invoke(get(), __a0, __a1); |
444 | } |
445 | |
446 | template <class _A0, class _A1> |
447 | _LIBCPP_INLINE_VISIBILITY |
448 | typename __invoke_return1<type, _A0 const, _A1 const>::type |
449 | operator() (_A0 const& __a0, _A1 const& __a1) const { |
450 | return __invoke(get(), __a0, __a1); |
451 | } |
452 | |
453 | template <class _A0, class _A1, class _A2> |
454 | _LIBCPP_INLINE_VISIBILITY |
455 | typename __invoke_return2<type, _A0, _A1, _A2>::type |
456 | operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { |
457 | return __invoke(get(), __a0, __a1, __a2); |
458 | } |
459 | |
460 | template <class _A0, class _A1, class _A2> |
461 | _LIBCPP_INLINE_VISIBILITY |
462 | typename __invoke_return2<type, _A0 const, _A1, _A2>::type |
463 | operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { |
464 | return __invoke(get(), __a0, __a1, __a2); |
465 | } |
466 | |
467 | template <class _A0, class _A1, class _A2> |
468 | _LIBCPP_INLINE_VISIBILITY |
469 | typename __invoke_return2<type, _A0, _A1 const, _A2>::type |
470 | operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { |
471 | return __invoke(get(), __a0, __a1, __a2); |
472 | } |
473 | |
474 | template <class _A0, class _A1, class _A2> |
475 | _LIBCPP_INLINE_VISIBILITY |
476 | typename __invoke_return2<type, _A0, _A1, _A2 const>::type |
477 | operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { |
478 | return __invoke(get(), __a0, __a1, __a2); |
479 | } |
480 | |
481 | template <class _A0, class _A1, class _A2> |
482 | _LIBCPP_INLINE_VISIBILITY |
483 | typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type |
484 | operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { |
485 | return __invoke(get(), __a0, __a1, __a2); |
486 | } |
487 | |
488 | template <class _A0, class _A1, class _A2> |
489 | _LIBCPP_INLINE_VISIBILITY |
490 | typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type |
491 | operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { |
492 | return __invoke(get(), __a0, __a1, __a2); |
493 | } |
494 | |
495 | template <class _A0, class _A1, class _A2> |
496 | _LIBCPP_INLINE_VISIBILITY |
497 | typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type |
498 | operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { |
499 | return __invoke(get(), __a0, __a1, __a2); |
500 | } |
501 | |
502 | template <class _A0, class _A1, class _A2> |
503 | _LIBCPP_INLINE_VISIBILITY |
504 | typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type |
505 | operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { |
506 | return __invoke(get(), __a0, __a1, __a2); |
507 | } |
508 | #endif // _LIBCPP_CXX03_LANG |
509 | }; |
510 | |
511 | |
512 | template <class _Tp> |
513 | inline _LIBCPP_INLINE_VISIBILITY |
514 | reference_wrapper<_Tp> |
515 | ref(_Tp& __t) _NOEXCEPT |
516 | { |
517 | return reference_wrapper<_Tp>(__t); |
518 | } |
519 | |
520 | template <class _Tp> |
521 | inline _LIBCPP_INLINE_VISIBILITY |
522 | reference_wrapper<_Tp> |
523 | ref(reference_wrapper<_Tp> __t) _NOEXCEPT |
524 | { |
525 | return ref(__t.get()); |
526 | } |
527 | |
528 | template <class _Tp> |
529 | inline _LIBCPP_INLINE_VISIBILITY |
530 | reference_wrapper<const _Tp> |
531 | cref(const _Tp& __t) _NOEXCEPT |
532 | { |
533 | return reference_wrapper<const _Tp>(__t); |
534 | } |
535 | |
536 | template <class _Tp> |
537 | inline _LIBCPP_INLINE_VISIBILITY |
538 | reference_wrapper<const _Tp> |
539 | cref(reference_wrapper<_Tp> __t) _NOEXCEPT |
540 | { |
541 | return cref(__t.get()); |
542 | } |
543 | |
544 | #ifndef _LIBCPP_CXX03_LANG |
545 | template <class _Tp> void ref(const _Tp&&) = delete; |
546 | template <class _Tp> void cref(const _Tp&&) = delete; |
547 | #endif |
548 | |
549 | #if _LIBCPP_STD_VER > 11 |
550 | template <class _Tp, class, class = void> |
551 | struct __is_transparent : false_type {}; |
552 | |
553 | template <class _Tp, class _Up> |
554 | struct __is_transparent<_Tp, _Up, |
555 | typename __void_t<typename _Tp::is_transparent>::type> |
556 | : true_type {}; |
557 | #endif |
558 | |
559 | // allocator_arg_t |
560 | |
561 | struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; }; |
562 | |
563 | #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) |
564 | extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg; |
565 | #else |
566 | /* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t(); |
567 | #endif |
568 | |
569 | // uses_allocator |
570 | |
571 | template <class _Tp> |
572 | struct __has_allocator_type |
573 | { |
574 | private: |
575 | struct __two {char __lx; char __lxx;}; |
576 | template <class _Up> static __two __test(...); |
577 | template <class _Up> static char __test(typename _Up::allocator_type* = 0); |
578 | public: |
579 | static const bool value = sizeof(__test<_Tp>(0)) == 1; |
580 | }; |
581 | |
582 | template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value> |
583 | struct __uses_allocator |
584 | : public integral_constant<bool, |
585 | is_convertible<_Alloc, typename _Tp::allocator_type>::value> |
586 | { |
587 | }; |
588 | |
589 | template <class _Tp, class _Alloc> |
590 | struct __uses_allocator<_Tp, _Alloc, false> |
591 | : public false_type |
592 | { |
593 | }; |
594 | |
595 | template <class _Tp, class _Alloc> |
596 | struct _LIBCPP_TEMPLATE_VIS uses_allocator |
597 | : public __uses_allocator<_Tp, _Alloc> |
598 | { |
599 | }; |
600 | |
601 | #if _LIBCPP_STD_VER > 14 |
602 | template <class _Tp, class _Alloc> |
603 | _LIBCPP_INLINE_VAR constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value; |
604 | #endif |
605 | |
606 | #ifndef _LIBCPP_CXX03_LANG |
607 | |
608 | // allocator construction |
609 | |
610 | template <class _Tp, class _Alloc, class ..._Args> |
611 | struct __uses_alloc_ctor_imp |
612 | { |
613 | typedef _LIBCPP_NODEBUG_TYPE typename __uncvref<_Alloc>::type _RawAlloc; |
614 | static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value; |
615 | static const bool __ic = |
616 | is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; |
617 | static const int value = __ua ? 2 - __ic : 0; |
618 | }; |
619 | |
620 | template <class _Tp, class _Alloc, class ..._Args> |
621 | struct __uses_alloc_ctor |
622 | : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value> |
623 | {}; |
624 | |
625 | template <class _Tp, class _Allocator, class... _Args> |
626 | inline _LIBCPP_INLINE_VISIBILITY |
627 | void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args ) |
628 | { |
629 | new (__storage) _Tp (_VSTD::forward<_Args>(__args)...); |
630 | } |
631 | |
632 | // FIXME: This should have a version which takes a non-const alloc. |
633 | template <class _Tp, class _Allocator, class... _Args> |
634 | inline _LIBCPP_INLINE_VISIBILITY |
635 | void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) |
636 | { |
637 | new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...); |
638 | } |
639 | |
640 | // FIXME: This should have a version which takes a non-const alloc. |
641 | template <class _Tp, class _Allocator, class... _Args> |
642 | inline _LIBCPP_INLINE_VISIBILITY |
643 | void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) |
644 | { |
645 | new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a); |
646 | } |
647 | |
648 | #endif // _LIBCPP_CXX03_LANG |
649 | |
650 | _LIBCPP_END_NAMESPACE_STD |
651 | |
652 | #endif // _LIBCPP_FUNCTIONAL_BASE |
653 | |