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