Boost logo

Boost :

From: Unai Uribarri Rodríguez (unaiur_at_[hidden])
Date: 2003-01-28 15:14:39


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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk