any.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // See http://www.boost.org/libs/any for Documentation.
  2. #ifndef BOOST_ANY_INCLUDED
  3. #define BOOST_ANY_INCLUDED
  4. // what: variant type boost::any
  5. // who: contributed by Kevlin Henney,
  6. // with features contributed and bugs found by
  7. // Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
  8. // when: July 2001
  9. // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
  10. #include <algorithm>
  11. #include <typeinfo>
  12. #include "boost/config.hpp"
  13. #include <boost/type_traits/remove_reference.hpp>
  14. #include <boost/type_traits/is_reference.hpp>
  15. #include <boost/throw_exception.hpp>
  16. #include <boost/static_assert.hpp>
  17. namespace boost
  18. {
  19. class any
  20. {
  21. public: // structors
  22. any()
  23. : content(0)
  24. {
  25. }
  26. template<typename ValueType>
  27. any(const ValueType & value)
  28. : content(new holder<ValueType>(value))
  29. {
  30. }
  31. any(const any & other)
  32. : content(other.content ? other.content->clone() : 0)
  33. {
  34. }
  35. ~any()
  36. {
  37. delete content;
  38. }
  39. public: // modifiers
  40. any & swap(any & rhs)
  41. {
  42. std::swap(content, rhs.content);
  43. return *this;
  44. }
  45. template<typename ValueType>
  46. any & operator=(const ValueType & rhs)
  47. {
  48. any(rhs).swap(*this);
  49. return *this;
  50. }
  51. any & operator=(any rhs)
  52. {
  53. rhs.swap(*this);
  54. return *this;
  55. }
  56. public: // queries
  57. bool empty() const
  58. {
  59. return !content;
  60. }
  61. const std::type_info & type() const
  62. {
  63. return content ? content->type() : typeid(void);
  64. }
  65. #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
  66. private: // types
  67. #else
  68. public: // types (public so any_cast can be non-friend)
  69. #endif
  70. class placeholder
  71. {
  72. public: // structors
  73. virtual ~placeholder()
  74. {
  75. }
  76. public: // queries
  77. virtual const std::type_info & type() const = 0;
  78. virtual placeholder * clone() const = 0;
  79. };
  80. template<typename ValueType>
  81. class holder : public placeholder
  82. {
  83. public: // structors
  84. holder(const ValueType & value)
  85. : held(value)
  86. {
  87. }
  88. public: // queries
  89. virtual const std::type_info & type() const
  90. {
  91. return typeid(ValueType);
  92. }
  93. virtual placeholder * clone() const
  94. {
  95. return new holder(held);
  96. }
  97. public: // representation
  98. ValueType held;
  99. private: // intentionally left unimplemented
  100. holder & operator=(const holder &);
  101. };
  102. #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
  103. private: // representation
  104. template<typename ValueType>
  105. friend ValueType * any_cast(any *);
  106. template<typename ValueType>
  107. friend ValueType * unsafe_any_cast(any *);
  108. #else
  109. public: // representation (public so any_cast can be non-friend)
  110. #endif
  111. placeholder * content;
  112. };
  113. class bad_any_cast : public std::bad_cast
  114. {
  115. public:
  116. virtual const char * what() const throw()
  117. {
  118. return "boost::bad_any_cast: "
  119. "failed conversion using boost::any_cast";
  120. }
  121. };
  122. template<typename ValueType>
  123. ValueType * any_cast(any * operand)
  124. {
  125. return operand && operand->type() == typeid(ValueType)
  126. ? &static_cast<any::holder<ValueType> *>(operand->content)->held
  127. : 0;
  128. }
  129. template<typename ValueType>
  130. inline const ValueType * any_cast(const any * operand)
  131. {
  132. return any_cast<ValueType>(const_cast<any *>(operand));
  133. }
  134. template<typename ValueType>
  135. ValueType any_cast(any & operand)
  136. {
  137. typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
  138. #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  139. // If 'nonref' is still reference type, it means the user has not
  140. // specialized 'remove_reference'.
  141. // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
  142. // to generate specialization of remove_reference for your class
  143. // See type traits library documentation for details
  144. BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
  145. #endif
  146. nonref * result = any_cast<nonref>(&operand);
  147. if(!result)
  148. boost::throw_exception(bad_any_cast());
  149. return *result;
  150. }
  151. template<typename ValueType>
  152. inline ValueType any_cast(const any & operand)
  153. {
  154. typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
  155. #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  156. // The comment in the above version of 'any_cast' explains when this
  157. // assert is fired and what to do.
  158. BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
  159. #endif
  160. return any_cast<const nonref &>(const_cast<any &>(operand));
  161. }
  162. // Note: The "unsafe" versions of any_cast are not part of the
  163. // public interface and may be removed at any time. They are
  164. // required where we know what type is stored in the any and can't
  165. // use typeid() comparison, e.g., when our types may travel across
  166. // different shared libraries.
  167. template<typename ValueType>
  168. inline ValueType * unsafe_any_cast(any * operand)
  169. {
  170. return &static_cast<any::holder<ValueType> *>(operand->content)->held;
  171. }
  172. template<typename ValueType>
  173. inline const ValueType * unsafe_any_cast(const any * operand)
  174. {
  175. return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
  176. }
  177. }
  178. // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
  179. //
  180. // Distributed under the Boost Software License, Version 1.0. (See
  181. // accompanying file LICENSE_1_0.txt or copy at
  182. // http://www.boost.org/LICENSE_1_0.txt)
  183. #endif