|
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>(©),
+ 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");
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk