any 15 KB

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