| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 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_EXPERIMENTAL_ANY | 
|  | 12 | #define _LIBCPP_EXPERIMENTAL_ANY | 
|  | 13 |  | 
|  | 14 | /* | 
|  | 15 | experimental/any synopsis | 
|  | 16 |  | 
|  | 17 | namespace std { | 
|  | 18 | namespace experimental { | 
|  | 19 | inline namespace fundamentals_v1 { | 
|  | 20 |  | 
|  | 21 | class bad_any_cast : public bad_cast | 
|  | 22 | { | 
|  | 23 | public: | 
|  | 24 | virtual const char* what() const noexcept; | 
|  | 25 | }; | 
|  | 26 |  | 
|  | 27 | class any | 
|  | 28 | { | 
|  | 29 | public: | 
|  | 30 |  | 
|  | 31 | // 6.3.1 any construct/destruct | 
|  | 32 | any() noexcept; | 
|  | 33 |  | 
|  | 34 | any(const any& other); | 
|  | 35 | any(any&& other) noexcept; | 
|  | 36 |  | 
|  | 37 | template <class ValueType> | 
|  | 38 | any(ValueType&& value); | 
|  | 39 |  | 
|  | 40 | ~any(); | 
|  | 41 |  | 
|  | 42 | // 6.3.2 any assignments | 
|  | 43 | any& operator=(const any& rhs); | 
|  | 44 | any& operator=(any&& rhs) noexcept; | 
|  | 45 |  | 
|  | 46 | template <class ValueType> | 
|  | 47 | any& operator=(ValueType&& rhs); | 
|  | 48 |  | 
|  | 49 | // 6.3.3 any modifiers | 
|  | 50 | void clear() noexcept; | 
|  | 51 | void swap(any& rhs) noexcept; | 
|  | 52 |  | 
|  | 53 | // 6.3.4 any observers | 
|  | 54 | bool empty() const noexcept; | 
|  | 55 | const type_info& type() const noexcept; | 
|  | 56 | }; | 
|  | 57 |  | 
|  | 58 | // 6.4 Non-member functions | 
|  | 59 | void swap(any& x, any& y) noexcept; | 
|  | 60 |  | 
|  | 61 | template<class ValueType> | 
|  | 62 | ValueType any_cast(const any& operand); | 
|  | 63 | template<class ValueType> | 
|  | 64 | ValueType any_cast(any& operand); | 
|  | 65 | template<class ValueType> | 
|  | 66 | ValueType any_cast(any&& operand); | 
|  | 67 |  | 
|  | 68 | template<class ValueType> | 
|  | 69 | const ValueType* any_cast(const any* operand) noexcept; | 
|  | 70 | template<class ValueType> | 
|  | 71 | ValueType* any_cast(any* operand) noexcept; | 
|  | 72 |  | 
|  | 73 | } // namespace fundamentals_v1 | 
|  | 74 | } // namespace experimental | 
|  | 75 | } // namespace std | 
|  | 76 |  | 
|  | 77 | */ | 
|  | 78 |  | 
|  | 79 | #include <experimental/__config> | 
|  | 80 | #include <memory> | 
|  | 81 | #include <new> | 
|  | 82 | #include <typeinfo> | 
|  | 83 | #include <type_traits> | 
|  | 84 | #include <cstdlib> | 
|  | 85 |  | 
|  | 86 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | 
|  | 87 | #pragma GCC system_header | 
|  | 88 | #endif | 
|  | 89 |  | 
|  | 90 | _LIBCPP_BEGIN_NAMESPACE_LFTS | 
|  | 91 |  | 
| Duncan P. N. Exon Smith | b1cb279 | 2017-06-18 14:52:26 +0000 | [diff] [blame] | 92 | class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 93 | { | 
|  | 94 | public: | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 95 | virtual const char* what() const _NOEXCEPT; | 
|  | 96 | }; | 
|  | 97 |  | 
|  | 98 | #if _LIBCPP_STD_VER > 11                                            // C++ > 11 | 
|  | 99 |  | 
| Marshall Clow | d437fa5 | 2016-08-25 15:09:01 +0000 | [diff] [blame] | 100 | _LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE | 
| Duncan P. N. Exon Smith | b1cb279 | 2017-06-18 14:52:26 +0000 | [diff] [blame] | 101 | _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST | 
| Marshall Clow | 567a1d0 | 2016-08-25 15:56:55 +0000 | [diff] [blame] | 102 | void __throw_bad_any_cast() | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 103 | { | 
|  | 104 | #ifndef _LIBCPP_NO_EXCEPTIONS | 
|  | 105 | throw bad_any_cast(); | 
|  | 106 | #else | 
| Marshall Clow | d437fa5 | 2016-08-25 15:09:01 +0000 | [diff] [blame] | 107 | _VSTD::abort(); | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 108 | #endif | 
|  | 109 | } | 
|  | 110 |  | 
|  | 111 | // Forward declarations | 
|  | 112 | class any; | 
|  | 113 |  | 
|  | 114 | template <class _ValueType> | 
|  | 115 | typename add_pointer<typename add_const<_ValueType>::type>::type | 
| Evgeniy Stepanov | cd31b43 | 2016-04-22 01:04:55 +0000 | [diff] [blame] | 116 | _LIBCPP_INLINE_VISIBILITY | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 117 | any_cast(any const *) _NOEXCEPT; | 
|  | 118 |  | 
|  | 119 | template <class _ValueType> | 
|  | 120 | typename add_pointer<_ValueType>::type | 
| Evgeniy Stepanov | cd31b43 | 2016-04-22 01:04:55 +0000 | [diff] [blame] | 121 | _LIBCPP_INLINE_VISIBILITY | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 122 | any_cast(any *) _NOEXCEPT; | 
|  | 123 |  | 
|  | 124 | namespace __any_imp | 
|  | 125 | { | 
|  | 126 | typedef typename aligned_storage<3*sizeof(void*), alignment_of<void*>::value>::type | 
|  | 127 | _Buffer; | 
|  | 128 |  | 
|  | 129 | template <class _Tp> | 
|  | 130 | struct _IsSmallObject | 
|  | 131 | : public integral_constant<bool | 
|  | 132 | , sizeof(_Tp) <= sizeof(_Buffer) | 
|  | 133 | && alignment_of<_Buffer>::value | 
|  | 134 | % alignment_of<_Tp>::value == 0 | 
|  | 135 | && is_nothrow_move_constructible<_Tp>::value | 
|  | 136 | > | 
|  | 137 | {}; | 
|  | 138 |  | 
|  | 139 | enum class _Action | 
|  | 140 | { | 
|  | 141 | _Destroy, | 
|  | 142 | _Copy, | 
|  | 143 | _Move, | 
|  | 144 | _Get, | 
|  | 145 | _TypeInfo | 
|  | 146 | }; | 
|  | 147 |  | 
|  | 148 | template <class _Tp> | 
|  | 149 | struct _SmallHandler; | 
|  | 150 |  | 
|  | 151 | template <class _Tp> | 
|  | 152 | struct _LargeHandler; | 
|  | 153 |  | 
|  | 154 | template <class _Tp> | 
|  | 155 | using _Handler = typename conditional<_IsSmallObject<_Tp>::value | 
|  | 156 | , _SmallHandler<_Tp> | 
|  | 157 | , _LargeHandler<_Tp> | 
|  | 158 | >::type; | 
|  | 159 | template <class _ValueType> | 
|  | 160 | using _EnableIfNotAny = typename | 
|  | 161 | enable_if< | 
|  | 162 | !is_same<typename decay<_ValueType>::type, any>::value | 
|  | 163 | >::type; | 
|  | 164 |  | 
|  | 165 | } // namespace __any_imp | 
|  | 166 |  | 
|  | 167 | class any | 
|  | 168 | { | 
|  | 169 | public: | 
|  | 170 | // 6.3.1 any construct/destruct | 
|  | 171 | _LIBCPP_INLINE_VISIBILITY | 
|  | 172 | any() _NOEXCEPT : __h(nullptr) {} | 
|  | 173 |  | 
|  | 174 | _LIBCPP_INLINE_VISIBILITY | 
|  | 175 | any(any const & __other) : __h(nullptr) | 
|  | 176 | { | 
|  | 177 | if (__other.__h) __other.__call(_Action::_Copy, this); | 
|  | 178 | } | 
|  | 179 |  | 
|  | 180 | _LIBCPP_INLINE_VISIBILITY | 
|  | 181 | any(any && __other) _NOEXCEPT : __h(nullptr) | 
|  | 182 | { | 
|  | 183 | if (__other.__h) __other.__call(_Action::_Move, this); | 
|  | 184 | } | 
|  | 185 |  | 
|  | 186 | template < | 
|  | 187 | class _ValueType | 
|  | 188 | , class = __any_imp::_EnableIfNotAny<_ValueType> | 
|  | 189 | > | 
| Evgeniy Stepanov | cd31b43 | 2016-04-22 01:04:55 +0000 | [diff] [blame] | 190 | _LIBCPP_INLINE_VISIBILITY | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 191 | any(_ValueType && __value); | 
|  | 192 |  | 
|  | 193 | _LIBCPP_INLINE_VISIBILITY | 
|  | 194 | ~any() | 
|  | 195 | { | 
|  | 196 | this->clear(); | 
|  | 197 | } | 
|  | 198 |  | 
|  | 199 | // 6.3.2 any assignments | 
|  | 200 | _LIBCPP_INLINE_VISIBILITY | 
|  | 201 | any & operator=(any const & __rhs) | 
|  | 202 | { | 
|  | 203 | any(__rhs).swap(*this); | 
|  | 204 | return *this; | 
|  | 205 | } | 
|  | 206 |  | 
|  | 207 | _LIBCPP_INLINE_VISIBILITY | 
|  | 208 | any & operator=(any && __rhs) _NOEXCEPT | 
|  | 209 | { | 
|  | 210 | any(_VSTD::move(__rhs)).swap(*this); | 
|  | 211 | return *this; | 
|  | 212 | } | 
|  | 213 |  | 
|  | 214 | template < | 
|  | 215 | class _ValueType | 
|  | 216 | , class = __any_imp::_EnableIfNotAny<_ValueType> | 
|  | 217 | > | 
| Evgeniy Stepanov | cd31b43 | 2016-04-22 01:04:55 +0000 | [diff] [blame] | 218 | _LIBCPP_INLINE_VISIBILITY | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 219 | any & operator=(_ValueType && __rhs); | 
|  | 220 |  | 
|  | 221 | // 6.3.3 any modifiers | 
|  | 222 | _LIBCPP_INLINE_VISIBILITY | 
|  | 223 | void clear() _NOEXCEPT | 
|  | 224 | { | 
|  | 225 | if (__h) this->__call(_Action::_Destroy); | 
|  | 226 | } | 
|  | 227 |  | 
| Evgeniy Stepanov | cd31b43 | 2016-04-22 01:04:55 +0000 | [diff] [blame] | 228 | _LIBCPP_INLINE_VISIBILITY | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 229 | void swap(any & __rhs) _NOEXCEPT; | 
|  | 230 |  | 
|  | 231 | // 6.3.4 any observers | 
|  | 232 | _LIBCPP_INLINE_VISIBILITY | 
|  | 233 | bool empty() const _NOEXCEPT | 
|  | 234 | { | 
|  | 235 | return __h == nullptr; | 
|  | 236 | } | 
|  | 237 |  | 
|  | 238 | #if !defined(_LIBCPP_NO_RTTI) | 
|  | 239 | _LIBCPP_INLINE_VISIBILITY | 
|  | 240 | const type_info & type() const _NOEXCEPT | 
|  | 241 | { | 
|  | 242 | if (__h) { | 
|  | 243 | return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo)); | 
|  | 244 | } else { | 
|  | 245 | return typeid(void); | 
|  | 246 | } | 
|  | 247 | } | 
|  | 248 | #endif | 
|  | 249 |  | 
|  | 250 | private: | 
|  | 251 | typedef __any_imp::_Action _Action; | 
|  | 252 |  | 
|  | 253 | typedef void* (*_HandleFuncPtr)(_Action, any const *, any *, const type_info *); | 
|  | 254 |  | 
|  | 255 | union _Storage | 
|  | 256 | { | 
|  | 257 | void *  __ptr; | 
|  | 258 | __any_imp::_Buffer __buf; | 
|  | 259 | }; | 
|  | 260 |  | 
|  | 261 | _LIBCPP_ALWAYS_INLINE | 
|  | 262 | void * __call(_Action __a, any * __other = nullptr, | 
|  | 263 | type_info const * __info = nullptr) const | 
|  | 264 | { | 
|  | 265 | return __h(__a, this, __other, __info); | 
|  | 266 | } | 
|  | 267 |  | 
|  | 268 | _LIBCPP_ALWAYS_INLINE | 
|  | 269 | void * __call(_Action __a, any * __other = nullptr, | 
|  | 270 | type_info const * __info = nullptr) | 
|  | 271 | { | 
|  | 272 | return __h(__a, this, __other, __info); | 
|  | 273 | } | 
|  | 274 |  | 
|  | 275 | template <class> | 
|  | 276 | friend struct __any_imp::_SmallHandler; | 
|  | 277 | template <class> | 
|  | 278 | friend struct __any_imp::_LargeHandler; | 
|  | 279 |  | 
|  | 280 | template <class _ValueType> | 
|  | 281 | friend typename add_pointer<typename add_const<_ValueType>::type>::type | 
|  | 282 | any_cast(any const *) _NOEXCEPT; | 
|  | 283 |  | 
|  | 284 | template <class _ValueType> | 
|  | 285 | friend typename add_pointer<_ValueType>::type | 
|  | 286 | any_cast(any *) _NOEXCEPT; | 
|  | 287 |  | 
|  | 288 | _HandleFuncPtr __h; | 
|  | 289 | _Storage __s; | 
|  | 290 | }; | 
|  | 291 |  | 
|  | 292 | namespace __any_imp | 
|  | 293 | { | 
|  | 294 |  | 
|  | 295 | template <class _Tp> | 
| Eric Fiselier | e2f2d1e | 2017-01-04 23:56:00 +0000 | [diff] [blame] | 296 | struct _LIBCPP_TEMPLATE_VIS _SmallHandler | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 297 | { | 
|  | 298 | _LIBCPP_INLINE_VISIBILITY | 
|  | 299 | static void* __handle(_Action __act, any const * __this, any * __other, | 
|  | 300 | type_info const * __info) | 
|  | 301 | { | 
|  | 302 | switch (__act) | 
|  | 303 | { | 
|  | 304 | case _Action::_Destroy: | 
|  | 305 | __destroy(const_cast<any &>(*__this)); | 
|  | 306 | return nullptr; | 
|  | 307 | case _Action::_Copy: | 
|  | 308 | __copy(*__this, *__other); | 
|  | 309 | return nullptr; | 
|  | 310 | case _Action::_Move: | 
|  | 311 | __move(const_cast<any &>(*__this), *__other); | 
|  | 312 | return nullptr; | 
|  | 313 | case _Action::_Get: | 
|  | 314 | return __get(const_cast<any &>(*__this), __info); | 
|  | 315 | case _Action::_TypeInfo: | 
|  | 316 | return __type_info(); | 
|  | 317 | } | 
|  | 318 | } | 
|  | 319 |  | 
|  | 320 | template <class _Up> | 
|  | 321 | _LIBCPP_INLINE_VISIBILITY | 
|  | 322 | static void __create(any & __dest, _Up && __v) | 
|  | 323 | { | 
|  | 324 | ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Up>(__v)); | 
|  | 325 | __dest.__h = &_SmallHandler::__handle; | 
|  | 326 | } | 
|  | 327 |  | 
|  | 328 | private: | 
|  | 329 | _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY | 
|  | 330 | static void __destroy(any & __this) | 
|  | 331 | { | 
|  | 332 | _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf)); | 
|  | 333 | __value.~_Tp(); | 
|  | 334 | __this.__h = nullptr; | 
|  | 335 | } | 
|  | 336 |  | 
|  | 337 | _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY | 
|  | 338 | static void __copy(any const & __this, any & __dest) | 
|  | 339 | { | 
|  | 340 | _SmallHandler::__create(__dest, *static_cast<_Tp const *>( | 
|  | 341 | static_cast<void const *>(&__this.__s.__buf))); | 
|  | 342 | } | 
|  | 343 |  | 
|  | 344 | _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY | 
|  | 345 | static void __move(any & __this, any & __dest) | 
|  | 346 | { | 
|  | 347 | _SmallHandler::__create(__dest, _VSTD::move( | 
|  | 348 | *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf)))); | 
|  | 349 | __destroy(__this); | 
|  | 350 | } | 
|  | 351 |  | 
|  | 352 | _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY | 
|  | 353 | static void* __get(any & __this, type_info const * __info) | 
|  | 354 | { | 
|  | 355 | #if !defined(_LIBCPP_NO_RTTI) | 
|  | 356 | if (typeid(_Tp) == *__info) { | 
|  | 357 | return static_cast<void*>(&__this.__s.__buf); | 
|  | 358 | } | 
|  | 359 | return nullptr; | 
|  | 360 | #else | 
|  | 361 | return static_cast<void*>(&__this.__s.__buf); | 
|  | 362 | #endif | 
|  | 363 | } | 
|  | 364 |  | 
|  | 365 | _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY | 
|  | 366 | static void* __type_info() | 
|  | 367 | { | 
|  | 368 | #if !defined(_LIBCPP_NO_RTTI) | 
|  | 369 | return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); | 
|  | 370 | #else | 
|  | 371 | return nullptr; | 
|  | 372 | #endif | 
|  | 373 | } | 
|  | 374 | }; | 
|  | 375 |  | 
|  | 376 | template <class _Tp> | 
| Eric Fiselier | e2f2d1e | 2017-01-04 23:56:00 +0000 | [diff] [blame] | 377 | struct _LIBCPP_TEMPLATE_VIS _LargeHandler | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 378 | { | 
|  | 379 | _LIBCPP_INLINE_VISIBILITY | 
|  | 380 | static void* __handle(_Action __act, any const * __this, any * __other, | 
|  | 381 | type_info const * __info) | 
|  | 382 | { | 
|  | 383 | switch (__act) | 
|  | 384 | { | 
|  | 385 | case _Action::_Destroy: | 
|  | 386 | __destroy(const_cast<any &>(*__this)); | 
|  | 387 | return nullptr; | 
|  | 388 | case _Action::_Copy: | 
|  | 389 | __copy(*__this, *__other); | 
|  | 390 | return nullptr; | 
|  | 391 | case _Action::_Move: | 
|  | 392 | __move(const_cast<any &>(*__this), *__other); | 
|  | 393 | return nullptr; | 
|  | 394 | case _Action::_Get: | 
|  | 395 | return __get(const_cast<any &>(*__this), __info); | 
|  | 396 | case _Action::_TypeInfo: | 
|  | 397 | return __type_info(); | 
|  | 398 | } | 
|  | 399 | } | 
|  | 400 |  | 
|  | 401 | template <class _Up> | 
|  | 402 | _LIBCPP_INLINE_VISIBILITY | 
|  | 403 | static void __create(any & __dest, _Up && __v) | 
|  | 404 | { | 
|  | 405 | typedef allocator<_Tp> _Alloc; | 
|  | 406 | typedef __allocator_destructor<_Alloc> _Dp; | 
|  | 407 | _Alloc __a; | 
|  | 408 | unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); | 
|  | 409 | ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Up>(__v)); | 
|  | 410 | __dest.__s.__ptr = __hold.release(); | 
|  | 411 | __dest.__h = &_LargeHandler::__handle; | 
|  | 412 | } | 
|  | 413 |  | 
|  | 414 | private: | 
|  | 415 |  | 
|  | 416 | _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY | 
|  | 417 | static void __destroy(any & __this) | 
|  | 418 | { | 
|  | 419 | delete static_cast<_Tp*>(__this.__s.__ptr); | 
|  | 420 | __this.__h = nullptr; | 
|  | 421 | } | 
|  | 422 |  | 
|  | 423 | _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY | 
|  | 424 | static void __copy(any const & __this, any & __dest) | 
|  | 425 | { | 
|  | 426 | _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr)); | 
|  | 427 | } | 
|  | 428 |  | 
|  | 429 | _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY | 
|  | 430 | static void __move(any & __this, any & __dest) | 
|  | 431 | { | 
|  | 432 | __dest.__s.__ptr = __this.__s.__ptr; | 
|  | 433 | __dest.__h = &_LargeHandler::__handle; | 
|  | 434 | __this.__h = nullptr; | 
|  | 435 | } | 
|  | 436 |  | 
|  | 437 | _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY | 
|  | 438 | static void* __get(any & __this, type_info const * __info) | 
|  | 439 | { | 
|  | 440 | #if !defined(_LIBCPP_NO_RTTI) | 
|  | 441 | if (typeid(_Tp) == *__info) { | 
|  | 442 | return static_cast<void*>(__this.__s.__ptr); | 
|  | 443 | } | 
|  | 444 | return nullptr; | 
|  | 445 | #else | 
|  | 446 | return static_cast<void*>(__this.__s.__ptr); | 
|  | 447 | #endif | 
|  | 448 | } | 
|  | 449 |  | 
|  | 450 | _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY | 
|  | 451 | static void* __type_info() | 
|  | 452 | { | 
|  | 453 | #if !defined(_LIBCPP_NO_RTTI) | 
|  | 454 | return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); | 
|  | 455 | #else | 
|  | 456 | return nullptr; | 
|  | 457 | #endif | 
|  | 458 | } | 
|  | 459 | }; | 
|  | 460 |  | 
|  | 461 | } // namespace __any_imp | 
|  | 462 |  | 
|  | 463 |  | 
|  | 464 | template <class _ValueType, class> | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 465 | any::any(_ValueType && __v) : __h(nullptr) | 
|  | 466 | { | 
|  | 467 | typedef typename decay<_ValueType>::type _Tp; | 
|  | 468 | static_assert(is_copy_constructible<_Tp>::value, | 
|  | 469 | "_ValueType must be CopyConstructible."); | 
|  | 470 | typedef __any_imp::_Handler<_Tp> _HandlerType; | 
|  | 471 | _HandlerType::__create(*this, _VSTD::forward<_ValueType>(__v)); | 
|  | 472 | } | 
|  | 473 |  | 
|  | 474 | template <class _ValueType, class> | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 475 | any & any::operator=(_ValueType && __v) | 
|  | 476 | { | 
|  | 477 | typedef typename decay<_ValueType>::type _Tp; | 
|  | 478 | static_assert(is_copy_constructible<_Tp>::value, | 
|  | 479 | "_ValueType must be CopyConstructible."); | 
|  | 480 | any(_VSTD::forward<_ValueType>(__v)).swap(*this); | 
|  | 481 | return *this; | 
|  | 482 | } | 
|  | 483 |  | 
| Evgeniy Stepanov | cd31b43 | 2016-04-22 01:04:55 +0000 | [diff] [blame] | 484 | inline | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 485 | void any::swap(any & __rhs) _NOEXCEPT | 
|  | 486 | { | 
|  | 487 | if (__h && __rhs.__h) { | 
|  | 488 | any __tmp; | 
|  | 489 | __rhs.__call(_Action::_Move, &__tmp); | 
|  | 490 | this->__call(_Action::_Move, &__rhs); | 
|  | 491 | __tmp.__call(_Action::_Move, this); | 
|  | 492 | } | 
|  | 493 | else if (__h) { | 
|  | 494 | this->__call(_Action::_Move, &__rhs); | 
|  | 495 | } | 
|  | 496 | else if (__rhs.__h) { | 
|  | 497 | __rhs.__call(_Action::_Move, this); | 
|  | 498 | } | 
|  | 499 | } | 
|  | 500 |  | 
|  | 501 | // 6.4 Non-member functions | 
|  | 502 |  | 
|  | 503 | inline _LIBCPP_INLINE_VISIBILITY | 
|  | 504 | void swap(any & __lhs, any & __rhs) _NOEXCEPT | 
|  | 505 | { | 
|  | 506 | __lhs.swap(__rhs); | 
|  | 507 | } | 
|  | 508 |  | 
|  | 509 | template <class _ValueType> | 
| Duncan P. N. Exon Smith | b1cb279 | 2017-06-18 14:52:26 +0000 | [diff] [blame] | 510 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 511 | _ValueType any_cast(any const & __v) | 
|  | 512 | { | 
|  | 513 | static_assert( | 
|  | 514 | is_reference<_ValueType>::value | 
|  | 515 | || is_copy_constructible<_ValueType>::value, | 
|  | 516 | "_ValueType is required to be a reference or a CopyConstructible type."); | 
|  | 517 | typedef typename add_const<typename remove_reference<_ValueType>::type>::type | 
|  | 518 | _Tp; | 
|  | 519 | _Tp * __tmp = any_cast<_Tp>(&__v); | 
|  | 520 | if (__tmp == nullptr) | 
|  | 521 | __throw_bad_any_cast(); | 
|  | 522 | return *__tmp; | 
|  | 523 | } | 
|  | 524 |  | 
|  | 525 | template <class _ValueType> | 
| Duncan P. N. Exon Smith | b1cb279 | 2017-06-18 14:52:26 +0000 | [diff] [blame] | 526 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 527 | _ValueType any_cast(any & __v) | 
|  | 528 | { | 
|  | 529 | static_assert( | 
|  | 530 | is_reference<_ValueType>::value | 
|  | 531 | || is_copy_constructible<_ValueType>::value, | 
|  | 532 | "_ValueType is required to be a reference or a CopyConstructible type."); | 
|  | 533 | typedef typename remove_reference<_ValueType>::type _Tp; | 
|  | 534 | _Tp * __tmp = any_cast<_Tp>(&__v); | 
|  | 535 | if (__tmp == nullptr) | 
|  | 536 | __throw_bad_any_cast(); | 
|  | 537 | return *__tmp; | 
|  | 538 | } | 
|  | 539 |  | 
|  | 540 | template <class _ValueType> | 
| Duncan P. N. Exon Smith | b1cb279 | 2017-06-18 14:52:26 +0000 | [diff] [blame] | 541 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 542 | _ValueType any_cast(any && __v) | 
|  | 543 | { | 
|  | 544 | static_assert( | 
|  | 545 | is_reference<_ValueType>::value | 
|  | 546 | || is_copy_constructible<_ValueType>::value, | 
|  | 547 | "_ValueType is required to be a reference or a CopyConstructible type."); | 
|  | 548 | typedef typename remove_reference<_ValueType>::type _Tp; | 
|  | 549 | _Tp * __tmp = any_cast<_Tp>(&__v); | 
|  | 550 | if (__tmp == nullptr) | 
|  | 551 | __throw_bad_any_cast(); | 
|  | 552 | return *__tmp; | 
|  | 553 | } | 
|  | 554 |  | 
|  | 555 | template <class _ValueType> | 
| Evgeniy Stepanov | cd31b43 | 2016-04-22 01:04:55 +0000 | [diff] [blame] | 556 | inline | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 557 | typename add_pointer<typename add_const<_ValueType>::type>::type | 
|  | 558 | any_cast(any const * __any) _NOEXCEPT | 
|  | 559 | { | 
|  | 560 | static_assert(!is_reference<_ValueType>::value, | 
|  | 561 | "_ValueType may not be a reference."); | 
|  | 562 | return any_cast<_ValueType>(const_cast<any *>(__any)); | 
|  | 563 | } | 
|  | 564 |  | 
|  | 565 | template <class _ValueType> | 
| Eric Fiselier | 3461dbc | 2015-07-31 02:24:58 +0000 | [diff] [blame] | 566 | typename add_pointer<_ValueType>::type | 
|  | 567 | any_cast(any * __any) _NOEXCEPT | 
|  | 568 | { | 
|  | 569 | using __any_imp::_Action; | 
|  | 570 | static_assert(!is_reference<_ValueType>::value, | 
|  | 571 | "_ValueType may not be a reference."); | 
|  | 572 | typedef typename add_pointer<_ValueType>::type _ReturnType; | 
|  | 573 | if (__any && __any->__h) { | 
|  | 574 |  | 
|  | 575 | return static_cast<_ReturnType>( | 
|  | 576 | __any->__call(_Action::_Get, nullptr, | 
|  | 577 | #if !defined(_LIBCPP_NO_RTTI) | 
|  | 578 | &typeid(_ValueType) | 
|  | 579 | #else | 
|  | 580 | nullptr | 
|  | 581 | #endif | 
|  | 582 | )); | 
|  | 583 |  | 
|  | 584 | } | 
|  | 585 | return nullptr; | 
|  | 586 | } | 
|  | 587 |  | 
|  | 588 | #endif // _LIBCPP_STD_VER > 11 | 
|  | 589 |  | 
|  | 590 | _LIBCPP_END_NAMESPACE_LFTS | 
|  | 591 |  | 
|  | 592 | #endif // _LIBCPP_EXPERIMENTAL_ANY |