Chris@16: // See http://www.boost.org/libs/any for Documentation. Chris@16: Chris@16: #ifndef BOOST_ANY_INCLUDED Chris@16: #define BOOST_ANY_INCLUDED Chris@16: Chris@101: #if defined(_MSC_VER) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: // what: variant type boost::any Chris@16: // who: contributed by Kevlin Henney, Chris@16: // with features contributed and bugs found by Chris@16: // Antony Polukhin, Ed Brey, Mark Rodgers, Chris@16: // Peter Dimov, and James Curran Chris@16: // when: July 2001, April 2013 - May 2013 Chris@16: Chris@16: #include Chris@16: Chris@16: #include "boost/config.hpp" Chris@101: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: class any Chris@16: { Chris@16: public: // structors Chris@16: Chris@16: any() BOOST_NOEXCEPT Chris@16: : content(0) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: any(const ValueType & value) Chris@101: : content(new holder< Chris@101: BOOST_DEDUCED_TYPENAME remove_cv::type>::type Chris@101: >(value)) Chris@16: { Chris@16: } Chris@16: Chris@16: any(const any & other) Chris@16: : content(other.content ? other.content->clone() : 0) Chris@16: { Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: // Move constructor Chris@16: any(any&& other) BOOST_NOEXCEPT Chris@16: : content(other.content) Chris@16: { Chris@16: other.content = 0; Chris@16: } Chris@16: Chris@16: // Perfect forwarding of ValueType Chris@16: template Chris@16: any(ValueType&& value Chris@16: , typename boost::disable_if >::type* = 0 // disable if value has type `any&` Chris@16: , typename boost::disable_if >::type* = 0) // disable if value has type `const ValueType&&` Chris@16: : content(new holder< typename decay::type >(static_cast(value))) Chris@16: { Chris@16: } Chris@16: #endif Chris@16: Chris@16: ~any() BOOST_NOEXCEPT Chris@16: { Chris@16: delete content; Chris@16: } Chris@16: Chris@16: public: // modifiers Chris@16: Chris@16: any & swap(any & rhs) BOOST_NOEXCEPT Chris@16: { Chris@16: std::swap(content, rhs.content); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: Chris@16: #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: template Chris@16: any & operator=(const ValueType & rhs) Chris@16: { Chris@16: any(rhs).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: any & operator=(any rhs) Chris@16: { Chris@16: any(rhs).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: #else Chris@16: any & operator=(const any& rhs) Chris@16: { Chris@16: any(rhs).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // move assignement Chris@16: any & operator=(any&& rhs) BOOST_NOEXCEPT Chris@16: { Chris@16: rhs.swap(*this); Chris@16: any().swap(rhs); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Perfect forwarding of ValueType Chris@16: template Chris@16: any & operator=(ValueType&& rhs) Chris@16: { Chris@16: any(static_cast(rhs)).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: Chris@16: public: // queries Chris@16: Chris@16: bool empty() const BOOST_NOEXCEPT Chris@16: { Chris@16: return !content; Chris@16: } Chris@16: Chris@16: void clear() BOOST_NOEXCEPT Chris@16: { Chris@16: any().swap(*this); Chris@16: } Chris@16: Chris@101: const boost::typeindex::type_info& type() const BOOST_NOEXCEPT Chris@16: { Chris@101: return content ? content->type() : boost::typeindex::type_id().type_info(); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS Chris@16: private: // types Chris@16: #else Chris@16: public: // types (public so any_cast can be non-friend) Chris@16: #endif Chris@16: Chris@16: class placeholder Chris@16: { Chris@16: public: // structors Chris@16: Chris@16: virtual ~placeholder() Chris@16: { Chris@16: } Chris@16: Chris@16: public: // queries Chris@16: Chris@101: virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT = 0; Chris@16: Chris@16: virtual placeholder * clone() const = 0; Chris@16: Chris@16: }; Chris@16: Chris@16: template Chris@16: class holder : public placeholder Chris@16: { Chris@16: public: // structors Chris@16: Chris@16: holder(const ValueType & value) Chris@16: : held(value) Chris@16: { Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: holder(ValueType&& value) Chris@16: : held(static_cast< ValueType&& >(value)) Chris@16: { Chris@16: } Chris@16: #endif Chris@16: public: // queries Chris@16: Chris@101: virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT Chris@16: { Chris@101: return boost::typeindex::type_id().type_info(); Chris@16: } Chris@16: Chris@16: virtual placeholder * clone() const Chris@16: { Chris@16: return new holder(held); Chris@16: } Chris@16: Chris@16: public: // representation Chris@16: Chris@16: ValueType held; Chris@16: Chris@16: private: // intentionally left unimplemented Chris@16: holder & operator=(const holder &); Chris@16: }; Chris@16: Chris@16: #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS Chris@16: Chris@16: private: // representation Chris@16: Chris@16: template Chris@16: friend ValueType * any_cast(any *) BOOST_NOEXCEPT; Chris@16: Chris@16: template Chris@16: friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT; Chris@16: Chris@16: #else Chris@16: Chris@16: public: // representation (public so any_cast can be non-friend) Chris@16: Chris@16: #endif Chris@16: Chris@16: placeholder * content; Chris@16: Chris@16: }; Chris@16: Chris@16: inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT Chris@16: { Chris@16: lhs.swap(rhs); Chris@16: } Chris@16: Chris@101: class BOOST_SYMBOL_VISIBLE bad_any_cast : Chris@101: #ifndef BOOST_NO_RTTI Chris@101: public std::bad_cast Chris@101: #else Chris@101: public std::exception Chris@101: #endif Chris@16: { Chris@16: public: Chris@16: virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW Chris@16: { Chris@16: return "boost::bad_any_cast: " Chris@16: "failed conversion using boost::any_cast"; Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: ValueType * any_cast(any * operand) BOOST_NOEXCEPT Chris@16: { Chris@101: return operand && operand->type() == boost::typeindex::type_id() Chris@101: ? &static_cast::type> *>(operand->content)->held Chris@16: : 0; Chris@16: } Chris@16: Chris@16: template Chris@16: inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT Chris@16: { Chris@16: return any_cast(const_cast(operand)); Chris@16: } Chris@16: Chris@16: template Chris@16: ValueType any_cast(any & operand) Chris@16: { Chris@16: typedef BOOST_DEDUCED_TYPENAME remove_reference::type nonref; Chris@16: Chris@16: Chris@16: nonref * result = any_cast(&operand); Chris@16: if(!result) Chris@16: boost::throw_exception(bad_any_cast()); Chris@16: Chris@16: // Attempt to avoid construction of a temporary object in cases when Chris@16: // `ValueType` is not a reference. Example: Chris@16: // `static_cast(*result);` Chris@16: // which is equal to `std::string(*result);` Chris@16: typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< Chris@16: boost::is_reference, Chris@16: ValueType, Chris@16: BOOST_DEDUCED_TYPENAME boost::add_reference::type Chris@16: >::type ref_type; Chris@16: Chris@16: return static_cast(*result); Chris@16: } Chris@16: Chris@16: template Chris@16: inline ValueType any_cast(const any & operand) Chris@16: { Chris@16: typedef BOOST_DEDUCED_TYPENAME remove_reference::type nonref; Chris@16: return any_cast(const_cast(operand)); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: template Chris@101: inline ValueType any_cast(any&& operand) Chris@16: { Chris@16: BOOST_STATIC_ASSERT_MSG( Chris@101: boost::is_rvalue_reference::value /*true if ValueType is rvalue or just a value*/ Chris@16: || boost::is_const< typename boost::remove_reference::type >::value, Chris@16: "boost::any_cast shall not be used for getting nonconst references to temporary objects" Chris@16: ); Chris@101: return any_cast(operand); Chris@16: } Chris@16: #endif Chris@16: Chris@16: Chris@16: // Note: The "unsafe" versions of any_cast are not part of the Chris@16: // public interface and may be removed at any time. They are Chris@16: // required where we know what type is stored in the any and can't Chris@16: // use typeid() comparison, e.g., when our types may travel across Chris@16: // different shared libraries. Chris@16: template Chris@16: inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT Chris@16: { Chris@16: return &static_cast *>(operand->content)->held; Chris@16: } Chris@16: Chris@16: template Chris@16: inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT Chris@16: { Chris@16: return unsafe_any_cast(const_cast(operand)); Chris@16: } Chris@16: } Chris@16: Chris@16: // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #endif