You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
253 lines
6.4 KiB
253 lines
6.4 KiB
// See http://www.boost.org/libs/any for Documentation. |
|
|
|
#ifndef BOOST_ANY_INCLUDED |
|
#define BOOST_ANY_INCLUDED |
|
|
|
// what: variant type boost::any |
|
// who: contributed by Kevlin Henney, |
|
// with features contributed and bugs found by |
|
// Ed Brey, Mark Rodgers, Peter Dimov, and James Curran |
|
// when: July 2001 |
|
// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95 |
|
|
|
#include <algorithm> |
|
#include <typeinfo> |
|
|
|
#include "boost/config.hpp" |
|
#include <boost/type_traits/remove_reference.hpp> |
|
#include <boost/type_traits/is_reference.hpp> |
|
#include <boost/throw_exception.hpp> |
|
#include <boost/static_assert.hpp> |
|
|
|
// See boost/python/type_id.hpp |
|
// TODO: add BOOST_TYPEID_COMPARE_BY_NAME to config.hpp |
|
# if (defined(__GNUC__) && __GNUC__ >= 3) \ |
|
|| defined(_AIX) \ |
|
|| ( defined(__sgi) && defined(__host_mips)) \ |
|
|| (defined(__hpux) && defined(__HP_aCC)) \ |
|
|| (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC)) |
|
# define BOOST_AUX_ANY_TYPE_ID_NAME |
|
#include <cstring> |
|
# endif |
|
|
|
namespace boost |
|
{ |
|
class any |
|
{ |
|
public: // structors |
|
|
|
any() |
|
: content(0) |
|
{ |
|
} |
|
|
|
template<typename ValueType> |
|
any(const ValueType & value) |
|
: content(new holder<ValueType>(value)) |
|
{ |
|
} |
|
|
|
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<typename ValueType> |
|
any & operator=(const ValueType & rhs) |
|
{ |
|
any(rhs).swap(*this); |
|
return *this; |
|
} |
|
|
|
any & operator=(any rhs) |
|
{ |
|
rhs.swap(*this); |
|
return *this; |
|
} |
|
|
|
public: // queries |
|
|
|
bool empty() const |
|
{ |
|
return !content; |
|
} |
|
|
|
const std::type_info & type() const |
|
{ |
|
return content ? content->type() : typeid(void); |
|
} |
|
|
|
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS |
|
private: // types |
|
#else |
|
public: // types (public so any_cast can be non-friend) |
|
#endif |
|
|
|
class placeholder |
|
{ |
|
public: // structors |
|
|
|
virtual ~placeholder() |
|
{ |
|
} |
|
|
|
public: // queries |
|
|
|
virtual const std::type_info & type() const = 0; |
|
|
|
virtual placeholder * clone() const = 0; |
|
|
|
}; |
|
|
|
template<typename ValueType> |
|
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: // intentionally left unimplemented |
|
holder & operator=(const holder &); |
|
}; |
|
|
|
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS |
|
|
|
private: // representation |
|
|
|
template<typename ValueType> |
|
friend ValueType * any_cast(any *); |
|
|
|
template<typename ValueType> |
|
friend ValueType * unsafe_any_cast(any *); |
|
|
|
#else |
|
|
|
public: // representation (public so any_cast can be non-friend) |
|
|
|
#endif |
|
|
|
placeholder * content; |
|
|
|
}; |
|
|
|
class bad_any_cast : public std::bad_cast |
|
{ |
|
public: |
|
virtual const char * what() const throw() |
|
{ |
|
return "boost::bad_any_cast: " |
|
"failed conversion using boost::any_cast"; |
|
} |
|
}; |
|
|
|
template<typename ValueType> |
|
ValueType * any_cast(any * operand) |
|
{ |
|
return operand && |
|
#ifdef BOOST_AUX_ANY_TYPE_ID_NAME |
|
std::strcmp(operand->type().name(), typeid(ValueType).name()) == 0 |
|
#else |
|
operand->type() == typeid(ValueType) |
|
#endif |
|
? &static_cast<any::holder<ValueType> *>(operand->content)->held |
|
: 0; |
|
} |
|
|
|
template<typename ValueType> |
|
inline const ValueType * any_cast(const any * operand) |
|
{ |
|
return any_cast<ValueType>(const_cast<any *>(operand)); |
|
} |
|
|
|
template<typename ValueType> |
|
ValueType any_cast(any & operand) |
|
{ |
|
typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref; |
|
|
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|
// If 'nonref' is still reference type, it means the user has not |
|
// specialized 'remove_reference'. |
|
|
|
// Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro |
|
// to generate specialization of remove_reference for your class |
|
// See type traits library documentation for details |
|
BOOST_STATIC_ASSERT(!is_reference<nonref>::value); |
|
#endif |
|
|
|
nonref * result = any_cast<nonref>(&operand); |
|
if(!result) |
|
boost::throw_exception(bad_any_cast()); |
|
return *result; |
|
} |
|
|
|
template<typename ValueType> |
|
inline ValueType any_cast(const any & operand) |
|
{ |
|
typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref; |
|
|
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|
// The comment in the above version of 'any_cast' explains when this |
|
// assert is fired and what to do. |
|
BOOST_STATIC_ASSERT(!is_reference<nonref>::value); |
|
#endif |
|
|
|
return any_cast<const nonref &>(const_cast<any &>(operand)); |
|
} |
|
|
|
// Note: The "unsafe" versions of any_cast are not part of the |
|
// public interface and may be removed at any time. They are |
|
// required where we know what type is stored in the any and can't |
|
// use typeid() comparison, e.g., when our types may travel across |
|
// different shared libraries. |
|
template<typename ValueType> |
|
inline ValueType * unsafe_any_cast(any * operand) |
|
{ |
|
return &static_cast<any::holder<ValueType> *>(operand->content)->held; |
|
} |
|
|
|
template<typename ValueType> |
|
inline const ValueType * unsafe_any_cast(const any * operand) |
|
{ |
|
return unsafe_any_cast<ValueType>(const_cast<any *>(operand)); |
|
} |
|
} |
|
|
|
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. |
|
// |
|
// Distributed under the Boost Software License, Version 1.0. (See |
|
// accompanying file LICENSE_1_0.txt or copy at |
|
// http://www.boost.org/LICENSE_1_0.txt) |
|
|
|
#endif
|
|
|