any.hpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. // See http://www.boost.org/libs/any for Documentation.
  2. #ifndef BOOST_ANY_INCLUDED
  3. #define BOOST_ANY_INCLUDED
  4. #include <boost/config.hpp>
  5. #ifdef BOOST_HAS_PRAGMA_ONCE
  6. # pragma once
  7. #endif
  8. // what: variant type boost::any
  9. // who: contributed by Kevlin Henney,
  10. // with features contributed and bugs found by
  11. // Antony Polukhin, Ed Brey, Mark Rodgers,
  12. // Peter Dimov, and James Curran
  13. // when: July 2001, April 2013 - 2020
  14. #include <boost/any/bad_any_cast.hpp>
  15. #include <boost/any/fwd.hpp>
  16. #include <boost/type_index.hpp>
  17. #include <boost/type_traits/remove_reference.hpp>
  18. #include <boost/type_traits/decay.hpp>
  19. #include <boost/type_traits/remove_cv.hpp>
  20. #include <boost/type_traits/add_reference.hpp>
  21. #include <boost/type_traits/is_reference.hpp>
  22. #include <boost/type_traits/is_const.hpp>
  23. #include <boost/throw_exception.hpp>
  24. #include <boost/static_assert.hpp>
  25. #include <boost/core/enable_if.hpp>
  26. #include <boost/core/addressof.hpp>
  27. #include <boost/type_traits/is_same.hpp>
  28. #include <boost/type_traits/conditional.hpp>
  29. namespace boost
  30. {
  31. class any
  32. {
  33. public: // structors
  34. BOOST_CONSTEXPR any() BOOST_NOEXCEPT
  35. : content(0)
  36. {
  37. }
  38. template<typename ValueType>
  39. any(const ValueType & value)
  40. : content(new holder<
  41. BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type
  42. >(value))
  43. {
  44. BOOST_STATIC_ASSERT_MSG(
  45. !anys::detail::is_basic_any<ValueType>::value,
  46. "boost::any shall not be constructed from boost::anys::basic_any"
  47. );
  48. }
  49. any(const any & other)
  50. : content(other.content ? other.content->clone() : 0)
  51. {
  52. }
  53. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  54. // Move constructor
  55. any(any&& other) BOOST_NOEXCEPT
  56. : content(other.content)
  57. {
  58. other.content = 0;
  59. }
  60. // Perfect forwarding of ValueType
  61. template<typename ValueType>
  62. any(ValueType&& value
  63. , typename boost::disable_if<boost::is_same<any&, ValueType> >::type* = 0 // disable if value has type `any&`
  64. , typename boost::disable_if<boost::is_const<ValueType> >::type* = 0) // disable if value has type `const ValueType&&`
  65. : content(new holder< typename decay<ValueType>::type >(static_cast<ValueType&&>(value)))
  66. {
  67. BOOST_STATIC_ASSERT_MSG(
  68. !anys::detail::is_basic_any<typename boost::decay<ValueType>::type>::value,
  69. "boost::any shall not be constructed from boost::anys::basic_any"
  70. );
  71. }
  72. #endif
  73. ~any() BOOST_NOEXCEPT
  74. {
  75. delete content;
  76. }
  77. public: // modifiers
  78. any & swap(any & rhs) BOOST_NOEXCEPT
  79. {
  80. placeholder* tmp = content;
  81. content = rhs.content;
  82. rhs.content = tmp;
  83. return *this;
  84. }
  85. #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
  86. template<typename ValueType>
  87. any & operator=(const ValueType & rhs)
  88. {
  89. BOOST_STATIC_ASSERT_MSG(
  90. !anys::detail::is_basic_any<ValueType>::value,
  91. "boost::anys::basic_any shall not be assigned into boost::any"
  92. );
  93. any(rhs).swap(*this);
  94. return *this;
  95. }
  96. any & operator=(any rhs)
  97. {
  98. rhs.swap(*this);
  99. return *this;
  100. }
  101. #else
  102. any & operator=(const any& rhs)
  103. {
  104. any(rhs).swap(*this);
  105. return *this;
  106. }
  107. // move assignment
  108. any & operator=(any&& rhs) BOOST_NOEXCEPT
  109. {
  110. rhs.swap(*this);
  111. any().swap(rhs);
  112. return *this;
  113. }
  114. // Perfect forwarding of ValueType
  115. template <class ValueType>
  116. any & operator=(ValueType&& rhs)
  117. {
  118. BOOST_STATIC_ASSERT_MSG(
  119. !anys::detail::is_basic_any<typename boost::decay<ValueType>::type>::value,
  120. "boost::anys::basic_any shall not be assigned into boost::any"
  121. );
  122. any(static_cast<ValueType&&>(rhs)).swap(*this);
  123. return *this;
  124. }
  125. #endif
  126. public: // queries
  127. bool empty() const BOOST_NOEXCEPT
  128. {
  129. return !content;
  130. }
  131. void clear() BOOST_NOEXCEPT
  132. {
  133. any().swap(*this);
  134. }
  135. const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
  136. {
  137. return content ? content->type() : boost::typeindex::type_id<void>().type_info();
  138. }
  139. #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
  140. private: // types
  141. #else
  142. public: // types (public so any_cast can be non-friend)
  143. #endif
  144. class BOOST_SYMBOL_VISIBLE placeholder
  145. {
  146. public: // structors
  147. virtual ~placeholder()
  148. {
  149. }
  150. public: // queries
  151. virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT = 0;
  152. virtual placeholder * clone() const = 0;
  153. };
  154. template<typename ValueType>
  155. class holder
  156. #ifndef BOOST_NO_CXX11_FINAL
  157. final
  158. #endif
  159. : public placeholder
  160. {
  161. public: // structors
  162. holder(const ValueType & value)
  163. : held(value)
  164. {
  165. }
  166. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  167. holder(ValueType&& value)
  168. : held(static_cast< ValueType&& >(value))
  169. {
  170. }
  171. #endif
  172. public: // queries
  173. const boost::typeindex::type_info& type() const BOOST_NOEXCEPT BOOST_OVERRIDE
  174. {
  175. return boost::typeindex::type_id<ValueType>().type_info();
  176. }
  177. placeholder * clone() const BOOST_OVERRIDE
  178. {
  179. return new holder(held);
  180. }
  181. public: // representation
  182. ValueType held;
  183. private: // intentionally left unimplemented
  184. holder & operator=(const holder &);
  185. };
  186. #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
  187. private: // representation
  188. template<typename ValueType>
  189. friend ValueType * any_cast(any *) BOOST_NOEXCEPT;
  190. template<typename ValueType>
  191. friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT;
  192. #else
  193. public: // representation (public so any_cast can be non-friend)
  194. #endif
  195. placeholder * content;
  196. };
  197. inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT
  198. {
  199. lhs.swap(rhs);
  200. }
  201. template<typename ValueType>
  202. ValueType * any_cast(any * operand) BOOST_NOEXCEPT
  203. {
  204. return operand && operand->type() == boost::typeindex::type_id<ValueType>()
  205. ? boost::addressof(
  206. static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
  207. )
  208. : 0;
  209. }
  210. template<typename ValueType>
  211. inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT
  212. {
  213. return any_cast<ValueType>(const_cast<any *>(operand));
  214. }
  215. template<typename ValueType>
  216. ValueType any_cast(any & operand)
  217. {
  218. typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
  219. nonref * result = any_cast<nonref>(boost::addressof(operand));
  220. if(!result)
  221. boost::throw_exception(bad_any_cast());
  222. // Attempt to avoid construction of a temporary object in cases when
  223. // `ValueType` is not a reference. Example:
  224. // `static_cast<std::string>(*result);`
  225. // which is equal to `std::string(*result);`
  226. typedef BOOST_DEDUCED_TYPENAME boost::conditional<
  227. boost::is_reference<ValueType>::value,
  228. ValueType,
  229. BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type
  230. >::type ref_type;
  231. #ifdef BOOST_MSVC
  232. # pragma warning(push)
  233. # pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local!
  234. #endif
  235. return static_cast<ref_type>(*result);
  236. #ifdef BOOST_MSVC
  237. # pragma warning(pop)
  238. #endif
  239. }
  240. template<typename ValueType>
  241. inline ValueType any_cast(const any & operand)
  242. {
  243. typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
  244. return any_cast<const nonref &>(const_cast<any &>(operand));
  245. }
  246. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  247. template<typename ValueType>
  248. inline ValueType any_cast(any&& operand)
  249. {
  250. BOOST_STATIC_ASSERT_MSG(
  251. boost::is_rvalue_reference<ValueType&&>::value /*true if ValueType is rvalue or just a value*/
  252. || boost::is_const< typename boost::remove_reference<ValueType>::type >::value,
  253. "boost::any_cast shall not be used for getting nonconst references to temporary objects"
  254. );
  255. return any_cast<ValueType>(operand);
  256. }
  257. #endif
  258. // Note: The "unsafe" versions of any_cast are not part of the
  259. // public interface and may be removed at any time. They are
  260. // required where we know what type is stored in the any and can't
  261. // use typeid() comparison, e.g., when our types may travel across
  262. // different shared libraries.
  263. template<typename ValueType>
  264. inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT
  265. {
  266. return boost::addressof(
  267. static_cast<any::holder<ValueType> *>(operand->content)->held
  268. );
  269. }
  270. template<typename ValueType>
  271. inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT
  272. {
  273. return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
  274. }
  275. }
  276. // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
  277. // Copyright Antony Polukhin, 2013-2023.
  278. //
  279. // Distributed under the Boost Software License, Version 1.0. (See
  280. // accompanying file LICENSE_1_0.txt or copy at
  281. // http://www.boost.org/LICENSE_1_0.txt)
  282. #endif