is_exactly_a: use typeid() to check the type of expression.
authorAlexei Sheplyakov <varg@theor.jinr.ru>
Wed, 15 Oct 2008 11:32:11 +0000 (15:32 +0400)
committerAlexei Sheplyakov <varg@theor.jinr.ru>
Sun, 19 Oct 2008 17:29:11 +0000 (21:29 +0400)
Custom RTTI considered harmful, part 1.

Custom run time type information (RTTI) system implemented in GiNaC have
several serious drawbacks, such as

1. It makes writing GiNaC classes unnecessary cumbersome.
2. It wastes sizeof(void *) bytes per object, for small objects like
   symbol, numeric, etc. this overhead is considerable.

It turns out that GiNaC's RTTI is not any faster than the standard one
(at least on GNU/Linux and Solaris with GNU C++ library and compiler).
So, GiNaC RTTI have no reasons to exit any more.

ginac/basic.h
ginac/symbol.h

index ffc508d..304adcf 100644 (file)
@@ -27,6 +27,7 @@
 #include <vector>
 #include <set>
 #include <map>
+#include <typeinfo> // for typeid
 // CINT needs <algorithm> to work properly with <vector>
 #include <algorithm>
 
@@ -306,7 +307,7 @@ inline bool is_a(const basic &obj)
 template <class T>
 inline bool is_exactly_a(const basic & obj)
 {
-       return obj.tinfo() == &T::tinfo_static;
+       return typeid(T) == typeid(obj);
 }
 
 } // namespace GiNaC
index c174ad5..3caa24e 100644 (file)
@@ -24,6 +24,7 @@
 #define __GINAC_SYMBOL_H__
 
 #include <string>
+#include <typeinfo>
 #include "basic.h"
 #include "ex.h"
 #include "ptr.h"
@@ -129,7 +130,7 @@ public:
 /** Specialization of is_exactly_a<realsymbol>(obj) for realsymbol objects. */
 template<> inline bool is_exactly_a<realsymbol>(const basic & obj)
 {
-       if (obj.tinfo() != &symbol::tinfo_static)
+       if (!is_a<symbol>(obj))
                return false;
        unsigned domain = static_cast<const symbol &>(obj).get_domain();
        return domain==domain::real || domain==domain::positive;
@@ -138,7 +139,7 @@ template<> inline bool is_exactly_a<realsymbol>(const basic & obj)
 /** Specialization of is_exactly_a<possymbol>(obj) for possymbol objects. */
 template<> inline bool is_exactly_a<possymbol>(const basic & obj)
 {
-       if (obj.tinfo() != &symbol::tinfo_static)
+       if (!is_a<symbol>(obj))
                return false;
        unsigned domain = static_cast<const symbol &>(obj).get_domain();
        return domain == domain::positive;