1 | // -*- C++ -*- |
2 | //===------------------------------ any -----------------------------------===// |
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_ANY |
11 | #define _LIBCPP_ANY |
12 | |
13 | /* |
14 | any synopsis |
15 | |
16 | namespace std { |
17 | |
18 | class bad_any_cast : public bad_cast |
19 | { |
20 | public: |
21 | virtual const char* what() const noexcept; |
22 | }; |
23 | |
24 | class any |
25 | { |
26 | public: |
27 | |
28 | // 6.3.1 any construct/destruct |
29 | any() noexcept; |
30 | |
31 | any(const any& other); |
32 | any(any&& other) noexcept; |
33 | |
34 | template <class ValueType> |
35 | any(ValueType&& value); |
36 | |
37 | ~any(); |
38 | |
39 | // 6.3.2 any assignments |
40 | any& operator=(const any& rhs); |
41 | any& operator=(any&& rhs) noexcept; |
42 | |
43 | template <class ValueType> |
44 | any& operator=(ValueType&& rhs); |
45 | |
46 | // 6.3.3 any modifiers |
47 | template <class ValueType, class... Args> |
48 | decay_t<ValueType>& emplace(Args&&... args); |
49 | template <class ValueType, class U, class... Args> |
50 | decay_t<ValueType>& emplace(initializer_list<U>, Args&&...); |
51 | void reset() noexcept; |
52 | void swap(any& rhs) noexcept; |
53 | |
54 | // 6.3.4 any observers |
55 | bool has_value() const noexcept; |
56 | const type_info& type() const noexcept; |
57 | }; |
58 | |
59 | // 6.4 Non-member functions |
60 | void swap(any& x, any& y) noexcept; |
61 | |
62 | template <class T, class ...Args> |
63 | any make_any(Args&& ...args); |
64 | template <class T, class U, class ...Args> |
65 | any make_any(initializer_list<U>, Args&& ...args); |
66 | |
67 | template<class ValueType> |
68 | ValueType any_cast(const any& operand); |
69 | template<class ValueType> |
70 | ValueType any_cast(any& operand); |
71 | template<class ValueType> |
72 | ValueType any_cast(any&& operand); |
73 | |
74 | template<class ValueType> |
75 | const ValueType* any_cast(const any* operand) noexcept; |
76 | template<class ValueType> |
77 | ValueType* any_cast(any* operand) noexcept; |
78 | |
79 | } // namespace std |
80 | |
81 | */ |
82 | |
83 | #include <experimental/__config> |
84 | #include <memory> |
85 | #include <new> |
86 | #include <typeinfo> |
87 | #include <type_traits> |
88 | #include <cstdlib> |
89 | #include <version> |
90 | |
91 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
92 | #pragma GCC system_header |
93 | #endif |
94 | |
95 | namespace std { |
96 | class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast |
97 | { |
98 | public: |
99 | virtual const char* what() const _NOEXCEPT; |
100 | }; |
101 | } // namespace std |
102 | |
103 | _LIBCPP_BEGIN_NAMESPACE_STD |
104 | |
105 | #if _LIBCPP_STD_VER > 14 |
106 | |
107 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
108 | _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST |
109 | void __throw_bad_any_cast() |
110 | { |
111 | #ifndef _LIBCPP_NO_EXCEPTIONS |
112 | throw bad_any_cast(); |
113 | #else |
114 | _VSTD::abort(); |
115 | #endif |
116 | } |
117 | |
118 | // Forward declarations |
119 | class _LIBCPP_TEMPLATE_VIS any; |
120 | |
121 | template <class _ValueType> |
122 | _LIBCPP_INLINE_VISIBILITY |
123 | add_pointer_t<add_const_t<_ValueType>> |
124 | any_cast(any const *) _NOEXCEPT; |
125 | |
126 | template <class _ValueType> |
127 | _LIBCPP_INLINE_VISIBILITY |
128 | add_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT; |
129 | |
130 | namespace __any_imp |
131 | { |
132 | using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>; |
133 | |
134 | template <class _Tp> |
135 | using _IsSmallObject = integral_constant<bool |
136 | , sizeof(_Tp) <= sizeof(_Buffer) |
137 | && alignment_of<_Buffer>::value |
138 | % alignment_of<_Tp>::value == 0 |
139 | && is_nothrow_move_constructible<_Tp>::value |
140 | >; |
141 | |
142 | enum class _Action { |
143 | _Destroy, |
144 | _Copy, |
145 | _Move, |
146 | _Get, |
147 | _TypeInfo |
148 | }; |
149 | |
150 | template <class _Tp> struct _SmallHandler; |
151 | template <class _Tp> struct _LargeHandler; |
152 | |
153 | template <class _Tp> |
154 | struct _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; }; |
155 | template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id; |
156 | |
157 | template <class _Tp> |
158 | inline _LIBCPP_INLINE_VISIBILITY |
159 | constexpr const void* __get_fallback_typeid() { |
160 | return &__unique_typeinfo<decay_t<_Tp>>::__id; |
161 | } |
162 | |
163 | template <class _Tp> |
164 | inline _LIBCPP_INLINE_VISIBILITY |
165 | bool __compare_typeid(type_info const* __id, const void* __fallback_id) |
166 | { |
167 | #if !defined(_LIBCPP_NO_RTTI) |
168 | if (__id && *__id == typeid(_Tp)) |
169 | return true; |
170 | #endif |
171 | if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>()) |
172 | return true; |
173 | return false; |
174 | } |
175 | |
176 | template <class _Tp> |
177 | using _Handler = conditional_t< |
178 | _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>; |
179 | |
180 | } // namespace __any_imp |
181 | |
182 | class _LIBCPP_TEMPLATE_VIS any |
183 | { |
184 | public: |
185 | // construct/destruct |
186 | _LIBCPP_INLINE_VISIBILITY |
187 | constexpr any() _NOEXCEPT : __h(nullptr) {} |
188 | |
189 | _LIBCPP_INLINE_VISIBILITY |
190 | any(any const & __other) : __h(nullptr) |
191 | { |
192 | if (__other.__h) __other.__call(_Action::_Copy, this); |
193 | } |
194 | |
195 | _LIBCPP_INLINE_VISIBILITY |
196 | any(any && __other) _NOEXCEPT : __h(nullptr) |
197 | { |
198 | if (__other.__h) __other.__call(_Action::_Move, this); |
199 | } |
200 | |
201 | template < |
202 | class _ValueType |
203 | , class _Tp = decay_t<_ValueType> |
204 | , class = enable_if_t< |
205 | !is_same<_Tp, any>::value && |
206 | !__is_inplace_type<_ValueType>::value && |
207 | is_copy_constructible<_Tp>::value> |
208 | > |
209 | _LIBCPP_INLINE_VISIBILITY |
210 | any(_ValueType && __value); |
211 | |
212 | template <class _ValueType, class ..._Args, |
213 | class _Tp = decay_t<_ValueType>, |
214 | class = enable_if_t< |
215 | is_constructible<_Tp, _Args...>::value && |
216 | is_copy_constructible<_Tp>::value |
217 | > |
218 | > |
219 | _LIBCPP_INLINE_VISIBILITY |
220 | explicit any(in_place_type_t<_ValueType>, _Args&&... __args); |
221 | |
222 | template <class _ValueType, class _Up, class ..._Args, |
223 | class _Tp = decay_t<_ValueType>, |
224 | class = enable_if_t< |
225 | is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && |
226 | is_copy_constructible<_Tp>::value> |
227 | > |
228 | _LIBCPP_INLINE_VISIBILITY |
229 | explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args); |
230 | |
231 | _LIBCPP_INLINE_VISIBILITY |
232 | ~any() { this->reset(); } |
233 | |
234 | // assignments |
235 | _LIBCPP_INLINE_VISIBILITY |
236 | any & operator=(any const & __rhs) { |
237 | any(__rhs).swap(*this); |
238 | return *this; |
239 | } |
240 | |
241 | _LIBCPP_INLINE_VISIBILITY |
242 | any & operator=(any && __rhs) _NOEXCEPT { |
243 | any(_VSTD::move(__rhs)).swap(*this); |
244 | return *this; |
245 | } |
246 | |
247 | template < |
248 | class _ValueType |
249 | , class _Tp = decay_t<_ValueType> |
250 | , class = enable_if_t< |
251 | !is_same<_Tp, any>::value |
252 | && is_copy_constructible<_Tp>::value> |
253 | > |
254 | _LIBCPP_INLINE_VISIBILITY |
255 | any & operator=(_ValueType && __rhs); |
256 | |
257 | template <class _ValueType, class ..._Args, |
258 | class _Tp = decay_t<_ValueType>, |
259 | class = enable_if_t< |
260 | is_constructible<_Tp, _Args...>::value && |
261 | is_copy_constructible<_Tp>::value> |
262 | > |
263 | _LIBCPP_INLINE_VISIBILITY |
264 | _Tp& emplace(_Args&&... args); |
265 | |
266 | template <class _ValueType, class _Up, class ..._Args, |
267 | class _Tp = decay_t<_ValueType>, |
268 | class = enable_if_t< |
269 | is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && |
270 | is_copy_constructible<_Tp>::value> |
271 | > |
272 | _LIBCPP_INLINE_VISIBILITY |
273 | _Tp& emplace(initializer_list<_Up>, _Args&&...); |
274 | |
275 | // 6.3.3 any modifiers |
276 | _LIBCPP_INLINE_VISIBILITY |
277 | void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); } |
278 | |
279 | _LIBCPP_INLINE_VISIBILITY |
280 | void swap(any & __rhs) _NOEXCEPT; |
281 | |
282 | // 6.3.4 any observers |
283 | _LIBCPP_INLINE_VISIBILITY |
284 | bool has_value() const _NOEXCEPT { return __h != nullptr; } |
285 | |
286 | #if !defined(_LIBCPP_NO_RTTI) |
287 | _LIBCPP_INLINE_VISIBILITY |
288 | const type_info & type() const _NOEXCEPT { |
289 | if (__h) { |
290 | return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo)); |
291 | } else { |
292 | return typeid(void); |
293 | } |
294 | } |
295 | #endif |
296 | |
297 | private: |
298 | typedef __any_imp::_Action _Action; |
299 | using _HandleFuncPtr = void* (*)(_Action, any const *, any *, const type_info *, |
300 | const void* __fallback_info); |
301 | |
302 | union _Storage { |
303 | constexpr _Storage() : __ptr(nullptr) {} |
304 | void * __ptr; |
305 | __any_imp::_Buffer __buf; |
306 | }; |
307 | |
308 | _LIBCPP_INLINE_VISIBILITY |
309 | void * __call(_Action __a, any * __other = nullptr, |
310 | type_info const * __info = nullptr, |
311 | const void* __fallback_info = nullptr) const |
312 | { |
313 | return __h(__a, this, __other, __info, __fallback_info); |
314 | } |
315 | |
316 | _LIBCPP_INLINE_VISIBILITY |
317 | void * __call(_Action __a, any * __other = nullptr, |
318 | type_info const * __info = nullptr, |
319 | const void* __fallback_info = nullptr) |
320 | { |
321 | return __h(__a, this, __other, __info, __fallback_info); |
322 | } |
323 | |
324 | template <class> |
325 | friend struct __any_imp::_SmallHandler; |
326 | template <class> |
327 | friend struct __any_imp::_LargeHandler; |
328 | |
329 | template <class _ValueType> |
330 | friend add_pointer_t<add_const_t<_ValueType>> |
331 | any_cast(any const *) _NOEXCEPT; |
332 | |
333 | template <class _ValueType> |
334 | friend add_pointer_t<_ValueType> |
335 | any_cast(any *) _NOEXCEPT; |
336 | |
337 | _HandleFuncPtr __h = nullptr; |
338 | _Storage __s; |
339 | }; |
340 | |
341 | namespace __any_imp |
342 | { |
343 | template <class _Tp> |
344 | struct _LIBCPP_TEMPLATE_VIS _SmallHandler |
345 | { |
346 | _LIBCPP_INLINE_VISIBILITY |
347 | static void* __handle(_Action __act, any const * __this, any * __other, |
348 | type_info const * __info, const void* __fallback_info) |
349 | { |
350 | switch (__act) |
351 | { |
352 | case _Action::_Destroy: |
353 | __destroy(const_cast<any &>(*__this)); |
354 | return nullptr; |
355 | case _Action::_Copy: |
356 | __copy(*__this, *__other); |
357 | return nullptr; |
358 | case _Action::_Move: |
359 | __move(const_cast<any &>(*__this), *__other); |
360 | return nullptr; |
361 | case _Action::_Get: |
362 | return __get(const_cast<any &>(*__this), __info, __fallback_info); |
363 | case _Action::_TypeInfo: |
364 | return __type_info(); |
365 | } |
366 | } |
367 | |
368 | template <class ..._Args> |
369 | _LIBCPP_INLINE_VISIBILITY |
370 | static _Tp& __create(any & __dest, _Args&&... __args) { |
371 | _Tp* __ret = ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...); |
372 | __dest.__h = &_SmallHandler::__handle; |
373 | return *__ret; |
374 | } |
375 | |
376 | private: |
377 | _LIBCPP_INLINE_VISIBILITY |
378 | static void __destroy(any & __this) { |
379 | _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf)); |
380 | __value.~_Tp(); |
381 | __this.__h = nullptr; |
382 | } |
383 | |
384 | _LIBCPP_INLINE_VISIBILITY |
385 | static void __copy(any const & __this, any & __dest) { |
386 | _SmallHandler::__create(__dest, *static_cast<_Tp const *>( |
387 | static_cast<void const *>(&__this.__s.__buf))); |
388 | } |
389 | |
390 | _LIBCPP_INLINE_VISIBILITY |
391 | static void __move(any & __this, any & __dest) { |
392 | _SmallHandler::__create(__dest, _VSTD::move( |
393 | *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf)))); |
394 | __destroy(__this); |
395 | } |
396 | |
397 | _LIBCPP_INLINE_VISIBILITY |
398 | static void* __get(any & __this, |
399 | type_info const * __info, |
400 | const void* __fallback_id) |
401 | { |
402 | if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id)) |
403 | return static_cast<void*>(&__this.__s.__buf); |
404 | return nullptr; |
405 | } |
406 | |
407 | _LIBCPP_INLINE_VISIBILITY |
408 | static void* __type_info() |
409 | { |
410 | #if !defined(_LIBCPP_NO_RTTI) |
411 | return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); |
412 | #else |
413 | return nullptr; |
414 | #endif |
415 | } |
416 | }; |
417 | |
418 | template <class _Tp> |
419 | struct _LIBCPP_TEMPLATE_VIS _LargeHandler |
420 | { |
421 | _LIBCPP_INLINE_VISIBILITY |
422 | static void* __handle(_Action __act, any const * __this, |
423 | any * __other, type_info const * __info, |
424 | void const* __fallback_info) |
425 | { |
426 | switch (__act) |
427 | { |
428 | case _Action::_Destroy: |
429 | __destroy(const_cast<any &>(*__this)); |
430 | return nullptr; |
431 | case _Action::_Copy: |
432 | __copy(*__this, *__other); |
433 | return nullptr; |
434 | case _Action::_Move: |
435 | __move(const_cast<any &>(*__this), *__other); |
436 | return nullptr; |
437 | case _Action::_Get: |
438 | return __get(const_cast<any &>(*__this), __info, __fallback_info); |
439 | case _Action::_TypeInfo: |
440 | return __type_info(); |
441 | } |
442 | } |
443 | |
444 | template <class ..._Args> |
445 | _LIBCPP_INLINE_VISIBILITY |
446 | static _Tp& __create(any & __dest, _Args&&... __args) { |
447 | typedef allocator<_Tp> _Alloc; |
448 | typedef __allocator_destructor<_Alloc> _Dp; |
449 | _Alloc __a; |
450 | unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
451 | _Tp* __ret = ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...); |
452 | __dest.__s.__ptr = __hold.release(); |
453 | __dest.__h = &_LargeHandler::__handle; |
454 | return *__ret; |
455 | } |
456 | |
457 | private: |
458 | |
459 | _LIBCPP_INLINE_VISIBILITY |
460 | static void __destroy(any & __this){ |
461 | delete static_cast<_Tp*>(__this.__s.__ptr); |
462 | __this.__h = nullptr; |
463 | } |
464 | |
465 | _LIBCPP_INLINE_VISIBILITY |
466 | static void __copy(any const & __this, any & __dest) { |
467 | _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr)); |
468 | } |
469 | |
470 | _LIBCPP_INLINE_VISIBILITY |
471 | static void __move(any & __this, any & __dest) { |
472 | __dest.__s.__ptr = __this.__s.__ptr; |
473 | __dest.__h = &_LargeHandler::__handle; |
474 | __this.__h = nullptr; |
475 | } |
476 | |
477 | _LIBCPP_INLINE_VISIBILITY |
478 | static void* __get(any & __this, type_info const * __info, |
479 | void const* __fallback_info) |
480 | { |
481 | if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info)) |
482 | return static_cast<void*>(__this.__s.__ptr); |
483 | return nullptr; |
484 | |
485 | } |
486 | |
487 | _LIBCPP_INLINE_VISIBILITY |
488 | static void* __type_info() |
489 | { |
490 | #if !defined(_LIBCPP_NO_RTTI) |
491 | return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); |
492 | #else |
493 | return nullptr; |
494 | #endif |
495 | } |
496 | }; |
497 | |
498 | } // namespace __any_imp |
499 | |
500 | |
501 | template <class _ValueType, class _Tp, class> |
502 | any::any(_ValueType && __v) : __h(nullptr) |
503 | { |
504 | __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v)); |
505 | } |
506 | |
507 | template <class _ValueType, class ..._Args, class _Tp, class> |
508 | any::any(in_place_type_t<_ValueType>, _Args&&... __args) { |
509 | __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); |
510 | } |
511 | |
512 | template <class _ValueType, class _Up, class ..._Args, class _Tp, class> |
513 | any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) { |
514 | __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); |
515 | } |
516 | |
517 | template <class _ValueType, class, class> |
518 | inline _LIBCPP_INLINE_VISIBILITY |
519 | any & any::operator=(_ValueType && __v) |
520 | { |
521 | any(_VSTD::forward<_ValueType>(__v)).swap(*this); |
522 | return *this; |
523 | } |
524 | |
525 | template <class _ValueType, class ..._Args, class _Tp, class> |
526 | inline _LIBCPP_INLINE_VISIBILITY |
527 | _Tp& any::emplace(_Args&&... __args) { |
528 | reset(); |
529 | return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); |
530 | } |
531 | |
532 | template <class _ValueType, class _Up, class ..._Args, class _Tp, class> |
533 | inline _LIBCPP_INLINE_VISIBILITY |
534 | _Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) { |
535 | reset(); |
536 | return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); |
537 | } |
538 | |
539 | inline _LIBCPP_INLINE_VISIBILITY |
540 | void any::swap(any & __rhs) _NOEXCEPT |
541 | { |
542 | if (this == &__rhs) |
543 | return; |
544 | if (__h && __rhs.__h) { |
545 | any __tmp; |
546 | __rhs.__call(_Action::_Move, &__tmp); |
547 | this->__call(_Action::_Move, &__rhs); |
548 | __tmp.__call(_Action::_Move, this); |
549 | } |
550 | else if (__h) { |
551 | this->__call(_Action::_Move, &__rhs); |
552 | } |
553 | else if (__rhs.__h) { |
554 | __rhs.__call(_Action::_Move, this); |
555 | } |
556 | } |
557 | |
558 | // 6.4 Non-member functions |
559 | |
560 | inline _LIBCPP_INLINE_VISIBILITY |
561 | void swap(any & __lhs, any & __rhs) _NOEXCEPT |
562 | { |
563 | __lhs.swap(__rhs); |
564 | } |
565 | |
566 | template <class _Tp, class ..._Args> |
567 | inline _LIBCPP_INLINE_VISIBILITY |
568 | any make_any(_Args&&... __args) { |
569 | return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...); |
570 | } |
571 | |
572 | template <class _Tp, class _Up, class ..._Args> |
573 | inline _LIBCPP_INLINE_VISIBILITY |
574 | any make_any(initializer_list<_Up> __il, _Args&&... __args) { |
575 | return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...); |
576 | } |
577 | |
578 | template <class _ValueType> |
579 | inline _LIBCPP_INLINE_VISIBILITY |
580 | _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST |
581 | _ValueType any_cast(any const & __v) |
582 | { |
583 | using _RawValueType = __uncvref_t<_ValueType>; |
584 | static_assert(is_constructible<_ValueType, _RawValueType const &>::value, |
585 | "ValueType is required to be a const lvalue reference " |
586 | "or a CopyConstructible type" ); |
587 | auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v); |
588 | if (__tmp == nullptr) |
589 | __throw_bad_any_cast(); |
590 | return static_cast<_ValueType>(*__tmp); |
591 | } |
592 | |
593 | template <class _ValueType> |
594 | inline _LIBCPP_INLINE_VISIBILITY |
595 | _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST |
596 | _ValueType any_cast(any & __v) |
597 | { |
598 | using _RawValueType = __uncvref_t<_ValueType>; |
599 | static_assert(is_constructible<_ValueType, _RawValueType &>::value, |
600 | "ValueType is required to be an lvalue reference " |
601 | "or a CopyConstructible type" ); |
602 | auto __tmp = _VSTD::any_cast<_RawValueType>(&__v); |
603 | if (__tmp == nullptr) |
604 | __throw_bad_any_cast(); |
605 | return static_cast<_ValueType>(*__tmp); |
606 | } |
607 | |
608 | template <class _ValueType> |
609 | inline _LIBCPP_INLINE_VISIBILITY |
610 | _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST |
611 | _ValueType any_cast(any && __v) |
612 | { |
613 | using _RawValueType = __uncvref_t<_ValueType>; |
614 | static_assert(is_constructible<_ValueType, _RawValueType>::value, |
615 | "ValueType is required to be an rvalue reference " |
616 | "or a CopyConstructible type" ); |
617 | auto __tmp = _VSTD::any_cast<_RawValueType>(&__v); |
618 | if (__tmp == nullptr) |
619 | __throw_bad_any_cast(); |
620 | return static_cast<_ValueType>(_VSTD::move(*__tmp)); |
621 | } |
622 | |
623 | template <class _ValueType> |
624 | inline _LIBCPP_INLINE_VISIBILITY |
625 | add_pointer_t<add_const_t<_ValueType>> |
626 | any_cast(any const * __any) _NOEXCEPT |
627 | { |
628 | static_assert(!is_reference<_ValueType>::value, |
629 | "_ValueType may not be a reference." ); |
630 | return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any)); |
631 | } |
632 | |
633 | template <class _RetType> |
634 | inline _LIBCPP_INLINE_VISIBILITY |
635 | _RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept { |
636 | return static_cast<_RetType>(__p); |
637 | } |
638 | |
639 | template <class _RetType> |
640 | inline _LIBCPP_INLINE_VISIBILITY |
641 | _RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept { |
642 | return nullptr; |
643 | } |
644 | |
645 | template <class _ValueType> |
646 | add_pointer_t<_ValueType> |
647 | any_cast(any * __any) _NOEXCEPT |
648 | { |
649 | using __any_imp::_Action; |
650 | static_assert(!is_reference<_ValueType>::value, |
651 | "_ValueType may not be a reference." ); |
652 | typedef typename add_pointer<_ValueType>::type _ReturnType; |
653 | if (__any && __any->__h) { |
654 | void *__p = __any->__call(_Action::_Get, nullptr, |
655 | #if !defined(_LIBCPP_NO_RTTI) |
656 | &typeid(_ValueType), |
657 | #else |
658 | nullptr, |
659 | #endif |
660 | __any_imp::__get_fallback_typeid<_ValueType>()); |
661 | return _VSTD::__pointer_or_func_cast<_ReturnType>( |
662 | __p, is_function<_ValueType>{}); |
663 | } |
664 | return nullptr; |
665 | } |
666 | |
667 | #endif // _LIBCPP_STD_VER > 14 |
668 | |
669 | _LIBCPP_END_NAMESPACE_STD |
670 | |
671 | #endif // _LIBCPP_ANY |
672 | |