It works with GCC 3.2, but I need help with Visual C++ 6; I get an internal compiler error. Also, I'm finding people to test it with other compilers.
Index: boost/boost/any.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/any.hpp,v retrieving revision 1.6 diff -u -r1.6 any.hpp --- boost/boost/any.hpp 23 Dec 2002 02:43:12 -0000 1.6 +++ boost/boost/any.hpp 27 Jan 2003 23:01:15 -0000 @@ -17,6 +17,17 @@ namespace boost { + class any; + + namespace detail + { + template <typename T> + struct type_tag {}; + + template <typename Type> + Type *any_cast_impl(any *op, type_tag<Type*>); + } + class any { public: // structors @@ -129,8 +140,8 @@ private: // representation - template<typename ValueType> - friend ValueType * any_cast(any *); + template<typename Type> + friend Type *detail::any_cast_impl(any *, detail::type_tag<Type*>); #else @@ -152,29 +163,68 @@ } }; - template<typename ValueType> - ValueType * any_cast(any * operand) + namespace detail { - return operand && operand->type() == typeid(ValueType) - ? &static_cast<any::holder<ValueType> *>(operand->content)->held - : 0; + template <typename Type> + Type *any_cast_impl(any *op, type_tag<Type*>) + { + if (op && op->type() == typeid(Type)) + return &static_cast<any::holder<Type>*>(op->content)->held; + else + return NULL; + } + + template <typename Type> + const Type *any_cast_impl(const any *op, type_tag<const Type *>) + { + return any_cast_impl(const_cast<any*>(op), type_tag<Type*>()); + } + + template <typename Type> + Type &any_cast_impl(any &op, type_tag<Type&>) + { + Type *tmp=any_cast_impl(&op, type_tag<Type*>()); + if (!tmp) + throw bad_any_cast(); + return *tmp; + } + + template <typename Type> + const Type &any_cast_impl(const any &op, type_tag<const Type &>) + { + return any_cast_impl(const_cast<any&>(op), type_tag<Type&>()); + } + + template <typename Type> + Type any_cast_impl(const any &op, type_tag<Type>) + { + return any_cast_impl(op, type_tag<const Type &>()); + } + }; + + template<typename Type> + Type any_cast(any *operand) + { + return detail::any_cast_impl(operand, detail::type_tag<Type>()); } - template<typename ValueType> - const ValueType * any_cast(const any * operand) + template<typename Type> + Type any_cast(const any *operand) { - return any_cast<ValueType>(const_cast<any *>(operand)); + return detail::any_cast_impl(operand, detail::type_tag<Type>()); } - template<typename ValueType> - ValueType any_cast(const any & operand) + template<typename Type> + Type any_cast(any &operand) { - const ValueType * result = any_cast<ValueType>(&operand); - if(!result) - throw bad_any_cast(); - return *result; + return detail::any_cast_impl(operand, detail::type_tag<Type>()); } + template<typename Type> + Type any_cast(const any &operand) + { + return detail::any_cast_impl(operand, detail::type_tag<Type>()); + } } // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. Index: boost/libs/any/any_test.cpp =================================================================== RCS file: /cvsroot/boost/boost/libs/any/any_test.cpp,v retrieving revision 1.2 diff -u -r1.2 any_test.cpp --- boost/libs/any/any_test.cpp 3 Dec 2002 19:08:54 -0000 1.2 +++ boost/libs/any/any_test.cpp 27 Jan 2003 23:01:17 -0000 @@ -67,7 +67,7 @@ const any value; check_true(value.empty(), "empty"); - check_null(any_cast<int>(&value), "any_cast<int>"); + check_null(any_cast<int const *>(&value), "any_cast<int*>"); check_equal(value.type(), typeid(void), "type"); } @@ -78,13 +78,14 @@ check_false(value.empty(), "empty"); check_equal(value.type(), typeid(std::string), "type"); - check_null(any_cast<int>(&value), "any_cast<int>"); - check_non_null(any_cast<std::string>(&value), "any_cast<std::string>"); + check_null(any_cast<int*>(&value), "any_cast<int*>"); + check_non_null(any_cast<std::string*>(&value), + "any_cast<std::string*>"); check_equal( - any_cast<std::string>(value), text, + any_cast<std::string&>(value), text, "comparing cast copy against original text"); check_unequal( - any_cast<std::string>(&value), &text, + any_cast<std::string*>(&value), &text, "comparing address in copy against original text"); } @@ -96,14 +97,14 @@ check_false(copy.empty(), "empty"); check_equal(original.type(), copy.type(), "type"); check_equal( - any_cast<std::string>(original), any_cast<std::string>(copy), + any_cast<std::string&>(original), any_cast<std::string&>(copy), "comparing cast copy against original"); check_equal( - text, any_cast<std::string>(copy), + text, any_cast<std::string&>(copy), "comparing cast copy against original text"); check_unequal( - any_cast<std::string>(&original), - any_cast<std::string>(©), + any_cast<std::string*>(&original), + any_cast<std::string*>(©), "comparing address in copy against original"); } @@ -116,14 +117,14 @@ check_false(copy.empty(), "empty"); check_equal(original.type(), copy.type(), "type"); check_equal( - any_cast<std::string>(original), any_cast<std::string>(copy), + any_cast<std::string&>(original), any_cast<std::string&>(copy), "comparing cast copy against cast original"); check_equal( - text, any_cast<std::string>(copy), + text, any_cast<std::string&>(copy), "comparing cast copy against original text"); check_unequal( - any_cast<std::string>(&original), - any_cast<std::string>(©), + any_cast<std::string*>(&original), + any_cast<std::string*>(©), "comparing address in copy against original"); check_equal(assign_result, ©, "address of assignment result"); } @@ -136,13 +137,13 @@ check_false(value.empty(), "type"); check_equal(value.type(), typeid(std::string), "type"); - check_null(any_cast<int>(&value), "any_cast<int>"); - check_non_null(any_cast<std::string>(&value), "any_cast<std::string>"); + check_null(any_cast<int*>(&value), "any_cast<int*>"); + check_non_null(any_cast<std::string*>(&value), "any_cast<std::string*>"); check_equal( - any_cast<std::string>(value), text, + any_cast<std::string&>(value), text, "comparing cast copy against original text"); check_unequal( - any_cast<std::string>(&value), + any_cast<std::string*>(&value), &text, "comparing address in copy against original text"); check_equal(assign_result, &value, "address of assignment result"); @@ -163,19 +164,19 @@ { std::string text = "test message"; any original = text, swapped; - std::string * original_ptr = any_cast<std::string>(&original); + std::string * original_ptr = any_cast<std::string*>(&original); any * swap_result = &original.swap(swapped); check_true(original.empty(), "empty on original"); check_false(swapped.empty(), "empty on swapped"); check_equal(swapped.type(), typeid(std::string), "type"); check_equal( - text, any_cast<std::string>(swapped), + text, any_cast<std::string&>(swapped), "comparing swapped copy against original text"); check_non_null(original_ptr, "address in pre-swapped original"); check_equal( original_ptr, - any_cast<std::string>(&swapped), + any_cast<std::string*>(&swapped), "comparing address in swapped against original"); check_equal(swap_result, &original, "address of swap result"); }
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost