lmi
[Top][All Lists]
Advanced

[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;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]