29 #ifndef _GLIBCXX_EXPERIMENTAL_ANY
30 #define _GLIBCXX_EXPERIMENTAL_ANY 1
32 #pragma GCC system_header
34 #if __cplusplus <= 201103L
44 namespace std _GLIBCXX_VISIBILITY(default)
46 namespace experimental
48 inline namespace fundamentals_v1
50 _GLIBCXX_BEGIN_NAMESPACE_VERSION
62 #define __cpp_lib_experimental_any 201411
71 virtual const char*
what() const noexcept {
return "bad any_cast"; }
74 [[gnu::noreturn]]
inline void __throw_bad_any_cast()
98 _Storage(
const _Storage&) =
delete;
99 _Storage&
operator=(
const _Storage&) =
delete;
102 aligned_storage<sizeof(_M_ptr), alignof(void*)>::type _M_buffer;
105 template<
typename _Tp,
typename _Safe = is_nothrow_move_constructible<_Tp>,
106 bool _Fits = (sizeof(_Tp) <= sizeof(_Storage))
107 && (alignof(_Tp) <= alignof(_Storage))>
108 using _Internal = std::
integral_constant<
bool, _Safe::value && _Fits>;
110 template<
typename _Tp>
111 struct _Manager_internal;
113 template<
typename _Tp>
114 struct _Manager_external;
116 template<
typename _Tp>
117 using _Manager = conditional_t<_Internal<_Tp>::value,
118 _Manager_internal<_Tp>,
119 _Manager_external<_Tp>>;
121 template<
typename _Tp,
typename _Decayed = decay_t<_Tp>>
122 using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>;
128 any() noexcept : _M_manager(
nullptr) { }
134 _M_manager =
nullptr;
139 __other._M_manager(_Op_clone, &__other, &__arg);
151 _M_manager =
nullptr;
156 __other._M_manager(_Op_xfer, &__other, &__arg);
161 template <
typename _ValueType,
typename _Tp = _Decay<_ValueType>,
162 typename _Mgr = _Manager<_Tp>,
163 typename enable_if<is_constructible<_Tp, _ValueType&&>::value,
166 : _M_manager(&_Mgr::_S_manage)
168 _Mgr::_S_create(_M_storage, std::forward<_ValueType>(__value));
169 static_assert(is_copy_constructible<_Tp>::value,
170 "The contained object must be CopyConstructible");
174 template <
typename _ValueType,
typename _Tp = _Decay<_ValueType>,
175 typename _Mgr = _Manager<_Tp>,
176 typename enable_if<!is_constructible<_Tp, _ValueType&&>::value,
179 : _M_manager(&_Mgr::_S_manage)
181 _Mgr::_S_create(_M_storage, __value);
182 static_assert(is_copy_constructible<_Tp>::value,
183 "The contained object must be CopyConstructible");
207 else if (
this != &__rhs)
212 __rhs._M_manager(_Op_xfer, &__rhs, &__arg);
218 template<
typename _ValueType>
219 enable_if_t<!is_same<any, decay_t<_ValueType>>::value,
any&>
222 *
this =
any(std::forward<_ValueType>(__rhs));
233 _M_manager(_Op_destroy,
this,
nullptr);
234 _M_manager =
nullptr;
241 if (
empty() && __rhs.empty())
244 if (!
empty() && !__rhs.empty())
251 __arg._M_any = &__tmp;
252 __rhs._M_manager(_Op_xfer, &__rhs, &__arg);
253 __arg._M_any = &__rhs;
254 _M_manager(_Op_xfer,
this, &__arg);
256 __tmp._M_manager(_Op_xfer, &__tmp, &__arg);
260 any* __empty =
empty() ?
this : &__rhs;
261 any* __full =
empty() ? &__rhs :
this;
263 __arg._M_any = __empty;
264 __full->_M_manager(_Op_xfer, __full, &__arg);
271 bool empty() const noexcept {
return _M_manager ==
nullptr; }
280 _M_manager(_Op_get_type_info,
this, &__arg);
281 return *__arg._M_typeinfo;
285 template<
typename _Tp>
286 static constexpr
bool __is_valid_cast()
287 {
return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; }
291 _Op_access, _Op_get_type_info, _Op_clone, _Op_destroy, _Op_xfer
301 void (*_M_manager)(_Op,
const any*, _Arg*);
304 template<
typename _Tp>
305 friend void* __any_caster(
const any* __any);
308 template<
typename _Tp>
309 struct _Manager_internal
312 _S_manage(_Op __which,
const any* __anyp, _Arg* __arg);
314 template<
typename _Up>
316 _S_create(_Storage& __storage, _Up&& __value)
318 void* __addr = &__storage._M_buffer;
319 ::new (__addr) _Tp(std::
forward<_Up>(__value));
324 template<typename _Tp>
325 struct _Manager_external
328 _S_manage(_Op __which,
const any* __anyp, _Arg* __arg);
330 template<
typename _Up>
332 _S_create(_Storage& __storage, _Up&& __value)
334 __storage._M_ptr =
new _Tp(std::forward<_Up>(__value));
340 inline void swap(
any& __x,
any& __y) noexcept { __x.swap(__y); }
352 template<
typename _ValueType>
355 static_assert(any::__is_valid_cast<_ValueType>(),
356 "Template argument must be a reference or CopyConstructible type");
357 auto __p =
any_cast<add_const_t<remove_reference_t<_ValueType>>>(&__any);
360 __throw_bad_any_cast();
375 template<
typename _ValueType>
378 static_assert(any::__is_valid_cast<_ValueType>(),
379 "Template argument must be a reference or CopyConstructible type");
380 auto __p =
any_cast<remove_reference_t<_ValueType>>(&__any);
383 __throw_bad_any_cast();
386 template<
typename _ValueType,
387 typename enable_if<!is_move_constructible<_ValueType>::value
392 static_assert(any::__is_valid_cast<_ValueType>(),
393 "Template argument must be a reference or CopyConstructible type");
394 auto __p =
any_cast<remove_reference_t<_ValueType>>(&__any);
397 __throw_bad_any_cast();
400 template<
typename _ValueType,
401 typename enable_if<is_move_constructible<_ValueType>::value
406 static_assert(any::__is_valid_cast<_ValueType>(),
407 "Template argument must be a reference or CopyConstructible type");
408 auto __p =
any_cast<remove_reference_t<_ValueType>>(&__any);
410 return std::move(*__p);
411 __throw_bad_any_cast();
415 template<
typename _Tp>
416 void* __any_caster(
const any* __any)
419 using _Up = decay_t<_Tp>;
420 using _Vp = conditional_t<is_copy_constructible<_Up>::value, _Up, _None>;
421 if (__any->_M_manager != &any::_Manager<_Vp>::_S_manage)
424 __any->_M_manager(any::_Op_access, __any, &__arg);
439 template<
typename _ValueType>
443 return static_cast<_ValueType*
>(__any_caster<_ValueType>(__any));
447 template<
typename _ValueType>
451 return static_cast<_ValueType*
>(__any_caster<_ValueType>(__any));
456 template<
typename _Tp>
458 any::_Manager_internal<_Tp>::
459 _S_manage(_Op __which,
const any* __any, _Arg* __arg)
462 auto __ptr =
reinterpret_cast<const _Tp*
>(&__any->_M_storage._M_buffer);
466 __arg->_M_obj =
const_cast<_Tp*
>(__ptr);
468 case _Op_get_type_info:
470 __arg->_M_typeinfo = &
typeid(_Tp);
474 ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr);
475 __arg->_M_any->_M_manager = __any->_M_manager;
481 ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp
482 (std::move(*const_cast<_Tp*>(__ptr)));
484 __arg->_M_any->_M_manager = __any->_M_manager;
485 const_cast<
any*>(__any)->_M_manager =
nullptr;
490 template<typename _Tp>
492 any::_Manager_external<_Tp>::
493 _S_manage(_Op __which, const
any* __any, _Arg* __arg)
496 auto __ptr =
static_cast<const _Tp*
>(__any->_M_storage._M_ptr);
500 __arg->_M_obj =
const_cast<_Tp*
>(__ptr);
502 case _Op_get_type_info:
504 __arg->_M_typeinfo = &
typeid(_Tp);
508 __arg->_M_any->_M_storage._M_ptr =
new _Tp(*__ptr);
509 __arg->_M_any->_M_manager = __any->_M_manager;
515 __arg->_M_any->_M_storage._M_ptr = __any->_M_storage._M_ptr;
516 __arg->_M_any->_M_manager = __any->_M_manager;
517 const_cast<any*
>(__any)->_M_manager =
nullptr;
523 _GLIBCXX_END_NAMESPACE_VERSION
530 #endif // _GLIBCXX_EXPERIMENTAL_ANY
bool empty() const noexcept
Reports whether there is a contained object or not.
void swap(any &__rhs) noexcept
Exchange state with another object.
A type-safe container of any type.
any(_ValueType &&__value)
Construct with a copy of __value as 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.
any(any &&__other) noexcept
Move constructor, transfer the state from __other.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
virtual const char * what() const noexcept
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.
any() noexcept
Default constructor, creates an empty object.
any(const any &__other)
Copy constructor, copies the state of __other.
_ValueType any_cast(const any &__any)
Access the contained object.
enable_if_t<!is_same< any, decay_t< _ValueType > >::value, any & > operator=(_ValueType &&__rhs)
Store a copy of __rhs as the contained object.
any & operator=(const any &__rhs)
Copy the state of another object.
Exception class thrown by a failed any_cast.
~any()
Destructor, calls clear()
any & operator=(any &&__rhs) noexcept
Move assignment operator.