1 1.1 mrg // <experimental/any> -*- C++ -*- 2 1.1 mrg 3 1.7 mrg // Copyright (C) 2014-2022 Free Software Foundation, Inc. 4 1.1 mrg // 5 1.1 mrg // This file is part of the GNU ISO C++ Library. This library is free 6 1.1 mrg // software; you can redistribute it and/or modify it under the 7 1.1 mrg // terms of the GNU General Public License as published by the 8 1.1 mrg // Free Software Foundation; either version 3, or (at your option) 9 1.1 mrg // any later version. 10 1.1 mrg 11 1.1 mrg // This library is distributed in the hope that it will be useful, 12 1.1 mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 mrg // GNU General Public License for more details. 15 1.1 mrg 16 1.1 mrg // Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg // permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg // 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg // You should have received a copy of the GNU General Public License and 21 1.1 mrg // a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg // <http://www.gnu.org/licenses/>. 24 1.1 mrg 25 1.1 mrg /** @file experimental/any 26 1.1 mrg * This is a TS C++ Library header. 27 1.6 mrg * @ingroup libfund-ts 28 1.1 mrg */ 29 1.1 mrg 30 1.1 mrg #ifndef _GLIBCXX_EXPERIMENTAL_ANY 31 1.1 mrg #define _GLIBCXX_EXPERIMENTAL_ANY 1 32 1.1 mrg 33 1.1 mrg #pragma GCC system_header 34 1.1 mrg 35 1.3 mrg #if __cplusplus >= 201402L 36 1.1 mrg 37 1.1 mrg #include <typeinfo> 38 1.1 mrg #include <new> 39 1.1 mrg #include <type_traits> 40 1.7 mrg #include <bits/move.h> 41 1.3 mrg #include <experimental/bits/lfts_config.h> 42 1.1 mrg 43 1.1 mrg namespace std _GLIBCXX_VISIBILITY(default) 44 1.1 mrg { 45 1.4 mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 46 1.4 mrg 47 1.1 mrg namespace experimental 48 1.1 mrg { 49 1.1 mrg inline namespace fundamentals_v1 50 1.1 mrg { 51 1.1 mrg /** 52 1.1 mrg * @defgroup any Type-safe container of any type 53 1.6 mrg * @ingroup libfund-ts 54 1.1 mrg * 55 1.1 mrg * A type-safe container for single values of value types, as 56 1.1 mrg * described in n3804 "Any Library Proposal (Revision 3)". 57 1.1 mrg * 58 1.1 mrg * @{ 59 1.1 mrg */ 60 1.1 mrg 61 1.1 mrg #define __cpp_lib_experimental_any 201411 62 1.1 mrg 63 1.1 mrg /** 64 1.1 mrg * @brief Exception class thrown by a failed @c any_cast 65 1.1 mrg * @ingroup exceptions 66 1.1 mrg */ 67 1.1 mrg class bad_any_cast : public bad_cast 68 1.1 mrg { 69 1.1 mrg public: 70 1.1 mrg virtual const char* what() const noexcept { return "bad any_cast"; } 71 1.1 mrg }; 72 1.1 mrg 73 1.6 mrg /// @cond undocumented 74 1.1 mrg [[gnu::noreturn]] inline void __throw_bad_any_cast() 75 1.1 mrg { 76 1.1 mrg #if __cpp_exceptions 77 1.1 mrg throw bad_any_cast{}; 78 1.1 mrg #else 79 1.1 mrg __builtin_abort(); 80 1.1 mrg #endif 81 1.1 mrg } 82 1.6 mrg /// @endcond 83 1.1 mrg 84 1.1 mrg /** 85 1.1 mrg * @brief A type-safe container of any type. 86 1.1 mrg * 87 1.1 mrg * An @c any object's state is either empty or it stores a contained object 88 1.1 mrg * of CopyConstructible type. 89 1.1 mrg */ 90 1.1 mrg class any 91 1.1 mrg { 92 1.1 mrg // Holds either pointer to a heap object or the contained object itself. 93 1.1 mrg union _Storage 94 1.1 mrg { 95 1.3 mrg // This constructor intentionally doesn't initialize anything. 96 1.3 mrg _Storage() = default; 97 1.3 mrg 98 1.3 mrg // Prevent trivial copies of this type, buffer might hold a non-POD. 99 1.3 mrg _Storage(const _Storage&) = delete; 100 1.3 mrg _Storage& operator=(const _Storage&) = delete; 101 1.3 mrg 102 1.1 mrg void* _M_ptr; 103 1.3 mrg aligned_storage<sizeof(_M_ptr), alignof(void*)>::type _M_buffer; 104 1.1 mrg }; 105 1.1 mrg 106 1.3 mrg template<typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>, 107 1.3 mrg bool _Fits = (sizeof(_Tp) <= sizeof(_Storage)) 108 1.3 mrg && (alignof(_Tp) <= alignof(_Storage))> 109 1.1 mrg using _Internal = std::integral_constant<bool, _Safe::value && _Fits>; 110 1.1 mrg 111 1.1 mrg template<typename _Tp> 112 1.1 mrg struct _Manager_internal; // uses small-object optimization 113 1.1 mrg 114 1.1 mrg template<typename _Tp> 115 1.1 mrg struct _Manager_external; // creates contained object on the heap 116 1.1 mrg 117 1.1 mrg template<typename _Tp> 118 1.7 mrg using _Manager = __conditional_t<_Internal<_Tp>::value, 119 1.7 mrg _Manager_internal<_Tp>, 120 1.7 mrg _Manager_external<_Tp>>; 121 1.1 mrg 122 1.1 mrg template<typename _Tp, typename _Decayed = decay_t<_Tp>> 123 1.1 mrg using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>; 124 1.1 mrg 125 1.1 mrg public: 126 1.1 mrg // construct/destruct 127 1.1 mrg 128 1.1 mrg /// Default constructor, creates an empty object. 129 1.1 mrg any() noexcept : _M_manager(nullptr) { } 130 1.1 mrg 131 1.1 mrg /// Copy constructor, copies the state of @p __other 132 1.3 mrg any(const any& __other) 133 1.1 mrg { 134 1.3 mrg if (__other.empty()) 135 1.3 mrg _M_manager = nullptr; 136 1.3 mrg else 137 1.1 mrg { 138 1.1 mrg _Arg __arg; 139 1.1 mrg __arg._M_any = this; 140 1.3 mrg __other._M_manager(_Op_clone, &__other, &__arg); 141 1.1 mrg } 142 1.1 mrg } 143 1.1 mrg 144 1.1 mrg /** 145 1.1 mrg * @brief Move constructor, transfer the state from @p __other 146 1.1 mrg * 147 1.3 mrg * @post @c __other.empty() (this postcondition is a GNU extension) 148 1.1 mrg */ 149 1.1 mrg any(any&& __other) noexcept 150 1.3 mrg { 151 1.3 mrg if (__other.empty()) 152 1.3 mrg _M_manager = nullptr; 153 1.3 mrg else 154 1.3 mrg { 155 1.3 mrg _Arg __arg; 156 1.3 mrg __arg._M_any = this; 157 1.3 mrg __other._M_manager(_Op_xfer, &__other, &__arg); 158 1.3 mrg } 159 1.3 mrg } 160 1.3 mrg 161 1.3 mrg /// Construct with a copy of @p __value as the contained object. 162 1.3 mrg template <typename _ValueType, typename _Tp = _Decay<_ValueType>, 163 1.3 mrg typename _Mgr = _Manager<_Tp>, 164 1.3 mrg typename enable_if<is_constructible<_Tp, _ValueType&&>::value, 165 1.3 mrg bool>::type = true> 166 1.3 mrg any(_ValueType&& __value) 167 1.3 mrg : _M_manager(&_Mgr::_S_manage) 168 1.3 mrg { 169 1.3 mrg _Mgr::_S_create(_M_storage, std::forward<_ValueType>(__value)); 170 1.3 mrg static_assert(is_copy_constructible<_Tp>::value, 171 1.3 mrg "The contained object must be CopyConstructible"); 172 1.3 mrg } 173 1.1 mrg 174 1.1 mrg /// Construct with a copy of @p __value as the contained object. 175 1.1 mrg template <typename _ValueType, typename _Tp = _Decay<_ValueType>, 176 1.3 mrg typename _Mgr = _Manager<_Tp>, 177 1.3 mrg typename enable_if<!is_constructible<_Tp, _ValueType&&>::value, 178 1.3 mrg bool>::type = false> 179 1.1 mrg any(_ValueType&& __value) 180 1.3 mrg : _M_manager(&_Mgr::_S_manage) 181 1.1 mrg { 182 1.3 mrg _Mgr::_S_create(_M_storage, __value); 183 1.1 mrg static_assert(is_copy_constructible<_Tp>::value, 184 1.1 mrg "The contained object must be CopyConstructible"); 185 1.1 mrg } 186 1.1 mrg 187 1.1 mrg /// Destructor, calls @c clear() 188 1.1 mrg ~any() { clear(); } 189 1.1 mrg 190 1.1 mrg // assignments 191 1.1 mrg 192 1.3 mrg /// Copy the state of another object. 193 1.1 mrg any& operator=(const any& __rhs) 194 1.1 mrg { 195 1.3 mrg *this = any(__rhs); 196 1.1 mrg return *this; 197 1.1 mrg } 198 1.1 mrg 199 1.1 mrg /** 200 1.1 mrg * @brief Move assignment operator 201 1.1 mrg * 202 1.1 mrg * @post @c __rhs.empty() (not guaranteed for other implementations) 203 1.1 mrg */ 204 1.1 mrg any& operator=(any&& __rhs) noexcept 205 1.1 mrg { 206 1.3 mrg if (__rhs.empty()) 207 1.3 mrg clear(); 208 1.3 mrg else if (this != &__rhs) 209 1.3 mrg { 210 1.3 mrg clear(); 211 1.3 mrg _Arg __arg; 212 1.3 mrg __arg._M_any = this; 213 1.3 mrg __rhs._M_manager(_Op_xfer, &__rhs, &__arg); 214 1.3 mrg } 215 1.1 mrg return *this; 216 1.1 mrg } 217 1.1 mrg 218 1.1 mrg /// Store a copy of @p __rhs as the contained object. 219 1.1 mrg template<typename _ValueType> 220 1.3 mrg enable_if_t<!is_same<any, decay_t<_ValueType>>::value, any&> 221 1.3 mrg operator=(_ValueType&& __rhs) 222 1.1 mrg { 223 1.3 mrg *this = any(std::forward<_ValueType>(__rhs)); 224 1.1 mrg return *this; 225 1.1 mrg } 226 1.1 mrg 227 1.1 mrg // modifiers 228 1.1 mrg 229 1.1 mrg /// If not empty, destroy the contained object. 230 1.1 mrg void clear() noexcept 231 1.1 mrg { 232 1.1 mrg if (!empty()) 233 1.1 mrg { 234 1.1 mrg _M_manager(_Op_destroy, this, nullptr); 235 1.1 mrg _M_manager = nullptr; 236 1.1 mrg } 237 1.1 mrg } 238 1.1 mrg 239 1.1 mrg /// Exchange state with another object. 240 1.1 mrg void swap(any& __rhs) noexcept 241 1.1 mrg { 242 1.3 mrg if (empty() && __rhs.empty()) 243 1.3 mrg return; 244 1.3 mrg 245 1.3 mrg if (!empty() && !__rhs.empty()) 246 1.3 mrg { 247 1.3 mrg if (this == &__rhs) 248 1.3 mrg return; 249 1.3 mrg 250 1.3 mrg any __tmp; 251 1.3 mrg _Arg __arg; 252 1.3 mrg __arg._M_any = &__tmp; 253 1.3 mrg __rhs._M_manager(_Op_xfer, &__rhs, &__arg); 254 1.3 mrg __arg._M_any = &__rhs; 255 1.3 mrg _M_manager(_Op_xfer, this, &__arg); 256 1.3 mrg __arg._M_any = this; 257 1.3 mrg __tmp._M_manager(_Op_xfer, &__tmp, &__arg); 258 1.3 mrg } 259 1.3 mrg else 260 1.3 mrg { 261 1.3 mrg any* __empty = empty() ? this : &__rhs; 262 1.3 mrg any* __full = empty() ? &__rhs : this; 263 1.3 mrg _Arg __arg; 264 1.3 mrg __arg._M_any = __empty; 265 1.3 mrg __full->_M_manager(_Op_xfer, __full, &__arg); 266 1.3 mrg } 267 1.1 mrg } 268 1.1 mrg 269 1.1 mrg // observers 270 1.1 mrg 271 1.1 mrg /// Reports whether there is a contained object or not. 272 1.5 mrg _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_manager == nullptr; } 273 1.1 mrg 274 1.1 mrg #if __cpp_rtti 275 1.1 mrg /// The @c typeid of the contained object, or @c typeid(void) if empty. 276 1.1 mrg const type_info& type() const noexcept 277 1.1 mrg { 278 1.1 mrg if (empty()) 279 1.1 mrg return typeid(void); 280 1.1 mrg _Arg __arg; 281 1.1 mrg _M_manager(_Op_get_type_info, this, &__arg); 282 1.1 mrg return *__arg._M_typeinfo; 283 1.1 mrg } 284 1.1 mrg #endif 285 1.1 mrg 286 1.1 mrg template<typename _Tp> 287 1.1 mrg static constexpr bool __is_valid_cast() 288 1.1 mrg { return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; } 289 1.1 mrg 290 1.1 mrg private: 291 1.3 mrg enum _Op { 292 1.3 mrg _Op_access, _Op_get_type_info, _Op_clone, _Op_destroy, _Op_xfer 293 1.3 mrg }; 294 1.1 mrg 295 1.1 mrg union _Arg 296 1.1 mrg { 297 1.1 mrg void* _M_obj; 298 1.1 mrg const std::type_info* _M_typeinfo; 299 1.1 mrg any* _M_any; 300 1.1 mrg }; 301 1.1 mrg 302 1.1 mrg void (*_M_manager)(_Op, const any*, _Arg*); 303 1.1 mrg _Storage _M_storage; 304 1.1 mrg 305 1.1 mrg template<typename _Tp> 306 1.4 mrg friend enable_if_t<is_object<_Tp>::value, void*> 307 1.4 mrg __any_caster(const any* __any); 308 1.1 mrg 309 1.1 mrg // Manage in-place contained object. 310 1.1 mrg template<typename _Tp> 311 1.1 mrg struct _Manager_internal 312 1.1 mrg { 313 1.1 mrg static void 314 1.1 mrg _S_manage(_Op __which, const any* __anyp, _Arg* __arg); 315 1.1 mrg 316 1.1 mrg template<typename _Up> 317 1.3 mrg static void 318 1.3 mrg _S_create(_Storage& __storage, _Up&& __value) 319 1.1 mrg { 320 1.1 mrg void* __addr = &__storage._M_buffer; 321 1.1 mrg ::new (__addr) _Tp(std::forward<_Up>(__value)); 322 1.1 mrg } 323 1.1 mrg }; 324 1.1 mrg 325 1.1 mrg // Manage external contained object. 326 1.1 mrg template<typename _Tp> 327 1.1 mrg struct _Manager_external 328 1.1 mrg { 329 1.1 mrg static void 330 1.1 mrg _S_manage(_Op __which, const any* __anyp, _Arg* __arg); 331 1.1 mrg 332 1.1 mrg template<typename _Up> 333 1.3 mrg static void 334 1.3 mrg _S_create(_Storage& __storage, _Up&& __value) 335 1.1 mrg { 336 1.1 mrg __storage._M_ptr = new _Tp(std::forward<_Up>(__value)); 337 1.1 mrg } 338 1.1 mrg }; 339 1.1 mrg }; 340 1.1 mrg 341 1.1 mrg /// Exchange the states of two @c any objects. 342 1.1 mrg inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); } 343 1.1 mrg 344 1.1 mrg /** 345 1.1 mrg * @brief Access the contained object. 346 1.1 mrg * 347 1.1 mrg * @tparam _ValueType A const-reference or CopyConstructible type. 348 1.1 mrg * @param __any The object to access. 349 1.1 mrg * @return The contained object. 350 1.1 mrg * @throw bad_any_cast If <code> 351 1.1 mrg * __any.type() != typeid(remove_reference_t<_ValueType>) 352 1.1 mrg * </code> 353 1.1 mrg */ 354 1.1 mrg template<typename _ValueType> 355 1.1 mrg inline _ValueType any_cast(const any& __any) 356 1.1 mrg { 357 1.1 mrg static_assert(any::__is_valid_cast<_ValueType>(), 358 1.1 mrg "Template argument must be a reference or CopyConstructible type"); 359 1.1 mrg auto __p = any_cast<add_const_t<remove_reference_t<_ValueType>>>(&__any); 360 1.1 mrg if (__p) 361 1.1 mrg return *__p; 362 1.1 mrg __throw_bad_any_cast(); 363 1.1 mrg } 364 1.1 mrg 365 1.1 mrg /** 366 1.1 mrg * @brief Access the contained object. 367 1.1 mrg * 368 1.1 mrg * @tparam _ValueType A reference or CopyConstructible type. 369 1.1 mrg * @param __any The object to access. 370 1.1 mrg * @return The contained object. 371 1.1 mrg * @throw bad_any_cast If <code> 372 1.1 mrg * __any.type() != typeid(remove_reference_t<_ValueType>) 373 1.1 mrg * </code> 374 1.1 mrg * 375 1.1 mrg * @{ 376 1.1 mrg */ 377 1.1 mrg template<typename _ValueType> 378 1.1 mrg inline _ValueType any_cast(any& __any) 379 1.1 mrg { 380 1.1 mrg static_assert(any::__is_valid_cast<_ValueType>(), 381 1.1 mrg "Template argument must be a reference or CopyConstructible type"); 382 1.1 mrg auto __p = any_cast<remove_reference_t<_ValueType>>(&__any); 383 1.1 mrg if (__p) 384 1.1 mrg return *__p; 385 1.1 mrg __throw_bad_any_cast(); 386 1.1 mrg } 387 1.1 mrg 388 1.3 mrg template<typename _ValueType, 389 1.3 mrg typename enable_if<!is_move_constructible<_ValueType>::value 390 1.3 mrg || is_lvalue_reference<_ValueType>::value, 391 1.3 mrg bool>::type = true> 392 1.1 mrg inline _ValueType any_cast(any&& __any) 393 1.1 mrg { 394 1.1 mrg static_assert(any::__is_valid_cast<_ValueType>(), 395 1.1 mrg "Template argument must be a reference or CopyConstructible type"); 396 1.1 mrg auto __p = any_cast<remove_reference_t<_ValueType>>(&__any); 397 1.1 mrg if (__p) 398 1.1 mrg return *__p; 399 1.1 mrg __throw_bad_any_cast(); 400 1.1 mrg } 401 1.3 mrg 402 1.3 mrg template<typename _ValueType, 403 1.3 mrg typename enable_if<is_move_constructible<_ValueType>::value 404 1.3 mrg && !is_lvalue_reference<_ValueType>::value, 405 1.3 mrg bool>::type = false> 406 1.3 mrg inline _ValueType any_cast(any&& __any) 407 1.3 mrg { 408 1.3 mrg static_assert(any::__is_valid_cast<_ValueType>(), 409 1.3 mrg "Template argument must be a reference or CopyConstructible type"); 410 1.3 mrg auto __p = any_cast<remove_reference_t<_ValueType>>(&__any); 411 1.3 mrg if (__p) 412 1.3 mrg return std::move(*__p); 413 1.3 mrg __throw_bad_any_cast(); 414 1.3 mrg } 415 1.6 mrg /// @} 416 1.1 mrg 417 1.4 mrg /// @cond undocumented 418 1.3 mrg template<typename _Tp> 419 1.4 mrg enable_if_t<is_object<_Tp>::value, void*> 420 1.4 mrg __any_caster(const any* __any) 421 1.3 mrg { 422 1.4 mrg // any_cast<T> returns non-null if __any->type() == typeid(T) and 423 1.4 mrg // typeid(T) ignores cv-qualifiers so remove them: 424 1.4 mrg using _Up = remove_cv_t<_Tp>; 425 1.4 mrg // The contained value has a decayed type, so if decay_t<U> is not U, 426 1.4 mrg // then it's not possible to have a contained value of type U. 427 1.4 mrg using __does_not_decay = is_same<decay_t<_Up>, _Up>; 428 1.4 mrg // Only copy constructible types can be used for contained values. 429 1.4 mrg using __is_copyable = is_copy_constructible<_Up>; 430 1.4 mrg // If the type _Tp could never be stored in an any we don't want to 431 1.4 mrg // instantiate _Manager<_Tp>, so use _Manager<any::_Op> instead, which 432 1.4 mrg // is explicitly specialized and has a no-op _S_manage function. 433 1.7 mrg using _Vp = __conditional_t<__and_<__does_not_decay, __is_copyable>{}, 434 1.7 mrg _Up, any::_Op>; 435 1.4 mrg // First try comparing function addresses, which works without RTTI 436 1.4 mrg if (__any->_M_manager == &any::_Manager<_Vp>::_S_manage 437 1.4 mrg #if __cpp_rtti 438 1.4 mrg || __any->type() == typeid(_Tp) 439 1.4 mrg #endif 440 1.4 mrg ) 441 1.4 mrg { 442 1.4 mrg any::_Arg __arg; 443 1.4 mrg __any->_M_manager(any::_Op_access, __any, &__arg); 444 1.4 mrg return __arg._M_obj; 445 1.4 mrg } 446 1.4 mrg return nullptr; 447 1.3 mrg } 448 1.3 mrg 449 1.4 mrg // This overload exists so that std::any_cast<void(*)()>(a) is well-formed. 450 1.4 mrg template<typename _Tp> 451 1.4 mrg enable_if_t<!is_object<_Tp>::value, _Tp*> 452 1.4 mrg __any_caster(const any*) noexcept 453 1.4 mrg { return nullptr; } 454 1.4 mrg /// @endcond 455 1.4 mrg 456 1.1 mrg /** 457 1.1 mrg * @brief Access the contained object. 458 1.1 mrg * 459 1.1 mrg * @tparam _ValueType The type of the contained object. 460 1.1 mrg * @param __any A pointer to the object to access. 461 1.1 mrg * @return The address of the contained object if <code> 462 1.1 mrg * __any != nullptr && __any.type() == typeid(_ValueType) 463 1.1 mrg * </code>, otherwise a null pointer. 464 1.1 mrg * 465 1.1 mrg * @{ 466 1.1 mrg */ 467 1.1 mrg template<typename _ValueType> 468 1.1 mrg inline const _ValueType* any_cast(const any* __any) noexcept 469 1.1 mrg { 470 1.1 mrg if (__any) 471 1.1 mrg return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); 472 1.1 mrg return nullptr; 473 1.1 mrg } 474 1.1 mrg 475 1.1 mrg template<typename _ValueType> 476 1.1 mrg inline _ValueType* any_cast(any* __any) noexcept 477 1.1 mrg { 478 1.1 mrg if (__any) 479 1.1 mrg return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); 480 1.1 mrg return nullptr; 481 1.1 mrg } 482 1.6 mrg /// @} 483 1.1 mrg 484 1.1 mrg template<typename _Tp> 485 1.1 mrg void 486 1.1 mrg any::_Manager_internal<_Tp>:: 487 1.1 mrg _S_manage(_Op __which, const any* __any, _Arg* __arg) 488 1.1 mrg { 489 1.1 mrg // The contained object is in _M_storage._M_buffer 490 1.1 mrg auto __ptr = reinterpret_cast<const _Tp*>(&__any->_M_storage._M_buffer); 491 1.1 mrg switch (__which) 492 1.1 mrg { 493 1.1 mrg case _Op_access: 494 1.1 mrg __arg->_M_obj = const_cast<_Tp*>(__ptr); 495 1.1 mrg break; 496 1.1 mrg case _Op_get_type_info: 497 1.1 mrg #if __cpp_rtti 498 1.1 mrg __arg->_M_typeinfo = &typeid(_Tp); 499 1.1 mrg #endif 500 1.1 mrg break; 501 1.1 mrg case _Op_clone: 502 1.1 mrg ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr); 503 1.3 mrg __arg->_M_any->_M_manager = __any->_M_manager; 504 1.1 mrg break; 505 1.1 mrg case _Op_destroy: 506 1.1 mrg __ptr->~_Tp(); 507 1.1 mrg break; 508 1.3 mrg case _Op_xfer: 509 1.3 mrg ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp 510 1.3 mrg (std::move(*const_cast<_Tp*>(__ptr))); 511 1.3 mrg __ptr->~_Tp(); 512 1.3 mrg __arg->_M_any->_M_manager = __any->_M_manager; 513 1.3 mrg const_cast<any*>(__any)->_M_manager = nullptr; 514 1.3 mrg break; 515 1.1 mrg } 516 1.1 mrg } 517 1.1 mrg 518 1.1 mrg template<typename _Tp> 519 1.1 mrg void 520 1.1 mrg any::_Manager_external<_Tp>:: 521 1.1 mrg _S_manage(_Op __which, const any* __any, _Arg* __arg) 522 1.1 mrg { 523 1.1 mrg // The contained object is *_M_storage._M_ptr 524 1.1 mrg auto __ptr = static_cast<const _Tp*>(__any->_M_storage._M_ptr); 525 1.1 mrg switch (__which) 526 1.1 mrg { 527 1.1 mrg case _Op_access: 528 1.1 mrg __arg->_M_obj = const_cast<_Tp*>(__ptr); 529 1.1 mrg break; 530 1.1 mrg case _Op_get_type_info: 531 1.1 mrg #if __cpp_rtti 532 1.1 mrg __arg->_M_typeinfo = &typeid(_Tp); 533 1.1 mrg #endif 534 1.1 mrg break; 535 1.1 mrg case _Op_clone: 536 1.1 mrg __arg->_M_any->_M_storage._M_ptr = new _Tp(*__ptr); 537 1.3 mrg __arg->_M_any->_M_manager = __any->_M_manager; 538 1.1 mrg break; 539 1.1 mrg case _Op_destroy: 540 1.1 mrg delete __ptr; 541 1.1 mrg break; 542 1.3 mrg case _Op_xfer: 543 1.3 mrg __arg->_M_any->_M_storage._M_ptr = __any->_M_storage._M_ptr; 544 1.3 mrg __arg->_M_any->_M_manager = __any->_M_manager; 545 1.3 mrg const_cast<any*>(__any)->_M_manager = nullptr; 546 1.3 mrg break; 547 1.1 mrg } 548 1.1 mrg } 549 1.1 mrg 550 1.4 mrg // Dummy specialization used by __any_caster. 551 1.4 mrg template<> 552 1.4 mrg struct any::_Manager_internal<any::_Op> 553 1.4 mrg { 554 1.4 mrg static void 555 1.4 mrg _S_manage(_Op, const any*, _Arg*) { } 556 1.4 mrg }; 557 1.4 mrg 558 1.6 mrg /// @} group any 559 1.1 mrg } // namespace fundamentals_v1 560 1.1 mrg } // namespace experimental 561 1.4 mrg 562 1.4 mrg _GLIBCXX_END_NAMESPACE_VERSION 563 1.1 mrg } // namespace std 564 1.1 mrg 565 1.1 mrg #endif // C++14 566 1.1 mrg 567 1.1 mrg #endif // _GLIBCXX_EXPERIMENTAL_ANY 568