1// -*- 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> 88 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 105_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 115// 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 200 , class _Tp = decay_t<_ValueType> 201 , class = enable_if_t< 202 !is_same<_Tp, any>::value && 203 !__is_inplace_type<_ValueType>::value && 204 is_copy_constructible<_Tp>::value> 205 > 206 _LIBCPP_INLINE_VISIBILITY 207 any(_ValueType && __value); 208 209 template <class _ValueType, class ..._Args, 210 class _Tp = decay_t<_ValueType>, 211 class = enable_if_t< 212 is_constructible<_Tp, _Args...>::value && 213 is_copy_constructible<_Tp>::value 214 > 215 > 216 _LIBCPP_INLINE_VISIBILITY 217 explicit any(in_place_type_t<_ValueType>, _Args&&... __args); 218 219 template <class _ValueType, class _Up, class ..._Args, 220 class _Tp = decay_t<_ValueType>, 221 class = enable_if_t< 222 is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && 223 is_copy_constructible<_Tp>::value> 224 > 225 _LIBCPP_INLINE_VISIBILITY 226 explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args); 227 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 248 , class _Tp = decay_t<_ValueType> 249 , class = enable_if_t< 250 !is_same<_Tp, any>::value 251 && is_copy_constructible<_Tp>::value 252 && !__is_inplace_type<_ValueType>::value> 253 > 254 _LIBCPP_INLINE_VISIBILITY 255 any & operator=(_ValueType && __rhs); 256 257 template <class _ValueType, class ..._Args, 258 class _Tp = decay_t<_ValueType>, 259 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 266 template <class _ValueType, class _Up, class ..._Args, 267 class _Tp = decay_t<_ValueType>, 268 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 499template <class _ValueType, class _Tp, class> 500any::any(_ValueType && __v) : __h(nullptr) 501{ 502 __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v)); 503} 504 505template <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)...); 508}; 509 510template <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)...); 513} 514 515template <class _ValueType, class, class> 516inline _LIBCPP_INLINE_VISIBILITY 517any & any::operator=(_ValueType && __v) 518{ 519 any(_VSTD::forward<_ValueType>(__v)).swap(*this); 520 return *this; 521} 522 523template <class _ValueType, class ..._Args, class _Tp, class> 524inline _LIBCPP_INLINE_VISIBILITY 525void any::emplace(_Args&&... __args) { 526 reset(); 527 __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); 528} 529 530template <class _ValueType, class _Up, class ..._Args, class _Tp, class> 531inline _LIBCPP_INLINE_VISIBILITY 532void any::emplace(initializer_list<_Up> __il, _Args&&... __args) { 533 reset(); 534 __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); 535} 536 537inline _LIBCPP_INLINE_VISIBILITY 538void any::swap(any & __rhs) _NOEXCEPT 539{ 540 if (this == &__rhs) 541 return; 542 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{ 580 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); 584 if (__tmp == nullptr) 585 __throw_bad_any_cast(); 586 return static_cast<_ValueType>(*__tmp); 587} 588 589template <class _ValueType> 590inline _LIBCPP_INLINE_VISIBILITY 591_ValueType any_cast(any & __v) 592{ 593 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); 597 if (__tmp == nullptr) 598 __throw_bad_any_cast(); 599 return static_cast<_ValueType>(*__tmp); 600} 601 602template <class _ValueType> 603inline _LIBCPP_INLINE_VISIBILITY 604_ValueType any_cast(any && __v) 605{ 606 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); 610 if (__tmp == nullptr) 611 __throw_bad_any_cast(); 612 return static_cast<_ValueType>(_VSTD::move(*__tmp)); 613} 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 652