calchash(): use type_info::name() instead of tinfo().
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 4.

The hash value of the object of different types should be different whenever
possible. Hence calcash() needs a unique per type number. Previously we used
tinfo_key for this. typeinfo::name() (a *pointer* to implementation dependent
string) is also unique for each class, so it's just as good as tinfo() is.

ginac/basic.cpp
ginac/constant.cpp
ginac/expairseq.cpp
ginac/function.pl
ginac/idx.cpp
ginac/relational.cpp
ginac/symbol.cpp
ginac/symmetry.cpp
ginac/wildcard.cpp

index 1f9ccba..fa6e1d9 100644 (file)
@@ -787,7 +787,8 @@ tinfo_t basic::return_type_tinfo() const
  *  would all end up with the same hashvalue. */
 unsigned basic::calchash() const
 {
-       unsigned v = golden_ratio_hash((p_int)tinfo());
+       const void* this_tinfo = (const void*)typeid(*this).name();
+       unsigned v = golden_ratio_hash((p_int)this_tinfo);
        for (size_t i=0; i<nops(); i++) {
                v = rotate_left(v);
                v ^= this->op(i).gethash();
index 13acc36..b63427f 100644 (file)
@@ -216,7 +216,8 @@ bool constant::is_equal_same_type(const basic & other) const
 
 unsigned constant::calchash() const
 {
-       hashvalue = golden_ratio_hash((p_int)tinfo() ^ serial);
+       const void* typeid_this = (const void*)typeid(*this).name();
+       hashvalue = golden_ratio_hash((p_int)typeid_this ^ serial);
 
        setflag(status_flags::hash_calculated);
 
index 120672f..39f7931 100644 (file)
@@ -615,7 +615,8 @@ unsigned expairseq::return_type() const
 
 unsigned expairseq::calchash() const
 {
-       unsigned v = golden_ratio_hash((p_int)this->tinfo());
+       const void* this_tinfo = (const void*)typeid(*this).name();
+       unsigned v = golden_ratio_hash((p_int)this_tinfo);
        epvector::const_iterator i = seq.begin();
        const epvector::const_iterator end = seq.end();
        while (i != end) {
index 7a4d5e7..b478023 100644 (file)
@@ -1066,7 +1066,8 @@ ex function::eval_ncmul(const exvector & v) const
 
 unsigned function::calchash() const
 {
-       unsigned v = golden_ratio_hash(golden_ratio_hash((p_int)tinfo()) ^ serial);
+       const void* this_tinfo = (const void*)typeid(*this).name();
+       unsigned v = golden_ratio_hash(golden_ratio_hash((p_int)this_tinfo) ^ serial);
        for (size_t i=0; i<nops(); i++) {
                v = rotate_left(v);
                v ^= this->op(i).gethash();
index c1412b9..174f95f 100644 (file)
@@ -352,7 +352,8 @@ unsigned idx::calchash() const
        // hash keys. That is, the hash values must not depend on the index
        // dimensions or other attributes (variance etc.).
        // The compare_same_type() methods will take care of the rest.
-       unsigned v = golden_ratio_hash((p_int)tinfo());
+       const void* this_tinfo = (const void*)(typeid(*this).name());
+       unsigned v = golden_ratio_hash((p_int)this_tinfo);
        v = rotate_left(v);
        v ^= value.gethash();
 
@@ -504,7 +505,7 @@ ex spinidx::toggle_variance_dot() const
 bool is_dummy_pair(const idx & i1, const idx & i2)
 {
        // The indices must be of exactly the same type
-       if (i1.tinfo() != i2.tinfo())
+       if (typeid(i1) != typeid(i2))
                return false;
 
        // Same type, let the indices decide whether they are paired
index 434b620..2f19d21 100644 (file)
@@ -258,7 +258,8 @@ tinfo_t relational::return_type_tinfo() const
 
 unsigned relational::calchash() const
 {
-       unsigned v = golden_ratio_hash((p_int)tinfo());
+       const void* this_tinfo = (const void*)typeid(*this).name();
+       unsigned v = golden_ratio_hash((p_int)this_tinfo);
        unsigned lhash = lh.gethash();
        unsigned rhash = rh.gethash();
 
index 6eedfef..f233d84 100644 (file)
@@ -287,7 +287,8 @@ bool symbol::is_equal_same_type(const basic & other) const
 
 unsigned symbol::calchash() const
 {
-       hashvalue = golden_ratio_hash((p_int)tinfo() ^ serial);
+       const void* this_tinfo = (const void*)typeid(*this).name();
+       hashvalue = golden_ratio_hash((p_int)this_tinfo ^ serial);
        setflag(status_flags::hash_calculated);
        return hashvalue;
 }
index 215a48a..9a15892 100644 (file)
@@ -185,7 +185,8 @@ int symmetry::compare_same_type(const basic & other) const
 
 unsigned symmetry::calchash() const
 {
-       unsigned v = golden_ratio_hash((p_int)tinfo());
+       const void* this_tinfo = (const void*)typeid(*this).name();
+       unsigned v = golden_ratio_hash((p_int)this_tinfo);
 
        if (type == none) {
                v = rotate_left(v);
index b5abfa1..4a89957 100644 (file)
@@ -104,9 +104,10 @@ void wildcard::do_print_python_repr(const print_python_repr & c, unsigned level)
 unsigned wildcard::calchash() const
 {
        // this is where the schoolbook method
-       // (golden_ratio_hash(tinfo()) ^ label)
+       // (golden_ratio_hash(typeid(*this).name()) ^ label)
        // is not good enough yet...
-       hashvalue = golden_ratio_hash(golden_ratio_hash((p_int)tinfo()) ^ label);
+       const void* this_tinfo = (const void*)typeid(*this).name();
+       hashvalue = golden_ratio_hash(golden_ratio_hash((p_int)this_tinfo) ^ label);
        setflag(status_flags::hash_calculated);
        return hashvalue;
 }