[PATCH]Enhancing any_cast

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; } }

Mikhail Glushenkov wrote:
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.
Hello Mikhail, I've updated your patch to properly support T volatile x; any a(x); It has been tested under Gentoo Linux on g++ 3.3.4 (hardened) and Intel 8.0 with and without BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION. -- Alexander Nasonov

Alexander Nasonov <alnsn <at> yandex.ru> writes:
Hello Mikhail, I've updated your patch to properly support T volatile x; any a(x); It has been tested under Gentoo Linux on g++ 3.3.4 (hardened) and Intel 8.0 with and without BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION. -- Alexander Nasonov
Thanks! Do you know if/when this patch will be added? (I notified Kevlin but he hasn't responded yet.)

I totally forgot about broken typename in bcc. It's fixed in attached any.hpp.
Alexander Nasonov writes:
Hello Mikhail, I've updated your patch to properly support T volatile x; any a(x);
I forgot to mention that the original version has small problem with any_cast to const type. If any stores T and you cast it to T const you're trying this sequence of static_casts: holder<T>* -> (in ctor) -> placeholder* -> (in any_cast) -> holder<T const>* Obviously, it's not getting back to original holder<T> type.
It has been tested under Gentoo Linux on g++ 3.3.4 (hardened) and Intel 8.0 with and without BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION.
Now tested on borland 5.5.1 and on VC++ 7.1 (free command line tool). Mikhail Glushenkov wrote:
Thanks! Do you know if/when this patch will be added? (I notified Kevlin but he hasn't responded yet.)
Let's wait for his reply. -- Alexander Nasonov
participants (2)
-
Alexander Nasonov
-
Mikhail Glushenkov