blob: e6e0b6ea695cf982a5860a5bb905862cdb7b0253 [file] [log] [blame]
Eric Fiseliere739d542016-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
Marshall Clow22381dd2017-04-12 22:51:27 +000048 template <class ValueType, class... Args>
49 decay_t<ValueType>& emplace(Args&&... args);
50 template <class ValueType, class U, class... Args>
51 decay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
Eric Fiseliere739d542016-08-11 03:13:11 +000052 void reset() noexcept;
53 void swap(any& rhs) noexcept;
54
55 // 6.3.4 any observers
56 bool has_value() const noexcept;
57 const type_info& type() const noexcept;
58 };
59
60 // 6.4 Non-member functions
61 void swap(any& x, any& y) noexcept;
62
63 template <class T, class ...Args>
64 any make_any(Args&& ...args);
65 template <class T, class U, class ...Args>
66 any make_any(initializer_list<U>, Args&& ...args);
67
68 template<class ValueType>
69 ValueType any_cast(const any& operand);
70 template<class ValueType>
71 ValueType any_cast(any& operand);
72 template<class ValueType>
73 ValueType any_cast(any&& operand);
74
75 template<class ValueType>
76 const ValueType* any_cast(const any* operand) noexcept;
77 template<class ValueType>
78 ValueType* any_cast(any* operand) noexcept;
79
Eric Fiseliere739d542016-08-11 03:13:11 +000080} // namespace std
81
82*/
83
84#include <experimental/__config>
85#include <memory>
86#include <new>
87#include <typeinfo>
88#include <type_traits>
89#include <cstdlib>
Eric Fiseliere739d542016-08-11 03:13:11 +000090
91#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
92#pragma GCC system_header
93#endif
94
95namespace std {
96class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast
97{
98public:
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
Louis Dionne54238052018-07-11 23:14:33 +0000107_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Marshall Clowe7acb0e2016-08-25 17:47:09 +0000108void __throw_bad_any_cast()
109{
110#ifndef _LIBCPP_NO_EXCEPTIONS
111 throw bad_any_cast();
112#else
Louis Dionne2580fdb2018-08-03 22:36:53 +0000113 _VSTD::abort();
Marshall Clowe7acb0e2016-08-25 17:47:09 +0000114#endif
115}
116
Eric Fiseliere739d542016-08-11 03:13:11 +0000117// Forward declarations
Eric Fiselierc3589a82017-01-04 23:56:00 +0000118class _LIBCPP_TEMPLATE_VIS any;
Eric Fiseliere739d542016-08-11 03:13:11 +0000119
120template <class _ValueType>
121_LIBCPP_INLINE_VISIBILITY
122add_pointer_t<add_const_t<_ValueType>>
123any_cast(any const *) _NOEXCEPT;
124
125template <class _ValueType>
126_LIBCPP_INLINE_VISIBILITY
127add_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT;
128
129namespace __any_imp
130{
131 using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>;
132
133 template <class _Tp>
134 using _IsSmallObject = integral_constant<bool
135 , sizeof(_Tp) <= sizeof(_Buffer)
136 && alignment_of<_Buffer>::value
137 % alignment_of<_Tp>::value == 0
138 && is_nothrow_move_constructible<_Tp>::value
139 >;
140
141 enum class _Action {
142 _Destroy,
143 _Copy,
144 _Move,
145 _Get,
146 _TypeInfo
147 };
148
149 template <class _Tp> struct _SmallHandler;
150 template <class _Tp> struct _LargeHandler;
151
152 template <class _Tp>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000153 struct _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; };
Eric Fiseliere739d542016-08-11 03:13:11 +0000154 template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id;
155
156 template <class _Tp>
157 inline _LIBCPP_INLINE_VISIBILITY
158 constexpr const void* __get_fallback_typeid() {
159 return &__unique_typeinfo<decay_t<_Tp>>::__id;
160 }
161
162 template <class _Tp>
163 inline _LIBCPP_INLINE_VISIBILITY
164 bool __compare_typeid(type_info const* __id, const void* __fallback_id)
165 {
166#if !defined(_LIBCPP_NO_RTTI)
167 if (__id && *__id == typeid(_Tp))
168 return true;
169#endif
170 if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>())
171 return true;
172 return false;
173 }
174
175 template <class _Tp>
176 using _Handler = conditional_t<
177 _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
178
179} // namespace __any_imp
180
Eric Fiselierc3589a82017-01-04 23:56:00 +0000181class _LIBCPP_TEMPLATE_VIS any
Eric Fiseliere739d542016-08-11 03:13:11 +0000182{
183public:
184 // construct/destruct
185 _LIBCPP_INLINE_VISIBILITY
186 constexpr any() _NOEXCEPT : __h(nullptr) {}
187
188 _LIBCPP_INLINE_VISIBILITY
189 any(any const & __other) : __h(nullptr)
190 {
191 if (__other.__h) __other.__call(_Action::_Copy, this);
192 }
193
194 _LIBCPP_INLINE_VISIBILITY
195 any(any && __other) _NOEXCEPT : __h(nullptr)
196 {
197 if (__other.__h) __other.__call(_Action::_Move, this);
198 }
199
200 template <
201 class _ValueType
Eric Fiselier2c429be2016-10-07 21:27:45 +0000202 , class _Tp = decay_t<_ValueType>
Eric Fiseliere739d542016-08-11 03:13:11 +0000203 , class = enable_if_t<
Eric Fiselier2c429be2016-10-07 21:27:45 +0000204 !is_same<_Tp, any>::value &&
Eric Fiselier8d335262016-11-17 19:24:04 +0000205 !__is_inplace_type<_ValueType>::value &&
Eric Fiselier2c429be2016-10-07 21:27:45 +0000206 is_copy_constructible<_Tp>::value>
Eric Fiseliere739d542016-08-11 03:13:11 +0000207 >
208 _LIBCPP_INLINE_VISIBILITY
209 any(_ValueType && __value);
210
Eric Fiselier2c429be2016-10-07 21:27:45 +0000211 template <class _ValueType, class ..._Args,
212 class _Tp = decay_t<_ValueType>,
Eric Fiseliere739d542016-08-11 03:13:11 +0000213 class = enable_if_t<
214 is_constructible<_Tp, _Args...>::value &&
215 is_copy_constructible<_Tp>::value
216 >
217 >
218 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier2c429be2016-10-07 21:27:45 +0000219 explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
Eric Fiseliere739d542016-08-11 03:13:11 +0000220
Eric Fiselier2c429be2016-10-07 21:27:45 +0000221 template <class _ValueType, class _Up, class ..._Args,
222 class _Tp = decay_t<_ValueType>,
Eric Fiseliere739d542016-08-11 03:13:11 +0000223 class = enable_if_t<
224 is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
225 is_copy_constructible<_Tp>::value>
226 >
227 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier2c429be2016-10-07 21:27:45 +0000228 explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
Eric Fiseliere739d542016-08-11 03:13:11 +0000229
230 _LIBCPP_INLINE_VISIBILITY
231 ~any() { this->reset(); }
232
233 // assignments
234 _LIBCPP_INLINE_VISIBILITY
235 any & operator=(any const & __rhs) {
236 any(__rhs).swap(*this);
237 return *this;
238 }
239
240 _LIBCPP_INLINE_VISIBILITY
241 any & operator=(any && __rhs) _NOEXCEPT {
242 any(_VSTD::move(__rhs)).swap(*this);
243 return *this;
244 }
245
Eric Fiseliere739d542016-08-11 03:13:11 +0000246 template <
247 class _ValueType
Eric Fiselier2c429be2016-10-07 21:27:45 +0000248 , class _Tp = decay_t<_ValueType>
Eric Fiseliere739d542016-08-11 03:13:11 +0000249 , class = enable_if_t<
Eric Fiselier2c429be2016-10-07 21:27:45 +0000250 !is_same<_Tp, any>::value
Eric Fiselier846edfb2016-10-16 02:51:50 +0000251 && is_copy_constructible<_Tp>::value>
Eric Fiseliere739d542016-08-11 03:13:11 +0000252 >
253 _LIBCPP_INLINE_VISIBILITY
254 any & operator=(_ValueType && __rhs);
255
Eric Fiselier2c429be2016-10-07 21:27:45 +0000256 template <class _ValueType, class ..._Args,
257 class _Tp = decay_t<_ValueType>,
Eric Fiseliere739d542016-08-11 03:13:11 +0000258 class = enable_if_t<
259 is_constructible<_Tp, _Args...>::value &&
260 is_copy_constructible<_Tp>::value>
261 >
262 _LIBCPP_INLINE_VISIBILITY
Marshall Clow22381dd2017-04-12 22:51:27 +0000263 _Tp& emplace(_Args&&... args);
Eric Fiseliere739d542016-08-11 03:13:11 +0000264
Eric Fiselier2c429be2016-10-07 21:27:45 +0000265 template <class _ValueType, class _Up, class ..._Args,
266 class _Tp = decay_t<_ValueType>,
Eric Fiseliere739d542016-08-11 03:13:11 +0000267 class = enable_if_t<
268 is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
269 is_copy_constructible<_Tp>::value>
270 >
271 _LIBCPP_INLINE_VISIBILITY
Marshall Clow22381dd2017-04-12 22:51:27 +0000272 _Tp& emplace(initializer_list<_Up>, _Args&&...);
Eric Fiseliere739d542016-08-11 03:13:11 +0000273
274 // 6.3.3 any modifiers
275 _LIBCPP_INLINE_VISIBILITY
276 void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); }
277
278 _LIBCPP_INLINE_VISIBILITY
279 void swap(any & __rhs) _NOEXCEPT;
280
281 // 6.3.4 any observers
282 _LIBCPP_INLINE_VISIBILITY
283 bool has_value() const _NOEXCEPT { return __h != nullptr; }
284
285#if !defined(_LIBCPP_NO_RTTI)
286 _LIBCPP_INLINE_VISIBILITY
287 const type_info & type() const _NOEXCEPT {
288 if (__h) {
289 return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo));
290 } else {
291 return typeid(void);
292 }
293 }
294#endif
295
296private:
297 typedef __any_imp::_Action _Action;
298 using _HandleFuncPtr = void* (*)(_Action, any const *, any *, const type_info *,
299 const void* __fallback_info);
300
301 union _Storage {
302 constexpr _Storage() : __ptr(nullptr) {}
303 void * __ptr;
304 __any_imp::_Buffer __buf;
305 };
306
Louis Dionne54238052018-07-11 23:14:33 +0000307 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere739d542016-08-11 03:13:11 +0000308 void * __call(_Action __a, any * __other = nullptr,
309 type_info const * __info = nullptr,
310 const void* __fallback_info = nullptr) const
311 {
312 return __h(__a, this, __other, __info, __fallback_info);
313 }
314
Louis Dionne54238052018-07-11 23:14:33 +0000315 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere739d542016-08-11 03:13:11 +0000316 void * __call(_Action __a, any * __other = nullptr,
317 type_info const * __info = nullptr,
318 const void* __fallback_info = nullptr)
319 {
320 return __h(__a, this, __other, __info, __fallback_info);
321 }
322
323 template <class>
324 friend struct __any_imp::_SmallHandler;
325 template <class>
326 friend struct __any_imp::_LargeHandler;
327
328 template <class _ValueType>
329 friend add_pointer_t<add_const_t<_ValueType>>
330 any_cast(any const *) _NOEXCEPT;
331
332 template <class _ValueType>
333 friend add_pointer_t<_ValueType>
334 any_cast(any *) _NOEXCEPT;
335
336 _HandleFuncPtr __h = nullptr;
337 _Storage __s;
338};
339
340namespace __any_imp
341{
342 template <class _Tp>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000343 struct _LIBCPP_TEMPLATE_VIS _SmallHandler
Eric Fiseliere739d542016-08-11 03:13:11 +0000344 {
345 _LIBCPP_INLINE_VISIBILITY
346 static void* __handle(_Action __act, any const * __this, any * __other,
347 type_info const * __info, const void* __fallback_info)
348 {
349 switch (__act)
350 {
351 case _Action::_Destroy:
352 __destroy(const_cast<any &>(*__this));
353 return nullptr;
354 case _Action::_Copy:
355 __copy(*__this, *__other);
356 return nullptr;
357 case _Action::_Move:
358 __move(const_cast<any &>(*__this), *__other);
359 return nullptr;
360 case _Action::_Get:
361 return __get(const_cast<any &>(*__this), __info, __fallback_info);
362 case _Action::_TypeInfo:
363 return __type_info();
364 }
365 }
366
367 template <class ..._Args>
368 _LIBCPP_INLINE_VISIBILITY
Marshall Clow22381dd2017-04-12 22:51:27 +0000369 static _Tp& __create(any & __dest, _Args&&... __args) {
370 _Tp* __ret = ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...);
Eric Fiseliere739d542016-08-11 03:13:11 +0000371 __dest.__h = &_SmallHandler::__handle;
Marshall Clow22381dd2017-04-12 22:51:27 +0000372 return *__ret;
Eric Fiseliere739d542016-08-11 03:13:11 +0000373 }
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>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000418 struct _LIBCPP_TEMPLATE_VIS _LargeHandler
Eric Fiseliere739d542016-08-11 03:13:11 +0000419 {
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
Marshall Clow22381dd2017-04-12 22:51:27 +0000445 static _Tp& __create(any & __dest, _Args&&... __args) {
Eric Fiseliere739d542016-08-11 03:13:11 +0000446 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));
Marshall Clow22381dd2017-04-12 22:51:27 +0000450 _Tp* __ret = ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...);
Eric Fiseliere739d542016-08-11 03:13:11 +0000451 __dest.__s.__ptr = __hold.release();
452 __dest.__h = &_LargeHandler::__handle;
Marshall Clow22381dd2017-04-12 22:51:27 +0000453 return *__ret;
Eric Fiseliere739d542016-08-11 03:13:11 +0000454 }
455
456 private:
457
458 _LIBCPP_INLINE_VISIBILITY
459 static void __destroy(any & __this){
460 delete static_cast<_Tp*>(__this.__s.__ptr);
461 __this.__h = nullptr;
462 }
463
464 _LIBCPP_INLINE_VISIBILITY
465 static void __copy(any const & __this, any & __dest) {
466 _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr));
467 }
468
469 _LIBCPP_INLINE_VISIBILITY
470 static void __move(any & __this, any & __dest) {
471 __dest.__s.__ptr = __this.__s.__ptr;
472 __dest.__h = &_LargeHandler::__handle;
473 __this.__h = nullptr;
474 }
475
476 _LIBCPP_INLINE_VISIBILITY
477 static void* __get(any & __this, type_info const * __info,
478 void const* __fallback_info)
479 {
480 if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
481 return static_cast<void*>(__this.__s.__ptr);
482 return nullptr;
483
484 }
485
486 _LIBCPP_INLINE_VISIBILITY
487 static void* __type_info()
488 {
489#if !defined(_LIBCPP_NO_RTTI)
490 return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
491#else
492 return nullptr;
493#endif
494 }
495 };
496
497} // namespace __any_imp
498
499
Eric Fiselier2c429be2016-10-07 21:27:45 +0000500template <class _ValueType, class _Tp, class>
Eric Fiseliere739d542016-08-11 03:13:11 +0000501any::any(_ValueType && __v) : __h(nullptr)
502{
Eric Fiselier2c429be2016-10-07 21:27:45 +0000503 __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v));
Eric Fiseliere739d542016-08-11 03:13:11 +0000504}
505
Eric Fiselier2c429be2016-10-07 21:27:45 +0000506template <class _ValueType, class ..._Args, class _Tp, class>
507any::any(in_place_type_t<_ValueType>, _Args&&... __args) {
508 __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
Eric Fiseliere739d542016-08-11 03:13:11 +0000509};
510
Eric Fiselier2c429be2016-10-07 21:27:45 +0000511template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
512any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
513 __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
Eric Fiseliere739d542016-08-11 03:13:11 +0000514}
515
Eric Fiselier2c429be2016-10-07 21:27:45 +0000516template <class _ValueType, class, class>
Eric Fiseliere739d542016-08-11 03:13:11 +0000517inline _LIBCPP_INLINE_VISIBILITY
518any & any::operator=(_ValueType && __v)
519{
Eric Fiseliere739d542016-08-11 03:13:11 +0000520 any(_VSTD::forward<_ValueType>(__v)).swap(*this);
521 return *this;
522}
523
Eric Fiselier2c429be2016-10-07 21:27:45 +0000524template <class _ValueType, class ..._Args, class _Tp, class>
Eric Fiseliere739d542016-08-11 03:13:11 +0000525inline _LIBCPP_INLINE_VISIBILITY
Marshall Clow22381dd2017-04-12 22:51:27 +0000526_Tp& any::emplace(_Args&&... __args) {
Eric Fiseliere739d542016-08-11 03:13:11 +0000527 reset();
Marshall Clow22381dd2017-04-12 22:51:27 +0000528 return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
Eric Fiseliere739d542016-08-11 03:13:11 +0000529}
530
Eric Fiselier2c429be2016-10-07 21:27:45 +0000531template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
Eric Fiseliere739d542016-08-11 03:13:11 +0000532inline _LIBCPP_INLINE_VISIBILITY
Marshall Clow22381dd2017-04-12 22:51:27 +0000533_Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
Eric Fiseliere739d542016-08-11 03:13:11 +0000534 reset();
Marshall Clow22381dd2017-04-12 22:51:27 +0000535 return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
Eric Fiseliere739d542016-08-11 03:13:11 +0000536}
537
538inline _LIBCPP_INLINE_VISIBILITY
539void any::swap(any & __rhs) _NOEXCEPT
540{
Eric Fiselier2c429be2016-10-07 21:27:45 +0000541 if (this == &__rhs)
542 return;
Eric Fiseliere739d542016-08-11 03:13:11 +0000543 if (__h && __rhs.__h) {
544 any __tmp;
545 __rhs.__call(_Action::_Move, &__tmp);
546 this->__call(_Action::_Move, &__rhs);
547 __tmp.__call(_Action::_Move, this);
548 }
549 else if (__h) {
550 this->__call(_Action::_Move, &__rhs);
551 }
552 else if (__rhs.__h) {
553 __rhs.__call(_Action::_Move, this);
554 }
555}
556
557// 6.4 Non-member functions
558
559inline _LIBCPP_INLINE_VISIBILITY
560void swap(any & __lhs, any & __rhs) _NOEXCEPT
561{
562 __lhs.swap(__rhs);
563}
564
565template <class _Tp, class ..._Args>
566inline _LIBCPP_INLINE_VISIBILITY
567any make_any(_Args&&... __args) {
Eric Fiselier8d335262016-11-17 19:24:04 +0000568 return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...);
Eric Fiseliere739d542016-08-11 03:13:11 +0000569}
570
571template <class _Tp, class _Up, class ..._Args>
572inline _LIBCPP_INLINE_VISIBILITY
573any make_any(initializer_list<_Up> __il, _Args&&... __args) {
Eric Fiselier8d335262016-11-17 19:24:04 +0000574 return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...);
Eric Fiseliere739d542016-08-11 03:13:11 +0000575}
576
577template <class _ValueType>
578inline _LIBCPP_INLINE_VISIBILITY
579_ValueType any_cast(any const & __v)
580{
Eric Fiselier2c429be2016-10-07 21:27:45 +0000581 using _RawValueType = __uncvref_t<_ValueType>;
582 static_assert(is_constructible<_ValueType, _RawValueType const &>::value,
Eric Fiselier100a39d2016-10-16 01:43:43 +0000583 "ValueType is required to be a const lvalue reference "
584 "or a CopyConstructible type");
Eric Fiselier2c429be2016-10-07 21:27:45 +0000585 auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v);
Eric Fiseliere739d542016-08-11 03:13:11 +0000586 if (__tmp == nullptr)
Marshall Clowe7acb0e2016-08-25 17:47:09 +0000587 __throw_bad_any_cast();
Eric Fiselier2c429be2016-10-07 21:27:45 +0000588 return static_cast<_ValueType>(*__tmp);
Eric Fiseliere739d542016-08-11 03:13:11 +0000589}
590
591template <class _ValueType>
592inline _LIBCPP_INLINE_VISIBILITY
593_ValueType any_cast(any & __v)
594{
Eric Fiselier2c429be2016-10-07 21:27:45 +0000595 using _RawValueType = __uncvref_t<_ValueType>;
596 static_assert(is_constructible<_ValueType, _RawValueType &>::value,
Eric Fiselier100a39d2016-10-16 01:43:43 +0000597 "ValueType is required to be an lvalue reference "
598 "or a CopyConstructible type");
Eric Fiselier2c429be2016-10-07 21:27:45 +0000599 auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
Eric Fiseliere739d542016-08-11 03:13:11 +0000600 if (__tmp == nullptr)
Marshall Clowe7acb0e2016-08-25 17:47:09 +0000601 __throw_bad_any_cast();
Eric Fiselier2c429be2016-10-07 21:27:45 +0000602 return static_cast<_ValueType>(*__tmp);
Eric Fiseliere739d542016-08-11 03:13:11 +0000603}
604
605template <class _ValueType>
606inline _LIBCPP_INLINE_VISIBILITY
607_ValueType any_cast(any && __v)
608{
Eric Fiselier2c429be2016-10-07 21:27:45 +0000609 using _RawValueType = __uncvref_t<_ValueType>;
610 static_assert(is_constructible<_ValueType, _RawValueType>::value,
Eric Fiselier100a39d2016-10-16 01:43:43 +0000611 "ValueType is required to be an rvalue reference "
612 "or a CopyConstructible type");
Eric Fiselier2c429be2016-10-07 21:27:45 +0000613 auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
Eric Fiseliere739d542016-08-11 03:13:11 +0000614 if (__tmp == nullptr)
Marshall Clowe7acb0e2016-08-25 17:47:09 +0000615 __throw_bad_any_cast();
Eric Fiselier2c429be2016-10-07 21:27:45 +0000616 return static_cast<_ValueType>(_VSTD::move(*__tmp));
Eric Fiseliere739d542016-08-11 03:13:11 +0000617}
618
619template <class _ValueType>
620inline _LIBCPP_INLINE_VISIBILITY
621add_pointer_t<add_const_t<_ValueType>>
622any_cast(any const * __any) _NOEXCEPT
623{
624 static_assert(!is_reference<_ValueType>::value,
625 "_ValueType may not be a reference.");
626 return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any));
627}
628
Eric Fiselier4035b662016-10-16 11:56:38 +0000629template <class _RetType>
630inline _LIBCPP_INLINE_VISIBILITY
631_RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept {
632 return static_cast<_RetType>(__p);
633}
634
635template <class _RetType>
636inline _LIBCPP_INLINE_VISIBILITY
637_RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept {
638 return nullptr;
639}
640
Eric Fiseliere739d542016-08-11 03:13:11 +0000641template <class _ValueType>
642add_pointer_t<_ValueType>
643any_cast(any * __any) _NOEXCEPT
644{
645 using __any_imp::_Action;
646 static_assert(!is_reference<_ValueType>::value,
647 "_ValueType may not be a reference.");
648 typedef typename add_pointer<_ValueType>::type _ReturnType;
649 if (__any && __any->__h) {
Eric Fiselier4035b662016-10-16 11:56:38 +0000650 void *__p = __any->__call(_Action::_Get, nullptr,
Eric Fiseliere739d542016-08-11 03:13:11 +0000651#if !defined(_LIBCPP_NO_RTTI)
652 &typeid(_ValueType),
653#else
654 nullptr,
655#endif
Eric Fiselier4035b662016-10-16 11:56:38 +0000656 __any_imp::__get_fallback_typeid<_ValueType>());
657 return _VSTD::__pointer_or_func_cast<_ReturnType>(
658 __p, is_function<_ValueType>{});
Eric Fiseliere739d542016-08-11 03:13:11 +0000659 }
660 return nullptr;
661}
662
663#endif // _LIBCPP_STD_VER > 14
664
665_LIBCPP_END_NAMESPACE_STD
666
667#endif // _LIBCPP_ANY