#ifndef BOOST_ANY_INCLUDED #define BOOST_ANY_INCLUDED // what: variant type any // who: contributed by Kevlin Henney, // with features contributed and bugs found by // Ed Brey, Mark Rodgers, Peter Dimov, and James Curran // when: October 2000 // where: tested with BCC 5.5 and MSVC 6.0 #include #include #ifdef COMPILING_MSVC #define MSVC_INCLUDE(code) code #define MSVC_EXCLUDE(code) #else #define MSVC_INCLUDE(code) #define MSVC_EXCLUDE(code) code #endif namespace boost { class any { public: // structors any() : content(0) { } template any(const ValueType & value) : content(new holder(value)) { } MSVC_INCLUDE(template<>) any(const any & other) : content(other.content ? other.content->clone() : 0) { } ~any() { delete content; } public: // modifiers any & swap(any & rhs) { std::swap(content, rhs.content); return *this; } template any & operator=(const ValueType & rhs) { any(rhs).swap(*this); return *this; } MSVC_INCLUDE(template<>) any & operator=(const any & rhs) { any(rhs).swap(*this); return *this; } public: // queries operator const void *() const { return content ? &typeid(void) : 0; } const std::type_info & type() const { return content ? content->type() : typeid(void); } template bool copy_to(ValueType & value) const { const ValueType * copyable = to_ptr MSVC_EXCLUDE()(MSVC_INCLUDE(&value)); if(copyable) { value = *copyable; } return copyable; } template ValueType * to_ptr(MSVC_INCLUDE(ValueType * = 0)) { return type() == typeid(ValueType) ? &static_cast *>(content)->held : 0; } template const ValueType * to_ptr(MSVC_INCLUDE(ValueType * dummy = 0)) const { return const_cast(this)-> to_ptr MSVC_EXCLUDE()(MSVC_INCLUDE(dummy)); } private: // types class placeholder { public: // structors virtual ~placeholder() { } public: // queries virtual const std::type_info & type() const = 0; virtual placeholder * clone() const = 0; }; template class holder : public placeholder { public: // structors holder(const ValueType & value) : held(value) { } public: // queries virtual const std::type_info & type() const { return typeid(ValueType); } virtual placeholder * clone() const { return new holder(held); } public: // representation ValueType held; }; private: // representation placeholder * content; }; class bad_any_cast : public std::bad_cast { public: virtual const char *what() const { return "boost::bad_any_cast: " "failed conversion using boost::any_cast"; } }; template ValueType any_cast(const any & operand) { const ValueType * result = operand.to_ptr MSVC_EXCLUDE()( MSVC_INCLUDE(static_cast(0))); if(!result) { throw bad_any_cast(); } return *result; } } // Copyright Kevlin Henney, 2000. All rights reserved. // // Permission to use, copy, modify, and distribute this software for any // purpose is hereby granted without fee, provided that this copyright and // permissions notice appear in all copies and derivatives, and that no // charge may be made for the software and its documentation except to cover // cost of distribution. // // This software is provided "as is" without express or implied warranty. #endif