30 #ifndef _GLIBCXX_EXPERIMENTAL_ANY
31 #define _GLIBCXX_EXPERIMENTAL_ANY 1
33 #pragma GCC system_header
35 #if __cplusplus >= 201402L
43 namespace std _GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
47 namespace experimental
49 inline namespace fundamentals_v1
61 #define __cpp_lib_experimental_any 201411
70 virtual const char*
what() const noexcept {
return "bad any_cast"; }
74 [[gnu::noreturn]]
inline void __throw_bad_any_cast()
99 _Storage(
const _Storage&) =
delete;
100 _Storage&
operator=(
const _Storage&) =
delete;
106 template<
typename _Tp,
typename _Safe = is_nothrow_move_constructible<_Tp>,
107 bool _Fits = (sizeof(_Tp) <= sizeof(_Storage))
108 && (alignof(_Tp) <= alignof(_Storage))>
109 using _Internal = std::
integral_constant<
bool, _Safe::value && _Fits>;
111 template<
typename _Tp>
112 struct _Manager_internal;
114 template<
typename _Tp>
115 struct _Manager_external;
117 template<
typename _Tp>
119 _Manager_internal<_Tp>,
120 _Manager_external<_Tp>>;
122 template<
typename _Tp,
typename _Decayed = decay_t<_Tp>>
129 any() noexcept : _M_manager(
nullptr) { }
135 _M_manager =
nullptr;
140 __other._M_manager(_Op_clone, &__other, &__arg);
152 _M_manager =
nullptr;
157 __other._M_manager(_Op_xfer, &__other, &__arg);
162 template <
typename _ValueType,
typename _Tp = _Decay<_ValueType>,
163 typename _Mgr = _Manager<_Tp>,
164 typename enable_if<is_constructible<_Tp, _ValueType&&>::value,
167 : _M_manager(&_Mgr::_S_manage)
169 _Mgr::_S_create(_M_storage, std::forward<_ValueType>(__value));
171 "The contained object must be CopyConstructible");
175 template <
typename _ValueType,
typename _Tp = _Decay<_ValueType>,
176 typename _Mgr = _Manager<_Tp>,
177 typename enable_if<!is_constructible<_Tp, _ValueType&&>::value,
180 : _M_manager(&_Mgr::_S_manage)
182 _Mgr::_S_create(_M_storage, __value);
184 "The contained object must be CopyConstructible");
208 else if (
this != &__rhs)
213 __rhs._M_manager(_Op_xfer, &__rhs, &__arg);
219 template<
typename _ValueType>
223 *
this =
any(std::forward<_ValueType>(__rhs));
234 _M_manager(_Op_destroy,
this,
nullptr);
235 _M_manager =
nullptr;
242 if (
empty() && __rhs.empty())
245 if (!
empty() && !__rhs.empty())
252 __arg._M_any = &__tmp;
253 __rhs._M_manager(_Op_xfer, &__rhs, &__arg);
254 __arg._M_any = &__rhs;
255 _M_manager(_Op_xfer,
this, &__arg);
257 __tmp._M_manager(_Op_xfer, &__tmp, &__arg);
261 any* __empty =
empty() ?
this : &__rhs;
262 any* __full =
empty() ? &__rhs :
this;
264 __arg._M_any = __empty;
265 __full->_M_manager(_Op_xfer, __full, &__arg);
272 _GLIBCXX_NODISCARD
bool empty() const noexcept {
return _M_manager ==
nullptr; }
281 _M_manager(_Op_get_type_info,
this, &__arg);
282 return *__arg._M_typeinfo;
286 template<
typename _Tp>
287 static constexpr
bool __is_valid_cast()
292 _Op_access, _Op_get_type_info, _Op_clone, _Op_destroy, _Op_xfer
302 void (*_M_manager)(_Op,
const any*, _Arg*);
305 template<
typename _Tp>
306 friend enable_if_t<is_object<_Tp>::value,
void*>
307 __any_caster(
const any* __any);
310 template<
typename _Tp>
311 struct _Manager_internal
314 _S_manage(_Op __which,
const any* __anyp, _Arg* __arg);
316 template<
typename _Up>
318 _S_create(_Storage& __storage, _Up&& __value)
320 void* __addr = &__storage._M_buffer;
321 ::new (__addr) _Tp(std::
forward<_Up>(__value));
326 template<typename _Tp>
327 struct _Manager_external
330 _S_manage(_Op __which,
const any* __anyp, _Arg* __arg);
332 template<
typename _Up>
334 _S_create(_Storage& __storage, _Up&& __value)
336 __storage._M_ptr =
new _Tp(std::forward<_Up>(__value));
342 inline void swap(
any& __x,
any& __y) noexcept { __x.swap(__y); }
354 template<
typename _ValueType>
357 static_assert(any::__is_valid_cast<_ValueType>(),
358 "Template argument must be a reference or CopyConstructible type");
362 __throw_bad_any_cast();
377 template<
typename _ValueType>
380 static_assert(any::__is_valid_cast<_ValueType>(),
381 "Template argument must be a reference or CopyConstructible type");
385 __throw_bad_any_cast();
388 template<
typename _ValueType,
394 static_assert(any::__is_valid_cast<_ValueType>(),
395 "Template argument must be a reference or CopyConstructible type");
399 __throw_bad_any_cast();
402 template<
typename _ValueType,
408 static_assert(any::__is_valid_cast<_ValueType>(),
409 "Template argument must be a reference or CopyConstructible type");
413 __throw_bad_any_cast();
418 template<
typename _Tp>
420 __any_caster(
const any* __any)
436 if (__any->_M_manager == &any::_Manager<_Vp>::_S_manage
438 || __any->type() ==
typeid(_Tp)
443 __any->_M_manager(any::_Op_access, __any, &__arg);
450 template<
typename _Tp>
451 enable_if_t<!is_object<_Tp>::value, _Tp*>
452 __any_caster(
const any*) noexcept
467 template<
typename _ValueType>
471 return static_cast<_ValueType*
>(__any_caster<_ValueType>(__any));
475 template<
typename _ValueType>
479 return static_cast<_ValueType*
>(__any_caster<_ValueType>(__any));
484 template<
typename _Tp>
486 any::_Manager_internal<_Tp>::
487 _S_manage(_Op __which,
const any* __any, _Arg* __arg)
490 auto __ptr =
reinterpret_cast<const _Tp*
>(&__any->_M_storage._M_buffer);
494 __arg->_M_obj =
const_cast<_Tp*
>(__ptr);
496 case _Op_get_type_info:
498 __arg->_M_typeinfo = &
typeid(_Tp);
502 ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr);
503 __arg->_M_any->_M_manager = __any->_M_manager;
509 ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp
510 (std::
move(*const_cast<_Tp*>(__ptr)));
512 __arg->_M_any->_M_manager = __any->_M_manager;
513 const_cast<
any*>(__any)->_M_manager =
nullptr;
518 template<typename _Tp>
520 any::_Manager_external<_Tp>::
521 _S_manage(_Op __which, const
any* __any, _Arg* __arg)
524 auto __ptr =
static_cast<const _Tp*
>(__any->_M_storage._M_ptr);
528 __arg->_M_obj =
const_cast<_Tp*
>(__ptr);
530 case _Op_get_type_info:
532 __arg->_M_typeinfo = &
typeid(_Tp);
536 __arg->_M_any->_M_storage._M_ptr =
new _Tp(*__ptr);
537 __arg->_M_any->_M_manager = __any->_M_manager;
543 __arg->_M_any->_M_storage._M_ptr = __any->_M_storage._M_ptr;
544 __arg->_M_any->_M_manager = __any->_M_manager;
545 const_cast<any*
>(__any)->_M_manager =
nullptr;
552 struct any::_Manager_internal<
any::_Op>
555 _S_manage(_Op,
const any*, _Arg*) { }
562 _GLIBCXX_END_NAMESPACE_VERSION
567 #endif // _GLIBCXX_EXPERIMENTAL_ANY
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
bool empty() const noexcept
Reports whether there is a contained object or not.
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
enable_if_t<!is_same< any, decay_t< _ValueType > >::value, any & > operator=(_ValueType &&__rhs)
Store a copy of __rhs as the contained object.
typename remove_cv< _Tp >::type remove_cv_t
Alias template for remove_cv.
virtual const char * what() const noexcept
any() noexcept
Default constructor, creates an empty object.
any & operator=(any &&__rhs) noexcept
Move assignment operator.
Exception class thrown by a failed any_cast.
_ValueType any_cast(const any &__any)
Access the contained object.
Define a member typedef type only if a boolean constant is true.
any & operator=(const any &__rhs)
Copy the state of another object.
typename remove_reference< _Tp >::type remove_reference_t
Alias template for remove_reference.
any(const any &__other)
Copy constructor, copies the state of __other.
typename add_const< _Tp >::type add_const_t
Alias template for add_const.
~any()
Destructor, calls clear()
A type-safe container of any type.
any(_ValueType &&__value)
Construct with a copy of __value as the contained object.
any(any &&__other) noexcept
Move constructor, transfer the state from __other.
typename conditional< _Cond, _Iftrue, _Iffalse >::type conditional_t
Alias template for conditional.
void swap(any &__rhs) noexcept
Exchange state with another object.
const type_info & type() const noexcept
The typeid of the contained object, or typeid(void) if empty.
void clear() noexcept
If not empty, destroy the contained object.
Thrown during incorrect typecasting.If you attempt an invalid dynamic_cast expression, an instance of this class (or something derived from this class) is thrown.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.