[GiNaC-list] A strange behaviour while implementing archive in a user-defined class

Feng Feng f.feng at outlook.com
Sat Dec 18 09:22:22 CET 2021


Dear all,


I got a strange behaviour while implementing the archive in user-defined class,
to make the behaviour more explicitly, let me post the C++ code here:


#include <ginac/ginac.h>
#include <fstream>


using namespace GiNaC;
using namespace std;


class Symbol : public symbol {
GINAC_DECLARE_REGISTERED_CLASS(Symbol, symbol)
public:
    Symbol(const string &s);
    void archive(archive_node & n) const override;
    void read_archive(const archive_node& n, lst& sym_lst) override;
    unsigned calchash() const override;
};
GINAC_DECLARE_UNARCHIVER(Symbol);


GINAC_IMPLEMENT_REGISTERED_CLASS(Symbol, symbol)
GINAC_BIND_UNARCHIVER(Symbol);


const symbol & get_symbol(const string & s) {
    static map<string, symbol> dict;
    if (dict.find(s) == dict.end()) dict[s] = symbol(s);
    return dict[s];
}


Symbol::Symbol() { }
Symbol::Symbol(const string &s) : symbol(get_symbol(s)) {  }
int Symbol::compare_same_type(const basic &other) const {
    const Symbol &o = static_cast<const Symbol &>(other);
    int ret = get_name().compare(o.get_name());
    if(ret==0) return 0;
    else if(ret<0) return -1;
    else return 1;
}
 
void Symbol::archive(archive_node & n) const {
    inherited::archive(n);
}
    
void Symbol::read_archive(const archive_node& n, lst& sym_lst) {
    inherited::read_archive(n, sym_lst);
    *this = Symbol(get_name());
}


unsigned Symbol::calchash() const {
    static auto hash = symbol("_").gethash();
    return hash;
}


int main() {
    Symbol k1("k1"), k2("k2");
    auto garfn = "tmp.gar";
    
    {
        archive ar;
        ex val = lst{ k1*k1, k2*k2 };
        ar.archive_ex(val, "key");
        ofstream out(garfn);
        out << ar;
        out.close();
        cout << "writed: " << val << endl;
    } {
        archive ar;
        ifstream in(garfn);
        in >> ar;
        in.close();
        auto val = ar.unarchive_ex(lst{}, "key");
        cout << "read: " << val << endl;
    }
    // console output is
    // writed: {k1^2,k2^2}
    // read: {k1^2,k2^2}
    
    {
        archive ar;
        ex val = lst{ k1*k1==0, k2*k2==0 };
        ar.archive_ex(val, "key");
        ofstream out(garfn);
        out << ar;
        out.close();
        cout << "writed: " << val << endl;
    } {
        archive ar;
        ifstream in(garfn);
        in >> ar;
        in.close();
        auto val = ar.unarchive_ex(lst{}, "key");
        cout << "read: " << val << endl;
    }
    // console output is
    // writed: {k1^2==0,k2^2==0}
    // read: {k1^2==0,k1^2==0} 
    // Note that the last line above, both items are the same: k1^2==0
    
    return 0;
}


Here I want to introduce a class Symbol, when one defines Symbol a(“a”), b(“a”);,
then a and b will be the same or equal, so I override the method compare_same_type.




The last console output seems very strange to me, the both items are the same,
while the expected result is "read: {k1^2==0,k2^2==0}”.


Thanks very much!


Best regards!
Feng
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.ginac.de/pipermail/ginac-list/attachments/20211218/b2e3832b/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.cpp
Type: application/octet-stream
Size: 2448 bytes
Desc: not available
URL: <http://www.ginac.de/pipermail/ginac-list/attachments/20211218/b2e3832b/attachment-0001.obj>


More information about the GiNaC-list mailing list