any.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. // See http://www.boost.org/libs/any for Documentation.
  2. #ifndef BOOST_ANY_INCLUDED
  3. #define BOOST_ANY_INCLUDED
  4. #include <boost/any/detail/config.hpp>
  5. #if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT)
  6. /// \file boost/any.hpp
  7. /// \brief \copybrief boost::any
  8. #ifndef BOOST_ANY_INTERFACE_UNIT
  9. #include <boost/config.hpp>
  10. #ifdef BOOST_HAS_PRAGMA_ONCE
  11. # pragma once
  12. #endif
  13. #include <memory> // for std::addressof
  14. #include <type_traits>
  15. #include <boost/throw_exception.hpp>
  16. #include <boost/type_index.hpp>
  17. #endif // #ifndef BOOST_ANY_INTERFACE_UNIT
  18. // what: variant type boost::any
  19. // who: contributed by Kevlin Henney,
  20. // with features contributed and bugs found by
  21. // Antony Polukhin, Ed Brey, Mark Rodgers,
  22. // Peter Dimov, and James Curran
  23. // when: July 2001, April 2013 - 2020
  24. #include <boost/any/bad_any_cast.hpp>
  25. #include <boost/any/fwd.hpp>
  26. #include <boost/any/detail/placeholder.hpp>
  27. namespace boost {
  28. BOOST_ANY_BEGIN_MODULE_EXPORT
  29. /// \brief A class whose instances can hold instances of any
  30. /// type that satisfies \forcedlink{ValueType} requirements.
  31. class any
  32. {
  33. public:
  34. /// \post this->empty() is true.
  35. constexpr any() noexcept
  36. : content(0)
  37. {
  38. }
  39. /// Makes a copy of `value`, so
  40. /// that the initial content of the new instance is equivalent
  41. /// in both type and value to `value`.
  42. ///
  43. /// \throws std::bad_alloc or any exceptions arising from the copy
  44. /// constructor of the contained type.
  45. template<typename ValueType>
  46. any(const ValueType & value)
  47. : content(new holder<
  48. typename std::remove_cv<typename std::decay<const ValueType>::type>::type
  49. >(value))
  50. {
  51. static_assert(
  52. !anys::detail::is_basic_any<ValueType>::value,
  53. "boost::any shall not be constructed from boost::anys::basic_any"
  54. );
  55. }
  56. /// Copy constructor that copies content of
  57. /// `other` into new instance, so that any content
  58. /// is equivalent in both type and value to the content of
  59. /// `other`, or empty if `other` is empty.
  60. ///
  61. /// \throws May fail with a `std::bad_alloc`
  62. /// exception or any exceptions arising from the copy
  63. /// constructor of the contained type.
  64. any(const any & other)
  65. : content(other.content ? other.content->clone() : 0)
  66. {
  67. }
  68. /// Move constructor that moves content of
  69. /// `other` into new instance and leaves `other` empty.
  70. ///
  71. /// \post other->empty() is true
  72. /// \throws Nothing.
  73. any(any&& other) noexcept
  74. : content(other.content)
  75. {
  76. other.content = 0;
  77. }
  78. /// Forwards `value`, so
  79. /// that the initial content of the new instance is equivalent
  80. /// in both type and value to `value` before the forward.
  81. ///
  82. /// \throws std::bad_alloc or any exceptions arising from the move or
  83. /// copy constructor of the contained type.
  84. template<typename ValueType>
  85. any(ValueType&& value
  86. , typename std::enable_if<!std::is_same<any&, ValueType>::value >::type* = 0 // disable if value has type `any&`
  87. , typename std::enable_if<!std::is_const<ValueType>::value >::type* = 0) // disable if value has type `const ValueType&&`
  88. : content(new holder< typename std::decay<ValueType>::type >(std::forward<ValueType>(value)))
  89. {
  90. static_assert(
  91. !anys::detail::is_basic_any<typename std::decay<ValueType>::type>::value,
  92. "boost::any shall not be constructed from boost::anys::basic_any"
  93. );
  94. }
  95. /// Releases any and all resources used in management of instance.
  96. ///
  97. /// \throws Nothing.
  98. ~any() noexcept
  99. {
  100. delete content;
  101. }
  102. public: // modifiers
  103. /// Exchange of the contents of `*this` and `rhs`.
  104. ///
  105. /// \returns `*this`
  106. /// \throws Nothing.
  107. any & swap(any & rhs) noexcept
  108. {
  109. placeholder* tmp = content;
  110. content = rhs.content;
  111. rhs.content = tmp;
  112. return *this;
  113. }
  114. /// Copies content of `rhs` into
  115. /// current instance, discarding previous content, so that the
  116. /// new content is equivalent in both type and value to the
  117. /// content of `rhs`, or empty if `rhs.empty()`.
  118. ///
  119. /// \throws std::bad_alloc
  120. /// or any exceptions arising from the copy constructor of the
  121. /// contained type. Assignment satisfies the strong guarantee
  122. /// of exception safety.
  123. any & operator=(const any& rhs)
  124. {
  125. any(rhs).swap(*this);
  126. return *this;
  127. }
  128. /// Moves content of `rhs` into
  129. /// current instance, discarding previous content, so that the
  130. /// new content is equivalent in both type and value to the
  131. /// content of `rhs` before move, or empty if
  132. /// `rhs.empty()`.
  133. ///
  134. /// \post `rhs->empty()` is true
  135. /// \throws Nothing.
  136. any & operator=(any&& rhs) noexcept
  137. {
  138. rhs.swap(*this);
  139. any().swap(rhs);
  140. return *this;
  141. }
  142. /// Forwards `rhs`,
  143. /// discarding previous content, so that the new content of is
  144. /// equivalent in both type and value to
  145. /// `rhs` before forward.
  146. ///
  147. /// \throws std::bad_alloc
  148. /// or any exceptions arising from the move or copy constructor of the
  149. /// contained type. Assignment satisfies the strong guarantee
  150. /// of exception safety.
  151. template <class ValueType>
  152. any & operator=(ValueType&& rhs)
  153. {
  154. static_assert(
  155. !anys::detail::is_basic_any<typename std::decay<ValueType>::type>::value,
  156. "boost::anys::basic_any shall not be assigned into boost::any"
  157. );
  158. any(std::forward<ValueType>(rhs)).swap(*this);
  159. return *this;
  160. }
  161. public: // queries
  162. /// \returns `true` if instance is empty, otherwise `false`.
  163. /// \throws Nothing.
  164. bool empty() const noexcept
  165. {
  166. return !content;
  167. }
  168. /// \post this->empty() is true
  169. void clear() noexcept
  170. {
  171. any().swap(*this);
  172. }
  173. /// \returns the `typeid` of the
  174. /// contained value if instance is non-empty, otherwise
  175. /// `typeid(void)`.
  176. ///
  177. /// Useful for querying against types known either at compile time or
  178. /// only at runtime.
  179. const boost::typeindex::type_info& type() const noexcept
  180. {
  181. return content ? content->type() : boost::typeindex::type_id<void>().type_info();
  182. }
  183. private: // types
  184. /// @cond
  185. class BOOST_SYMBOL_VISIBLE placeholder: public boost::anys::detail::placeholder
  186. {
  187. public:
  188. virtual placeholder * clone() const = 0;
  189. };
  190. template<typename ValueType>
  191. class holder final
  192. : public placeholder
  193. {
  194. public: // structors
  195. holder(const ValueType & value)
  196. : held(value)
  197. {
  198. }
  199. holder(ValueType&& value)
  200. : held(static_cast< ValueType&& >(value))
  201. {
  202. }
  203. public: // queries
  204. const boost::typeindex::type_info& type() const noexcept override
  205. {
  206. return boost::typeindex::type_id<ValueType>().type_info();
  207. }
  208. placeholder * clone() const BOOST_OVERRIDE
  209. {
  210. return new holder(held);
  211. }
  212. public: // representation
  213. ValueType held;
  214. private: // intentionally left unimplemented
  215. holder & operator=(const holder &);
  216. };
  217. private: // representation
  218. template<typename ValueType>
  219. friend ValueType * unsafe_any_cast(any *) noexcept;
  220. friend class boost::anys::unique_any;
  221. placeholder * content;
  222. /// @endcond
  223. };
  224. /// Exchange of the contents of `lhs` and `rhs`.
  225. /// \throws Nothing.
  226. inline void swap(any & lhs, any & rhs) noexcept
  227. {
  228. lhs.swap(rhs);
  229. }
  230. /// @cond
  231. // Note: The "unsafe" versions of any_cast are not part of the
  232. // public interface and may be removed at any time. They are
  233. // required where we know what type is stored in the any and can't
  234. // use typeid() comparison, e.g., when our types may travel across
  235. // different shared libraries.
  236. template<typename ValueType>
  237. inline ValueType * unsafe_any_cast(any * operand) noexcept
  238. {
  239. return std::addressof(
  240. static_cast<any::holder<ValueType> *>(operand->content)->held
  241. );
  242. }
  243. template<typename ValueType>
  244. inline const ValueType * unsafe_any_cast(const any * operand) noexcept
  245. {
  246. return boost::unsafe_any_cast<ValueType>(const_cast<any *>(operand));
  247. }
  248. /// @endcond
  249. /// \returns Pointer to a ValueType stored in `operand`, nullptr if
  250. /// `operand` does not contain specified `ValueType`.
  251. template<typename ValueType>
  252. ValueType * any_cast(any * operand) noexcept
  253. {
  254. return operand && operand->type() == boost::typeindex::type_id<ValueType>()
  255. ? boost::unsafe_any_cast<typename std::remove_cv<ValueType>::type>(operand)
  256. : 0;
  257. }
  258. /// \returns Const pointer to a ValueType stored in `operand`, nullptr if
  259. /// `operand` does not contain specified `ValueType`.
  260. template<typename ValueType>
  261. inline const ValueType * any_cast(const any * operand) noexcept
  262. {
  263. return boost::any_cast<ValueType>(const_cast<any *>(operand));
  264. }
  265. /// \returns ValueType stored in `operand`
  266. /// \throws boost::bad_any_cast if `operand` does not contain
  267. /// specified ValueType.
  268. template<typename ValueType>
  269. ValueType any_cast(any & operand)
  270. {
  271. using nonref = typename std::remove_reference<ValueType>::type;
  272. nonref * result = boost::any_cast<nonref>(std::addressof(operand));
  273. if(!result)
  274. boost::throw_exception(bad_any_cast());
  275. // Attempt to avoid construction of a temporary object in cases when
  276. // `ValueType` is not a reference. Example:
  277. // `static_cast<std::string>(*result);`
  278. // which is equal to `std::string(*result);`
  279. typedef typename std::conditional<
  280. std::is_reference<ValueType>::value,
  281. ValueType,
  282. typename std::add_lvalue_reference<ValueType>::type
  283. >::type ref_type;
  284. #ifdef BOOST_MSVC
  285. # pragma warning(push)
  286. # pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local!
  287. #endif
  288. return static_cast<ref_type>(*result);
  289. #ifdef BOOST_MSVC
  290. # pragma warning(pop)
  291. #endif
  292. }
  293. /// \returns `ValueType` stored in `operand`
  294. /// \throws boost::bad_any_cast if `operand` does not contain
  295. /// specified `ValueType`.
  296. template<typename ValueType>
  297. inline ValueType any_cast(const any & operand)
  298. {
  299. using nonref = typename std::remove_reference<ValueType>::type;
  300. return boost::any_cast<const nonref &>(const_cast<any &>(operand));
  301. }
  302. /// \returns `ValueType` stored in `operand`, leaving the `operand` empty.
  303. /// \throws boost::bad_any_cast if `operand` does not contain
  304. /// specified `ValueType`.
  305. template<typename ValueType>
  306. inline ValueType any_cast(any&& operand)
  307. {
  308. static_assert(
  309. std::is_rvalue_reference<ValueType&&>::value /*true if ValueType is rvalue or just a value*/
  310. || std::is_const< typename std::remove_reference<ValueType>::type >::value,
  311. "boost::any_cast shall not be used for getting nonconst references to temporary objects"
  312. );
  313. return boost::any_cast<ValueType>(operand);
  314. }
  315. BOOST_ANY_END_MODULE_EXPORT
  316. }
  317. // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
  318. // Copyright Antony Polukhin, 2013-2025.
  319. //
  320. // Distributed under the Boost Software License, Version 1.0. (See
  321. // accompanying file LICENSE_1_0.txt or copy at
  322. // http://www.boost.org/LICENSE_1_0.txt)
  323. #endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT)
  324. #endif