I've developed a new implementation that doesn't use remove_reference.

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>(&copy),
+            any_cast<std::string*>(&original),
+            any_cast<std::string*>(&copy),
             "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>(&copy),
+            any_cast<std::string*>(&original),
+            any_cast<std::string*>(&copy),
             "comparing address in copy against original");
         check_equal(assign_result, &copy, "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


Reply via email to