blob: 69fdbddd621dcad2a94c73dd0ce602e830a04474 [file] [log] [blame]
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +00001// -*- C++ -*-
2//===------------------------------ any -----------------------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_ANY
12#define _LIBCPP_ANY
13
14/*
15 any synopsis
16
17namespace std {
18
19 class bad_any_cast : public bad_cast
20 {
21 public:
22 virtual const char* what() const noexcept;
23 };
24
25 class any
26 {
27 public:
28
29 // 6.3.1 any construct/destruct
30 any() noexcept;
31
32 any(const any& other);
33 any(any&& other) noexcept;
34
35 template <class ValueType>
36 any(ValueType&& value);
37
38 ~any();
39
40 // 6.3.2 any assignments
41 any& operator=(const any& rhs);
42 any& operator=(any&& rhs) noexcept;
43
44 template <class ValueType>
45 any& operator=(ValueType&& rhs);
46
47 // 6.3.3 any modifiers
48 void reset() noexcept;
49 void swap(any& rhs) noexcept;
50
51 // 6.3.4 any observers
52 bool has_value() const noexcept;
53 const type_info& type() const noexcept;
54 };
55
56 // 6.4 Non-member functions
57 void swap(any& x, any& y) noexcept;
58
59 template <class T, class ...Args>
60 any make_any(Args&& ...args);
61 template <class T, class U, class ...Args>
62 any make_any(initializer_list<U>, Args&& ...args);
63
64 template<class ValueType>
65 ValueType any_cast(const any& operand);
66 template<class ValueType>
67 ValueType any_cast(any& operand);
68 template<class ValueType>
69 ValueType any_cast(any&& operand);
70
71 template<class ValueType>
72 const ValueType* any_cast(const any* operand) noexcept;
73 template<class ValueType>
74 ValueType* any_cast(any* operand) noexcept;
75
76} // namespace fundamentals_v1
77} // namespace experimental
78} // namespace std
79
80*/
81
82#include <experimental/__config>
83#include <memory>
84#include <new>
85#include <typeinfo>
86#include <type_traits>
87#include <cstdlib>
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +000088
89#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
90#pragma GCC system_header
91#endif
92
93namespace std {
94class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast
95{
96public:
97 virtual const char* what() const _NOEXCEPT;
98};
99} // namespace std
100
101_LIBCPP_BEGIN_NAMESPACE_STD
102
103#if _LIBCPP_STD_VER > 14
104
Marshall Clowed3e2292016-08-25 17:47:09 +0000105_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
106void __throw_bad_any_cast()
107{
108#ifndef _LIBCPP_NO_EXCEPTIONS
109 throw bad_any_cast();
110#else
111 _VSTD::abort();
112#endif
113}
114
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000115// Forward declarations
116class _LIBCPP_TYPE_VIS_ONLY any;
117
118template <class _ValueType>
119_LIBCPP_INLINE_VISIBILITY
120add_pointer_t<add_const_t<_ValueType>>
121any_cast(any const *) _NOEXCEPT;
122
123template <class _ValueType>
124_LIBCPP_INLINE_VISIBILITY
125add_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT;
126
127namespace __any_imp
128{
129 using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>;
130
131 template <class _Tp>
132 using _IsSmallObject = integral_constant<bool
133 , sizeof(_Tp) <= sizeof(_Buffer)
134 && alignment_of<_Buffer>::value
135 % alignment_of<_Tp>::value == 0
136 && is_nothrow_move_constructible<_Tp>::value
137 >;
138
139 enum class _Action {
140 _Destroy,
141 _Copy,
142 _Move,
143 _Get,
144 _TypeInfo
145 };
146
147 template <class _Tp> struct _SmallHandler;
148 template <class _Tp> struct _LargeHandler;
149
150 template <class _Tp>
151 struct _LIBCPP_TYPE_VIS_ONLY __unique_typeinfo { static constexpr int __id = 0; };
152 template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id;
153
154 template <class _Tp>
155 inline _LIBCPP_INLINE_VISIBILITY
156 constexpr const void* __get_fallback_typeid() {
157 return &__unique_typeinfo<decay_t<_Tp>>::__id;
158 }
159
160 template <class _Tp>
161 inline _LIBCPP_INLINE_VISIBILITY
162 bool __compare_typeid(type_info const* __id, const void* __fallback_id)
163 {
164#if !defined(_LIBCPP_NO_RTTI)
165 if (__id && *__id == typeid(_Tp))
166 return true;
167#endif
168 if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>())
169 return true;
170 return false;
171 }
172
173 template <class _Tp>
174 using _Handler = conditional_t<
175 _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
176
177} // namespace __any_imp
178
179class _LIBCPP_TYPE_VIS_ONLY any
180{
181public:
182 // construct/destruct
183 _LIBCPP_INLINE_VISIBILITY
184 constexpr any() _NOEXCEPT : __h(nullptr) {}
185
186 _LIBCPP_INLINE_VISIBILITY
187 any(any const & __other) : __h(nullptr)
188 {
189 if (__other.__h) __other.__call(_Action::_Copy, this);
190 }
191
192 _LIBCPP_INLINE_VISIBILITY
193 any(any && __other) _NOEXCEPT : __h(nullptr)
194 {
195 if (__other.__h) __other.__call(_Action::_Move, this);
196 }
197
198 template <
199 class _ValueType
Eric Fiselier58614252016-10-07 21:27:45 +0000200 , class _Tp = decay_t<_ValueType>
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000201 , class = enable_if_t<
Eric Fiselier58614252016-10-07 21:27:45 +0000202 !is_same<_Tp, any>::value &&
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000203 !__is_inplace_type<_ValueType>::value &&
Eric Fiselier58614252016-10-07 21:27:45 +0000204 is_copy_constructible<_Tp>::value>
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000205 >
206 _LIBCPP_INLINE_VISIBILITY
207 any(_ValueType && __value);
208
Eric Fiselier58614252016-10-07 21:27:45 +0000209 template <class _ValueType, class ..._Args,
210 class _Tp = decay_t<_ValueType>,
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000211 class = enable_if_t<
212 is_constructible<_Tp, _Args...>::value &&
213 is_copy_constructible<_Tp>::value
214 >
215 >
216 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier58614252016-10-07 21:27:45 +0000217 explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000218
Eric Fiselier58614252016-10-07 21:27:45 +0000219 template <class _ValueType, class _Up, class ..._Args,
220 class _Tp = decay_t<_ValueType>,
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000221 class = enable_if_t<
222 is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
223 is_copy_constructible<_Tp>::value>
224 >
225 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier58614252016-10-07 21:27:45 +0000226 explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000227
228 _LIBCPP_INLINE_VISIBILITY
229 ~any() { this->reset(); }
230
231 // assignments
232 _LIBCPP_INLINE_VISIBILITY
233 any & operator=(any const & __rhs) {
234 any(__rhs).swap(*this);
235 return *this;
236 }
237
238 _LIBCPP_INLINE_VISIBILITY
239 any & operator=(any && __rhs) _NOEXCEPT {
240 any(_VSTD::move(__rhs)).swap(*this);
241 return *this;
242 }
243
244 // TODO: Should this be constrained to disallow in_place types like the
245 // ValueType constructor?
246 template <
247 class _ValueType
Eric Fiselier58614252016-10-07 21:27:45 +0000248 , class _Tp = decay_t<_ValueType>
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000249 , class = enable_if_t<
Eric Fiselier58614252016-10-07 21:27:45 +0000250 !is_same<_Tp, any>::value
251 && is_copy_constructible<_Tp>::value
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000252 && !__is_inplace_type<_ValueType>::value>
253 >
254 _LIBCPP_INLINE_VISIBILITY
255 any & operator=(_ValueType && __rhs);
256
Eric Fiselier58614252016-10-07 21:27:45 +0000257 template <class _ValueType, class ..._Args,
258 class _Tp = decay_t<_ValueType>,
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000259 class = enable_if_t<
260 is_constructible<_Tp, _Args...>::value &&
261 is_copy_constructible<_Tp>::value>
262 >
263 _LIBCPP_INLINE_VISIBILITY
264 void emplace(_Args&&... args);
265
Eric Fiselier58614252016-10-07 21:27:45 +0000266 template <class _ValueType, class _Up, class ..._Args,
267 class _Tp = decay_t<_ValueType>,
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000268 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 void 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
297private:
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_ALWAYS_INLINE
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_ALWAYS_INLINE
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
341namespace __any_imp
342{
343 template <class _Tp>
344 struct _LIBCPP_TYPE_VIS_ONLY _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 void __create(any & __dest, _Args&&... __args) {
371 ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...);
372 __dest.__h = &_SmallHandler::__handle;
373 }
374
375 private:
376 _LIBCPP_INLINE_VISIBILITY
377 static void __destroy(any & __this) {
378 _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
379 __value.~_Tp();
380 __this.__h = nullptr;
381 }
382
383 _LIBCPP_INLINE_VISIBILITY
384 static void __copy(any const & __this, any & __dest) {
385 _SmallHandler::__create(__dest, *static_cast<_Tp const *>(
386 static_cast<void const *>(&__this.__s.__buf)));
387 }
388
389 _LIBCPP_INLINE_VISIBILITY
390 static void __move(any & __this, any & __dest) {
391 _SmallHandler::__create(__dest, _VSTD::move(
392 *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf))));
393 __destroy(__this);
394 }
395
396 _LIBCPP_INLINE_VISIBILITY
397 static void* __get(any & __this,
398 type_info const * __info,
399 const void* __fallback_id)
400 {
401 if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
402 return static_cast<void*>(&__this.__s.__buf);
403 return nullptr;
404 }
405
406 _LIBCPP_INLINE_VISIBILITY
407 static void* __type_info()
408 {
409#if !defined(_LIBCPP_NO_RTTI)
410 return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
411#else
412 return nullptr;
413#endif
414 }
415 };
416
417 template <class _Tp>
418 struct _LIBCPP_TYPE_VIS_ONLY _LargeHandler
419 {
420 _LIBCPP_INLINE_VISIBILITY
421 static void* __handle(_Action __act, any const * __this,
422 any * __other, type_info const * __info,
423 void const* __fallback_info)
424 {
425 switch (__act)
426 {
427 case _Action::_Destroy:
428 __destroy(const_cast<any &>(*__this));
429 return nullptr;
430 case _Action::_Copy:
431 __copy(*__this, *__other);
432 return nullptr;
433 case _Action::_Move:
434 __move(const_cast<any &>(*__this), *__other);
435 return nullptr;
436 case _Action::_Get:
437 return __get(const_cast<any &>(*__this), __info, __fallback_info);
438 case _Action::_TypeInfo:
439 return __type_info();
440 }
441 }
442
443 template <class ..._Args>
444 _LIBCPP_INLINE_VISIBILITY
445 static void __create(any & __dest, _Args&&... __args) {
446 typedef allocator<_Tp> _Alloc;
447 typedef __allocator_destructor<_Alloc> _Dp;
448 _Alloc __a;
449 unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
450 ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...);
451 __dest.__s.__ptr = __hold.release();
452 __dest.__h = &_LargeHandler::__handle;
453 }
454
455 private:
456
457 _LIBCPP_INLINE_VISIBILITY
458 static void __destroy(any & __this){
459 delete static_cast<_Tp*>(__this.__s.__ptr);
460 __this.__h = nullptr;
461 }
462
463 _LIBCPP_INLINE_VISIBILITY
464 static void __copy(any const & __this, any & __dest) {
465 _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr));
466 }
467
468 _LIBCPP_INLINE_VISIBILITY
469 static void __move(any & __this, any & __dest) {
470 __dest.__s.__ptr = __this.__s.__ptr;
471 __dest.__h = &_LargeHandler::__handle;
472 __this.__h = nullptr;
473 }
474
475 _LIBCPP_INLINE_VISIBILITY
476 static void* __get(any & __this, type_info const * __info,
477 void const* __fallback_info)
478 {
479 if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
480 return static_cast<void*>(__this.__s.__ptr);
481 return nullptr;
482
483 }
484
485 _LIBCPP_INLINE_VISIBILITY
486 static void* __type_info()
487 {
488#if !defined(_LIBCPP_NO_RTTI)
489 return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
490#else
491 return nullptr;
492#endif
493 }
494 };
495
496} // namespace __any_imp
497
498
Eric Fiselier58614252016-10-07 21:27:45 +0000499template <class _ValueType, class _Tp, class>
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000500any::any(_ValueType && __v) : __h(nullptr)
501{
Eric Fiselier58614252016-10-07 21:27:45 +0000502 __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v));
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000503}
504
Eric Fiselier58614252016-10-07 21:27:45 +0000505template <class _ValueType, class ..._Args, class _Tp, class>
506any::any(in_place_type_t<_ValueType>, _Args&&... __args) {
507 __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000508};
509
Eric Fiselier58614252016-10-07 21:27:45 +0000510template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
511any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
512 __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000513}
514
Eric Fiselier58614252016-10-07 21:27:45 +0000515template <class _ValueType, class, class>
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000516inline _LIBCPP_INLINE_VISIBILITY
517any & any::operator=(_ValueType && __v)
518{
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000519 any(_VSTD::forward<_ValueType>(__v)).swap(*this);
520 return *this;
521}
522
Eric Fiselier58614252016-10-07 21:27:45 +0000523template <class _ValueType, class ..._Args, class _Tp, class>
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000524inline _LIBCPP_INLINE_VISIBILITY
525void any::emplace(_Args&&... __args) {
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000526 reset();
Eric Fiselier58614252016-10-07 21:27:45 +0000527 __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000528}
529
Eric Fiselier58614252016-10-07 21:27:45 +0000530template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000531inline _LIBCPP_INLINE_VISIBILITY
532void any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000533 reset();
Eric Fiselier58614252016-10-07 21:27:45 +0000534 __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000535}
536
537inline _LIBCPP_INLINE_VISIBILITY
538void any::swap(any & __rhs) _NOEXCEPT
539{
Eric Fiselier58614252016-10-07 21:27:45 +0000540 if (this == &__rhs)
541 return;
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000542 if (__h && __rhs.__h) {
543 any __tmp;
544 __rhs.__call(_Action::_Move, &__tmp);
545 this->__call(_Action::_Move, &__rhs);
546 __tmp.__call(_Action::_Move, this);
547 }
548 else if (__h) {
549 this->__call(_Action::_Move, &__rhs);
550 }
551 else if (__rhs.__h) {
552 __rhs.__call(_Action::_Move, this);
553 }
554}
555
556// 6.4 Non-member functions
557
558inline _LIBCPP_INLINE_VISIBILITY
559void swap(any & __lhs, any & __rhs) _NOEXCEPT
560{
561 __lhs.swap(__rhs);
562}
563
564template <class _Tp, class ..._Args>
565inline _LIBCPP_INLINE_VISIBILITY
566any make_any(_Args&&... __args) {
567 return any(in_place<_Tp>, _VSTD::forward<_Args>(__args)...);
568}
569
570template <class _Tp, class _Up, class ..._Args>
571inline _LIBCPP_INLINE_VISIBILITY
572any make_any(initializer_list<_Up> __il, _Args&&... __args) {
573 return any(in_place<_Tp>, __il, _VSTD::forward<_Args>(__args)...);
574}
575
576template <class _ValueType>
577inline _LIBCPP_INLINE_VISIBILITY
578_ValueType any_cast(any const & __v)
579{
Eric Fiselier58614252016-10-07 21:27:45 +0000580 using _RawValueType = __uncvref_t<_ValueType>;
581 static_assert(is_constructible<_ValueType, _RawValueType const &>::value,
582 "ValueType is required to be a reference or a CopyConstructible type");
583 auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v);
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000584 if (__tmp == nullptr)
Marshall Clowed3e2292016-08-25 17:47:09 +0000585 __throw_bad_any_cast();
Eric Fiselier58614252016-10-07 21:27:45 +0000586 return static_cast<_ValueType>(*__tmp);
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000587}
588
589template <class _ValueType>
590inline _LIBCPP_INLINE_VISIBILITY
591_ValueType any_cast(any & __v)
592{
Eric Fiselier58614252016-10-07 21:27:45 +0000593 using _RawValueType = __uncvref_t<_ValueType>;
594 static_assert(is_constructible<_ValueType, _RawValueType &>::value,
595 "ValueType is required to be a reference or a CopyConstructible type");
596 auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000597 if (__tmp == nullptr)
Marshall Clowed3e2292016-08-25 17:47:09 +0000598 __throw_bad_any_cast();
Eric Fiselier58614252016-10-07 21:27:45 +0000599 return static_cast<_ValueType>(*__tmp);
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000600}
601
602template <class _ValueType>
603inline _LIBCPP_INLINE_VISIBILITY
604_ValueType any_cast(any && __v)
605{
Eric Fiselier58614252016-10-07 21:27:45 +0000606 using _RawValueType = __uncvref_t<_ValueType>;
607 static_assert(is_constructible<_ValueType, _RawValueType>::value,
608 "ValueType is required to be an rvalue reference or a CopyConstructible type");
609 auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000610 if (__tmp == nullptr)
Marshall Clowed3e2292016-08-25 17:47:09 +0000611 __throw_bad_any_cast();
Eric Fiselier58614252016-10-07 21:27:45 +0000612 return static_cast<_ValueType>(_VSTD::move(*__tmp));
Eric Fiselierf6b3bfe2016-08-11 03:13:11 +0000613}
614
615template <class _ValueType>
616inline _LIBCPP_INLINE_VISIBILITY
617add_pointer_t<add_const_t<_ValueType>>
618any_cast(any const * __any) _NOEXCEPT
619{
620 static_assert(!is_reference<_ValueType>::value,
621 "_ValueType may not be a reference.");
622 return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any));
623}
624
625template <class _ValueType>
626add_pointer_t<_ValueType>
627any_cast(any * __any) _NOEXCEPT
628{
629 using __any_imp::_Action;
630 static_assert(!is_reference<_ValueType>::value,
631 "_ValueType may not be a reference.");
632 typedef typename add_pointer<_ValueType>::type _ReturnType;
633 if (__any && __any->__h) {
634 return static_cast<_ReturnType>(
635 __any->__call(_Action::_Get, nullptr,
636#if !defined(_LIBCPP_NO_RTTI)
637 &typeid(_ValueType),
638#else
639 nullptr,
640#endif
641 __any_imp::__get_fallback_typeid<_ValueType>()
642 ));
643 }
644 return nullptr;
645}
646
647#endif // _LIBCPP_STD_VER > 14
648
649_LIBCPP_END_NAMESPACE_STD
650
651#endif // _LIBCPP_ANY