
This is an enhanced version of Unai Uribarri's patch (see http://lists.boost.org/MailArchives/boost/msg42284.php ). Adds support for the following syntax: boost::any a = 7; int& i = any_cast<int&>(a); Current syntax for reference extraction is int& i = *any_cast<int>(&a); Old syntax is preserved. On compilers without support for partial template specialization users are required to provide explicit specializations of boost::remove_reference for their classes (usually via BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION) if they want to use the new syntax. Patch was tested on msvc 6 and 7.1, intel 8.1 and gcc 3.3.1. If this patch will be accepted, I'll write tests/update documentation. --- any.hpp Thu Sep 16 11:23:30 2004 +++ new_any.hpp Fri Dec 10 19:47:45 2004 @@ -15,6 +15,12 @@ #include "boost/config.hpp" #include <boost/throw_exception.hpp> +#include <boost/type_traits/remove_reference.hpp> + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#include <boost/type_traits/is_reference.hpp> +#include <boost/static_assert.hpp> +#endif namespace boost { @@ -168,12 +174,39 @@ } template<typename ValueType> - ValueType any_cast(const any & operand) + const ValueType any_cast(const any & operand) { - const ValueType * result = any_cast<ValueType>(&operand); + #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // 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(!::boost::is_reference< + boost::remove_reference<ValueType>::type >::value); + + #endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + typedef typename boost::remove_reference<ValueType>::type Type; + const Type * result = any_cast<Type>(&operand); if(!result) boost::throw_exception(bad_any_cast()); return *result; + } + + template<typename ValueType> + ValueType any_cast(any & operand) + { + #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // 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(!::boost::is_reference< + boost::remove_reference<ValueType>::type >::value); + + #endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + typedef typename boost::remove_reference<ValueType>::type Type; + Type * result = any_cast<Type>(&operand); + if(!result) + boost::throw_exception(bad_any_cast()); + return *result; } }