[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi] access to mc_enum type information [patch 2/3]
From: |
Vaclav Slavik |
Subject: |
[lmi] access to mc_enum type information [patch 2/3] |
Date: |
Tue, 29 Mar 2011 20:41:25 +0200 |
User-agent: |
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.15) Gecko/20110303 Thunderbird/3.1.9 |
[PATCH 2/3] Add try_member_cast<> in addition to member_cast<>.
Unlike member_cast<>, try_member_cast<> may return NULL.
It is needed to determine column type in CensusView - we need to
check whether the member is an enum (i.e. derived from
mc_enum_base or not) and that is something that cannot be done
with type(), as member_cast<>'s documentation suggested.
---
any_member.hpp | 49 +++++++++++++++++++++++++++++++++++++++----------
1 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/any_member.hpp b/any_member.hpp
index 52cf0a9..f321f46 100644
--- a/any_member.hpp
+++ b/any_member.hpp
@@ -235,7 +235,7 @@ template<typename MemberType, typename ClassType>
MemberType* exact_cast(any_member<ClassType>&);
template<typename MemberType, typename ClassType>
-MemberType* member_cast(any_member<ClassType>&);
+MemberType* try_member_cast(any_member<ClassType>&);
struct any_member_test;
@@ -248,7 +248,7 @@ class any_member
friend MemberType* exact_cast(any_member<CT>&);
template<typename MemberType, typename CT>
- friend MemberType* member_cast(any_member<CT>&);
+ friend MemberType* try_member_cast(any_member<CT>&);
friend struct any_member_test;
@@ -465,6 +465,36 @@ MemberType const* exact_cast(any_member<ClassType> const&
member)
return exact_cast<MemberType>(const_cast<any_member<ClassType>&>(member));
}
+/// Implementation of free function template try_member_cast().
+///
+/// Hesitate to specialize this function. Instead, specialize class
+/// template reconstitutor. See:
+/// "Why Not Specialize Function Templates?"
+/// http://www.gotw.ca/publications/mill17.htm
+///
+/// Returns a pointer, of the specified type, to the held object, or
+/// NULL if it can't be cast to the specified type.
+///
+/// This function template is intended for use when convertibility is
+/// unknown and comparing type() value isn't sufficient. Use
+/// member_cast<> in situations when the conversion is known to be valid.
+
+template<typename MemberType, typename ClassType>
+MemberType* try_member_cast(any_member<ClassType>& member)
+{
+ MemberType* z = (member.type() == typeid(MemberType ClassType::*))
+ ? member.template exact_cast<MemberType>()
+ : reconstitutor<MemberType,ClassType>::reconstitute(member)
+ ;
+ return z;
+}
+
+template<typename MemberType, typename ClassType>
+MemberType const* try_member_cast(any_member<ClassType> const& member)
+{
+ return
try_member_cast<MemberType>(const_cast<any_member<ClassType>&>(member));
+}
+
/// Implementation of free function template member_cast().
///
/// Hesitate to specialize this function. Instead, specialize class
@@ -482,18 +512,17 @@ MemberType const* exact_cast(any_member<ClassType> const&
member)
/// Throws if the return value would be zero.
///
/// This function template is not intended for testing convertibility,
-/// which can easily be done with member function type(). Instead, it
-/// is intended to perform a conversion that's known to be valid, and
-/// it validates that precondition--so obtaining a null pointer is
-/// treated as failure, and throws an exception.
+/// which can easily be done with member function type() or
+/// try_member_cast<>. Instead, it is intended to perform a
+/// conversion that's known to be valid, and it validates that
+/// precondition--so obtaining a null pointer is treated as failure,
+/// and throws an exception. See try_member_cast<> for a more
+/// dynamic_cast<>-like version.
template<typename MemberType, typename ClassType>
MemberType* member_cast(any_member<ClassType>& member)
{
- MemberType* z = (member.type() == typeid(MemberType ClassType::*))
- ? member.template exact_cast<MemberType>()
- : reconstitutor<MemberType,ClassType>::reconstitute(member)
- ;
+ MemberType* z = try_member_cast<MemberType,ClassType>(member);
if(!z)
{
std::ostringstream oss;