Don't force every algebraic class to implement archiving/unarchiving.
authorAlexei Sheplyakov <varg@theor.jinr.ru>
Sun, 19 Oct 2008 15:39:30 +0000 (19:39 +0400)
committerAlexei Sheplyakov <varg@theor.jinr.ru>
Sun, 19 Oct 2008 17:29:12 +0000 (21:29 +0400)
So people who don't use (un)archiving don't need to bother with it.

57 files changed:
doc/examples/mystring.cpp
ginac/add.cpp
ginac/add.h
ginac/archive.cpp
ginac/archive.h
ginac/basic.cpp
ginac/basic.h
ginac/clifford.cpp
ginac/clifford.h
ginac/color.cpp
ginac/color.h
ginac/constant.cpp
ginac/constant.h
ginac/container.h
ginac/ex.h
ginac/expairseq.cpp
ginac/expairseq.h
ginac/fail.cpp
ginac/fail.h
ginac/fderivative.cpp
ginac/fderivative.h
ginac/function.pl
ginac/idx.cpp
ginac/idx.h
ginac/indexed.cpp
ginac/indexed.h
ginac/integral.cpp
ginac/integral.h
ginac/lst.cpp
ginac/lst.h
ginac/matrix.cpp
ginac/matrix.h
ginac/mul.cpp
ginac/mul.h
ginac/ncmul.cpp
ginac/ncmul.h
ginac/numeric.cpp
ginac/numeric.h
ginac/power.cpp
ginac/power.h
ginac/pseries.cpp
ginac/pseries.h
ginac/registrar.cpp
ginac/registrar.h
ginac/relational.cpp
ginac/relational.h
ginac/structure.h
ginac/symbol.cpp
ginac/symbol.h
ginac/symmetry.cpp
ginac/symmetry.h
ginac/tensor.cpp
ginac/tensor.h
ginac/utils.cpp
ginac/utils.h
ginac/wildcard.cpp
ginac/wildcard.h

index eb0e452..ac9903f 100644 (file)
@@ -47,8 +47,9 @@ int mystring::compare_same_type(const basic &other) const
 }
 
 // archiving/unarchiving
-mystring::mystring(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void mystring::read_archive(const archive_node &n, lst &sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        n.find_string("string", str);
 }
 
index 7f72154..06ada49 100644 (file)
@@ -97,7 +97,7 @@ add::add(std::auto_ptr<epvector> vp, const ex & oc)
 // archiving
 //////////
 
-DEFAULT_ARCHIVING(add)
+GINAC_BIND_UNARCHIVER(add);
 
 //////////
 // functions overriding virtual functions from base classes
index d96e126..0dfd603 100644 (file)
@@ -84,6 +84,7 @@ protected:
        void do_print_csrc(const print_csrc & c, unsigned level) const;
        void do_print_python_repr(const print_python_repr & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(add);
 
 } // namespace GiNaC
 
index d462584..1d65c7a 100644 (file)
@@ -516,6 +516,12 @@ void archive_node::get_properties(propinfovector &v) const
        }       
 }
 
+static synthesize_func find_factory_fcn(const std::string& name)
+{
+       static unarchive_table_t the_table;
+       synthesize_func ret = the_table.find(name);
+       return ret;
+}
 
 /** Convert archive node to GiNaC expression. */
 ex archive_node::unarchive(lst &sym_lst) const
@@ -528,14 +534,50 @@ ex archive_node::unarchive(lst &sym_lst) const
        std::string class_name;
        if (!find_string("class", class_name))
                throw (std::runtime_error("archive node contains no class name"));
-       unarch_func f = find_unarch_func(class_name);
 
        // Call instantiation function
-       e = f(*this, sym_lst);
+       synthesize_func factory_fcn = find_factory_fcn(class_name);
+       ptr<basic> obj(factory_fcn());
+       obj->setflag(status_flags::dynallocated);
+       obj->read_archive(*this, sym_lst);
+       e = ex(*obj);
        has_expression = true;
        return e;
 }
 
+int unarchive_table_t::usecount = 0;
+unarchive_map_t* unarchive_table_t::unarch_map = 0;
+
+unarchive_table_t::unarchive_table_t()
+{
+       if (usecount == 0)
+               unarch_map = new unarchive_map_t();
+       ++usecount;
+}
+
+synthesize_func unarchive_table_t::find(const std::string& classname) const
+{
+       unarchive_map_t::const_iterator i = unarch_map->find(classname);
+       if (i != unarch_map->end())
+               return i->second;
+       throw std::runtime_error(std::string("no unarchiving function for \"")
+                       + classname + "\" class");
+}
+
+void unarchive_table_t::insert(const std::string& classname, synthesize_func f)
+{
+       if (unarch_map->find(classname) != unarch_map->end())
+               throw std::runtime_error(std::string("Class \"" + classname
+                                       + "\" is already registered"));
+       unarch_map->operator[](classname) = f;
+}
+
+unarchive_table_t::~unarchive_table_t()
+{
+       if (--usecount == 0)
+               delete unarch_map;
+}
+
 
 void archive::clear()
 {
index 0c2a1af..5969b00 100644 (file)
@@ -158,6 +158,86 @@ private:
        mutable ex e;
 };
 
+typedef basic* (*synthesize_func)();
+typedef std::map<std::string, synthesize_func> unarchive_map_t;
+
+class unarchive_table_t
+{
+       static int usecount;
+       static unarchive_map_t* unarch_map;
+public:
+       unarchive_table_t();
+       ~unarchive_table_t();
+       synthesize_func find(const std::string& classname) const;
+       void insert(const std::string& classname, synthesize_func f);
+};
+static unarchive_table_t unarch_table_instance;
+
+/** Helper macros to register a class with (un)archiving (a.k.a.
+ * (de)serialization).
+ *
+ * Usage: put 
+ *
+ * GINAC_DECLARE_UNARCHIVER(myclass);
+ *
+ * into the header file (in the global or namespace scope), and
+ *
+ * GINAC_BIND_UNARCHIVER(myclass);
+ *
+ * into the source file.
+ *
+ * Effect: the `myclass' (being a class derived directly or indirectly
+ * from GiNaC::basic) can be archived and unarchived.
+ *
+ * Note: you need to use GINAC_{DECLARE,BIND}_UNARCHIVER incantations
+ * in order to make your class (un)archivable _even if your class does
+ * not overload `read_archive' method_. Sorry for inconvenience.
+ *
+ * How it works: 
+ *
+ * The `basic' class has a `read_archive' virtual method which reads an
+ * expression from archive. Derived classes can overload that method.
+ * There's a small problem, though. On unarchiving all we have is a set
+ * of named byte streams. In C++ the class name (as written in the source
+ * code) has nothing to do with its actual type. Thus, we need establish
+ * a correspondence ourselves. To do so we maintain a `class_name' =>
+ * `function_pointer' table (see the unarchive_table_t class above).
+ * Every function in this table is supposed to create a new object of
+ * the `class_name' type. The `archive_node' class uses that table to
+ * construct an object of correct type. Next it invokes read_archive
+ * virtual method of newly created object, which does the actual job.
+ *
+ * Note: this approach is very simple-minded (it does not handle classes
+ * with same names from different namespaces, multiple inheritance, etc),
+ * but it happens to work surprisingly well.
+ */
+#define GINAC_DECLARE_UNARCHIVER(classname)                    \
+class classname ## _unarchiver                                 \
+{                                                              \
+       static int usecount;                                    \
+public:                                                                \
+       static GiNaC::basic* create();                          \
+       classname ## _unarchiver();                             \
+       ~ classname ## _unarchiver();                           \
+};                                                             \
+static classname ## _unarchiver classname ## _unarchiver_instance
+
+#define GINAC_BIND_UNARCHIVER(classname)                       \
+classname ## _unarchiver::classname ## _unarchiver()           \
+{                                                              \
+       static GiNaC::unarchive_table_t table;                  \
+       if (usecount++ == 0) {                                  \
+               table.insert(std::string(#classname),           \
+                       &(classname ## _unarchiver::create));   \
+       }                                                       \
+}                                                              \
+GiNaC::basic* classname ## _unarchiver::create()               \
+{                                                              \
+       return new classname();                                 \
+}                                                              \
+classname ## _unarchiver::~ classname ## _unarchiver() { }     \
+int classname ## _unarchiver::usecount = 0
+
 
 /** This class holds archived versions of GiNaC expressions (class ex).
  *  An archive can be constructed from an expression and then written to
index 237c63d..04f87df 100644 (file)
@@ -92,16 +92,8 @@ const basic & basic::operator=(const basic & other)
 //////////
 
 /** Construct object from archive_node. */
-basic::basic(const archive_node &n, lst &sym_lst) : flags(0)
-{
-       // Reconstruct tinfo_key from class name
-       std::string class_name;
-       if (!n.find_string("class", class_name))
-               throw (std::runtime_error("archive node contains no class name"));
-}
-
-/** Unarchive the object. */
-DEFAULT_UNARCHIVE(basic)
+void basic::read_archive(const archive_node& n, lst& syms)
+{ }
 
 /** Archive the object. */
 void basic::archive(archive_node &n) const
index 534a591..51e0e90 100644 (file)
@@ -241,6 +241,23 @@ public:
 
        void print_dispatch(const registered_class_info & ri, const print_context & c, unsigned level) const;
 
+       /** Save (serialize) the object into archive node.
+        *
+        * Losely speaking, this method turns an expression into a byte
+        * stream (which can be saved and restored later on, or sent via
+        * network, etc.)
+        */
+       virtual void archive(archive_node& n) const;
+       /** Load (deserialize) the object from an archive node.
+        *
+        *  @note This method is essentially a constructor. However,
+        *  constructors can't be virtual. So, if unarchiving routines
+        *  are implemented as constructors one would need to define such
+        *  a constructor in every class, even if all it does is simply
+        *  calling constructor of a superclass.
+        */
+       virtual void read_archive(const archive_node& n, lst& syms); // no const
+
        ex subs_one_level(const exmap & m, unsigned options) const;
        ex diff(const symbol & s, unsigned nth = 1) const;
        int compare(const basic & other) const;
index d3667aa..07da693 100644 (file)
@@ -122,8 +122,9 @@ return_type_t clifford::return_type_tinfo() const
 // archiving
 //////////
 
-clifford::clifford(const archive_node & n, lst & sym_lst) : inherited(n, sym_lst)
+void clifford::read_archive(const archive_node& n, lst& sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        unsigned rl;
        n.find_unsigned("label", rl);
        representation_label = rl;
@@ -140,13 +141,12 @@ void clifford::archive(archive_node & n) const
        n.add_unsigned("commutator_sign+1", commutator_sign+1);
 }
 
-DEFAULT_UNARCHIVE(clifford)
-DEFAULT_ARCHIVING(diracone)
-DEFAULT_ARCHIVING(cliffordunit)
-DEFAULT_ARCHIVING(diracgamma)
-DEFAULT_ARCHIVING(diracgamma5)
-DEFAULT_ARCHIVING(diracgammaL)
-DEFAULT_ARCHIVING(diracgammaR)
+GINAC_BIND_UNARCHIVER(clifford);
+GINAC_BIND_UNARCHIVER(diracone);
+GINAC_BIND_UNARCHIVER(diracgamma);
+GINAC_BIND_UNARCHIVER(diracgamma5);
+GINAC_BIND_UNARCHIVER(diracgammaL);
+GINAC_BIND_UNARCHIVER(diracgammaR);
 
 
 ex clifford::get_metric(const ex & i, const ex & j, bool symmetrised) const
index 6b74a46..efb9dd6 100644 (file)
@@ -53,6 +53,8 @@ public:
        // functions overriding virtual functions from base classes
 public:
        unsigned precedence() const { return 65; }
+       void archive(archive_node& n) const;
+       void read_archive(const archive_node& n, lst& sym_lst);
 protected:
        ex eval_ncmul(const exvector & v) const;
        bool match_same_type(const basic & other) const;
@@ -83,6 +85,7 @@ protected:
        ex metric; /**< Metric of the space, all constructors make it an indexed object */
        int commutator_sign; /**< It is the sign in the definition e~i e~j +/- e~j e~i = B(i, j) + B(j, i)*/
 };
+GINAC_DECLARE_UNARCHIVER(clifford); 
 
 /** This class represents the Clifford algebra unity element. */
 class diracone : public tensor
@@ -94,6 +97,7 @@ protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(diracone);
 
 
 /** This class represents the Clifford algebra generators (units). */
@@ -126,6 +130,7 @@ protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(diracgamma);
 
 
 /** This class represents the Dirac gamma5 object which anticommutates with
@@ -142,6 +147,7 @@ protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(diracgamma5);
 
 
 /** This class represents the Dirac gammaL object which behaves like
@@ -158,6 +164,7 @@ protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(diracgammaL);
 
 
 /** This class represents the Dirac gammaL object which behaves like
@@ -174,6 +181,7 @@ protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(diracgammaR);
 
 
 // global functions
index 30c38d9..b1ca905 100644 (file)
@@ -103,8 +103,9 @@ return_type_t color::return_type_tinfo() const
 // archiving
 //////////
 
-color::color(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void color::read_archive(const archive_node& n, lst& sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        unsigned rl;
        n.find_unsigned("label", rl);
        representation_label = rl;
@@ -116,11 +117,11 @@ void color::archive(archive_node &n) const
        n.add_unsigned("label", representation_label);
 }
 
-DEFAULT_UNARCHIVE(color)
-DEFAULT_ARCHIVING(su3one)
-DEFAULT_ARCHIVING(su3t)
-DEFAULT_ARCHIVING(su3f)
-DEFAULT_ARCHIVING(su3d)
+GINAC_BIND_UNARCHIVER(color);
+GINAC_BIND_UNARCHIVER(su3one);
+GINAC_BIND_UNARCHIVER(su3t);
+GINAC_BIND_UNARCHIVER(su3f);
+GINAC_BIND_UNARCHIVER(su3d);
 
 //////////
 // functions overriding virtual functions from base classes
index 360223e..d595cb3 100644 (file)
@@ -49,6 +49,8 @@ public:
        // internal constructors
        color(unsigned char rl, const exvector & v, bool discardable = false);
        color(unsigned char rl, std::auto_ptr<exvector> vp);
+       void archive(archive_node& n) const;
+       void read_archive(const archive_node& n, lst& sym_lst);
 
        // functions overriding virtual functions from base classes
 protected:
@@ -67,6 +69,7 @@ public:
 private:
        unsigned char representation_label; /**< Representation label to distinguish independent color matrices coming from separated fermion lines */
 };
+GINAC_DECLARE_UNARCHIVER(color); 
 
 
 /** This class represents the su(3) unity element. */
@@ -79,6 +82,7 @@ protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(su3one);
 
 /** This class represents an su(3) generator. */
 class su3t : public tensor
@@ -94,6 +98,7 @@ protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(su3t);
 
 /** This class represents the tensor of antisymmetric su(3) structure
  *  constants. */
@@ -112,6 +117,7 @@ protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(su3f);
 
 /** This class represents the tensor of symmetric su(3) structure constants. */
 class su3d : public tensor
@@ -129,6 +135,7 @@ protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(su3d);
 
 
 // global functions
index 9247ac2..10972b0 100644 (file)
@@ -80,25 +80,24 @@ constant::constant(const std::string & initname, const numeric & initnumber, con
 // archiving
 //////////
 
-constant::constant(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst) {}
-
-ex constant::unarchive(const archive_node &n, lst &sym_lst)
+void constant::read_archive(const archive_node &n, lst &sym_lst)
 {
        // Find constant by name (!! this is bad: 'twould be better if there
        // was a list of all global constants that we could search)
        std::string s;
        if (n.find_string("name", s)) {
                if (s == Pi.name)
-                       return Pi;
+                       *this = Pi;
                else if (s == Catalan.name)
-                       return Catalan;
+                       *this = Catalan;
                else if (s == Euler.name)
-                       return Euler;
+                       *this = Euler;
                else
                        throw (std::runtime_error("unknown constant '" + s + "' in archive"));
        } else
                throw (std::runtime_error("unnamed constant in archive"));
 }
+GINAC_BIND_UNARCHIVER(constant);
 
 void constant::archive(archive_node &n) const
 {
index c18f6fc..efbe39e 100644 (file)
@@ -26,6 +26,7 @@
 #include <string>
 #include "basic.h"
 #include "ex.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -38,9 +39,6 @@ typedef ex (*evalffunctype)();
 class constant : public basic
 {
        GINAC_DECLARE_REGISTERED_CLASS(constant, basic)
-       
-// member functions
-       
        // other constructors
 public:
        constant(const std::string & initname, evalffunctype efun = 0, const std::string & texname = std::string(), unsigned domain = domain::complex);
@@ -54,6 +52,8 @@ public:
        ex conjugate() const;
        ex real_part() const;
        ex imag_part() const;
+       void archive(archive_node& n) const;
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
@@ -76,6 +76,7 @@ private:
        static unsigned next_serial;
        unsigned domain;      ///< numerical value this constant evalf()s to
 };
+GINAC_DECLARE_UNARCHIVER(constant); 
 
 extern const constant Pi;
 extern const constant Catalan;
index 7092e3b..c134594 100644 (file)
@@ -128,7 +128,6 @@ private:
 template <template <class T, class = std::allocator<T> > class C>
 class container : public basic, public container_storage<C> {
        GINAC_DECLARE_REGISTERED_CLASS(container, basic)
-
 protected:
        typedef typename container_storage<C>::STLT STLT;
 
@@ -366,6 +365,33 @@ public:
        ex eval(int level = 0) const;
        ex subs(const exmap & m, unsigned options = 0) const;
 
+       void read_archive(const archive_node &n, lst &sym_lst) 
+       {
+               inherited::read_archive(n, sym_lst);
+               setflag(get_default_flags());
+
+               archive_node::archive_node_cit first = n.find_first("seq");
+               archive_node::archive_node_cit last = n.find_last("seq");
+               ++last;
+               reserve(this->seq, last - first);
+               for (archive_node::archive_node_cit i=first; i<last; ++i) {
+                       ex e;
+                       n.find_ex_by_loc(i, e, sym_lst);
+                       this->seq.push_back(e);
+               }
+       }
+
+       /** Archive the object. */
+       void archive(archive_node &n) const
+       {
+               inherited::archive(n);
+               const_iterator i = this->seq.begin(), end = this->seq.end();
+               while (i != end) {
+                       n.add_ex("seq", *i);
+                       ++i;
+               }
+       }
+
 protected:
        ex conjugate() const
        {
@@ -480,41 +506,6 @@ container<C>::container()
        setflag(get_default_flags());
 }
 
-/** Construct object from archive_node. */
-template <template <class T, class = std::allocator<T> > class C>
-container<C>::container(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
-{
-       setflag(get_default_flags());
-
-       archive_node::archive_node_cit first = n.find_first("seq");
-       archive_node::archive_node_cit last = n.find_last("seq");
-       ++last;
-       reserve(this->seq, last - first);
-       for (archive_node::archive_node_cit i=first; i<last; ++i) {
-               ex e;
-               n.find_ex_by_loc(i, e, sym_lst);
-               this->seq.push_back(e);
-       }
-}
-
-/** Unarchive the object. */
-template <template <class T, class = std::allocator<T> > class C>
-ex container<C>::unarchive(const archive_node &n, lst &sym_lst)
-{
-       return (new container(n, sym_lst))->setflag(status_flags::dynallocated);
-}
-
-/** Archive the object. */
-template <template <class T, class = std::allocator<T> > class C>
-void container<C>::archive(archive_node &n) const
-{
-       inherited::archive(n);
-       const_iterator i = this->seq.begin(), end = this->seq.end();
-       while (i != end) {
-               n.add_ex("seq", *i);
-               ++i;
-       }
-}
 
 template <template <class T, class = std::allocator<T> > class C>
 void container<C>::do_print(const print_context & c, unsigned level) const
index 60d4080..e3766a0 100644 (file)
@@ -43,6 +43,7 @@ namespace GiNaC {
  *
  *  @see utils.cpp */
 class library_init {
+       static void init_unarchivers();
 public:
        library_init();
        ~library_init();
index 6057a85..c5911fc 100644 (file)
@@ -141,11 +141,9 @@ expairseq::expairseq(std::auto_ptr<epvector> vp, const ex &oc, bool do_index_ren
 // archiving
 //////////
 
-expairseq::expairseq(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
-#if EXPAIRSEQ_USE_HASHTAB
-       , hashtabsize(0)
-#endif
+void expairseq::read_archive(const archive_node &n, lst &sym_lst) 
 {
+       inherited::read_archive(n, sym_lst);
        archive_node::archive_node_cit first = n.find_first("rest");
        archive_node::archive_node_cit last = n.find_last("coeff");
        ++last;
@@ -177,7 +175,6 @@ void expairseq::archive(archive_node &n) const
        n.add_ex("overall_coeff", overall_coeff);
 }
 
-DEFAULT_UNARCHIVE(expairseq)
 
 //////////
 // functions overriding virtual functions from base classes
index 5f707f7..f1b4309 100644 (file)
@@ -88,6 +88,9 @@ public:
        ex subs(const exmap & m, unsigned options = 0) const;
        ex conjugate() const;
        bool is_polynomial(const ex & var) const;
+
+       void archive(archive_node& n) const;
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        bool is_equal_same_type(const basic & other) const;
        unsigned return_type() const;
index 5908c93..edc5852 100644 (file)
@@ -43,13 +43,12 @@ DEFAULT_CTOR(fail)
 // archiving
 //////////
 
-DEFAULT_ARCHIVING(fail)
-
 //////////
 // functions overriding virtual functions from base classes
 //////////
 
 DEFAULT_COMPARE(fail)
 DEFAULT_PRINT(fail, "FAIL")
+GINAC_BIND_UNARCHIVER(fail);
 
 } // namespace GiNaC
index 2e88c8a..dbd5faf 100644 (file)
@@ -25,6 +25,7 @@
 #define __GINAC_FAIL_H__
 
 #include "basic.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -40,6 +41,7 @@ protected:
 protected:
        void do_print(const print_context & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(fail);
 
 } // namespace GiNaC
 
index 82a0c8d..efe2a69 100644 (file)
@@ -63,8 +63,9 @@ fderivative::fderivative(unsigned ser, const paramset & params, std::auto_ptr<ex
 // archiving
 //////////
 
-fderivative::fderivative(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void fderivative::read_archive(const archive_node& n, lst& sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        unsigned i = 0;
        while (true) {
                unsigned u;
@@ -75,6 +76,7 @@ fderivative::fderivative(const archive_node &n, lst &sym_lst) : inherited(n, sym
                ++i;
        }
 }
+GINAC_BIND_UNARCHIVER(fderivative);
 
 void fderivative::archive(archive_node &n) const
 {
@@ -86,7 +88,6 @@ void fderivative::archive(archive_node &n) const
        }
 }
 
-DEFAULT_UNARCHIVE(fderivative)
 
 //////////
 // functions overriding virtual functions from base classes
index 0d74efc..b43423c 100644 (file)
@@ -66,6 +66,8 @@ public:
        ex series(const relational & r, int order, unsigned options = 0) const;
        ex thiscontainer(const exvector & v) const;
        ex thiscontainer(std::auto_ptr<exvector> vp) const;
+       void archive(archive_node& n) const;
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
@@ -81,6 +83,7 @@ protected:
 protected:
        paramset parameter_set; /**< Set of parameter numbers with respect to which to take the derivative */
 };
+GINAC_DECLARE_UNARCHIVER(fderivative); 
 
 } // namespace GiNaC
 
index 6c70d2d..3ac3c3c 100644 (file)
@@ -514,6 +514,8 @@ public:
        ex conjugate() const;
        ex real_part() const;
        ex imag_part() const;
+       void archive(archive_node& n) const;
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
@@ -543,6 +545,7 @@ public:
 protected:
        unsigned serial;
 };
+GINAC_DECLARE_UNARCHIVER(function);
 
 // utility functions/macros
 
@@ -852,8 +855,9 @@ function::function(unsigned ser, std::auto_ptr<exvector> vp)
 //////////
 
 /** Construct object from archive_node. */
-function::function(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void function::read_archive(const archive_node& n, lst& sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        // Find serial number by function name
        std::string s;
        if (n.find_string("name", s)) {
@@ -871,12 +875,6 @@ function::function(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
                throw (std::runtime_error("unnamed function in archive"));
 }
 
-/** Unarchive the object. */
-ex function::unarchive(const archive_node &n, lst &sym_lst)
-{
-       return (new function(n, sym_lst))->setflag(status_flags::dynallocated);
-}
-
 /** Archive the object. */
 void function::archive(archive_node &n) const
 {
@@ -885,6 +883,8 @@ void function::archive(archive_node &n) const
        n.add_string("name", registered_functions()[serial].name);
 }
 
+GINAC_BIND_UNARCHIVER(function);
+
 //////////
 // functions overriding virtual functions from base classes
 //////////
index 427dfe9..9a91e03 100644 (file)
@@ -87,21 +87,27 @@ spinidx::spinidx(const ex & v, const ex & d, bool cov, bool dot) : inherited(v,
 // archiving
 //////////
 
-idx::idx(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void idx::read_archive(const archive_node& n, lst& sym_lst) 
 {
+       inherited::read_archive(n, sym_lst);
        n.find_ex("value", value, sym_lst);
        n.find_ex("dim", dim, sym_lst);
 }
+GINAC_BIND_UNARCHIVER(idx);
 
-varidx::varidx(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void varidx::read_archive(const archive_node& n, lst& sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        n.find_bool("covariant", covariant);
 }
+GINAC_BIND_UNARCHIVER(varidx);
 
-spinidx::spinidx(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void spinidx::read_archive(const archive_node& n, lst& sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        n.find_bool("dotted", dotted);
 }
+GINAC_BIND_UNARCHIVER(spinidx);
 
 void idx::archive(archive_node &n) const
 {
@@ -122,10 +128,6 @@ void spinidx::archive(archive_node &n) const
        n.add_bool("dotted", dotted);
 }
 
-DEFAULT_UNARCHIVE(idx)
-DEFAULT_UNARCHIVE(varidx)
-DEFAULT_UNARCHIVE(spinidx)
-
 //////////
 // functions overriding virtual functions from base classes
 //////////
index f00f2dd..7ea9e5f 100644 (file)
@@ -54,7 +54,8 @@ public:
        ex map(map_function & f) const;
        ex evalf(int level = 0) const;
        ex subs(const exmap & m, unsigned options = 0) const;
-
+       void archive(archive_node& n) const;
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        ex derivative(const symbol & s) const;
        bool match_same_type(const basic & other) const;
@@ -104,6 +105,7 @@ protected:
        ex value; /**< Expression that constitutes the index (numeric or symbolic name) */
        ex dim;   /**< Dimension of space (can be symbolic or numeric) */
 };
+GINAC_DECLARE_UNARCHIVER(idx); 
 
 
 /** This class holds an index with a variance (co- or contravariant). There
@@ -125,7 +127,8 @@ public:
        // functions overriding virtual functions from base classes
 public:
        bool is_dummy_pair_same_type(const basic & other) const;
-
+       void archive(archive_node& n) const;
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        bool match_same_type(const basic & other) const;
 
@@ -148,6 +151,7 @@ protected:
 protected:
        bool covariant; /**< x.mu, default is contravariant: x~mu */
 };
+GINAC_DECLARE_UNARCHIVER(varidx);
 
 
 /** This class holds a spinor index that can be dotted or undotted and that
@@ -175,7 +179,8 @@ public:
        bool is_dummy_pair_same_type(const basic & other) const;
        // complex conjugation
        ex conjugate() const { return toggle_dot(); }
-
+       void archive(archive_node& n) const;
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        bool match_same_type(const basic & other) const;
 
@@ -204,6 +209,7 @@ protected:
 protected:
        bool dotted;
 };
+GINAC_DECLARE_UNARCHIVER(spinidx);
 
 
 // utility functions
index 8c5256a..01fc985 100644 (file)
@@ -129,8 +129,9 @@ indexed::indexed(const symmetry & symm, std::auto_ptr<exvector> vp) : inherited(
 // archiving
 //////////
 
-indexed::indexed(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void indexed::read_archive(const archive_node &n, lst &sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        if (!n.find_ex("symmetry", symtree, sym_lst)) {
                // GiNaC versions <= 0.9.0 had an unsigned "symmetry" property
                unsigned symm = 0;
@@ -149,6 +150,7 @@ indexed::indexed(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
                const_cast<symmetry &>(ex_to<symmetry>(symtree)).validate(seq.size() - 1);
        }
 }
+GINAC_BIND_UNARCHIVER(indexed);
 
 void indexed::archive(archive_node &n) const
 {
@@ -156,8 +158,6 @@ void indexed::archive(archive_node &n) const
        n.add_ex("symmetry", symtree);
 }
 
-DEFAULT_UNARCHIVE(indexed)
-
 //////////
 // functions overriding virtual functions from base classes
 //////////
index 82a45c3..b5339a7 100644 (file)
@@ -151,6 +151,10 @@ public:
        ex imag_part() const;
        exvector get_free_indices() const;
 
+       /** Save (a.k.a. serialize) indexed object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) indexed object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        ex derivative(const symbol & s) const;
        ex thiscontainer(const exvector & v) const;
@@ -198,6 +202,7 @@ protected:
 protected:
        ex symtree; /**< Index symmetry (tree of symmetry objects) */
 };
+GINAC_DECLARE_UNARCHIVER(indexed);
 
 
 class spmapkey {
index 74a356d..d6a39cd 100644 (file)
@@ -70,8 +70,9 @@ integral::integral(const ex & x_, const ex & a_, const ex & b_, const ex & f_)
 // archiving
 //////////
 
-integral::integral(const archive_node & n, lst & sym_lst) : inherited(n, sym_lst)
+void integral::read_archive(const archive_node& n, lst& sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        n.find_ex("x", x, sym_lst);
        n.find_ex("a", a, sym_lst);
        n.find_ex("b", b, sym_lst);
@@ -87,8 +88,6 @@ void integral::archive(archive_node & n) const
        n.add_ex("f", f);
 }
 
-DEFAULT_UNARCHIVE(integral)
-
 //////////
 // functions overriding virtual functions from base classes
 //////////
@@ -474,4 +473,5 @@ ex integral::eval_integ() const
        return *this;
 }
 
+GINAC_BIND_UNARCHIVER(integral);
 } // namespace GiNaC
index e2843c8..874b528 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "basic.h"
 #include "ex.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -54,6 +55,10 @@ public:
        return_type_t return_type_tinfo() const;
        ex conjugate() const;
        ex eval_integ() const;
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        ex derivative(const symbol & s) const;
        ex series(const relational & r, int order, unsigned options = 0) const;
@@ -74,6 +79,7 @@ private:
        ex b;
        ex f;
 };
+GINAC_DECLARE_UNARCHIVER(integral); 
 
 // utility functions
 
index f4c247f..f2106bd 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include "lst.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -37,4 +38,6 @@ template <> bool lst::info(unsigned inf) const
                return inherited::info(inf);
 }
 
+GINAC_BIND_UNARCHIVER(lst);
+
 } // namespace GiNaC
index eaea3ea..85b5f89 100644 (file)
@@ -42,6 +42,7 @@ template<> inline char lst::get_close_delim() { return '}'; }
 
 // defined in lst.cpp
 template<> bool lst::info(unsigned inf) const;
+GINAC_DECLARE_UNARCHIVER(lst);
 
 } // namespace GiNaC
 
index c92ea3f..37c4927 100644 (file)
@@ -105,22 +105,25 @@ matrix::matrix(unsigned r, unsigned c, const lst & l)
 // archiving
 //////////
 
-matrix::matrix(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void matrix::read_archive(const archive_node &n, lst &sym_lst)
 {
-       setflag(status_flags::not_shareable);
+       inherited::read_archive(n, sym_lst);
 
        if (!(n.find_unsigned("row", row)) || !(n.find_unsigned("col", col)))
                throw (std::runtime_error("unknown matrix dimensions in archive"));
        m.reserve(row * col);
+       // XXX: default ctor inserts a zero element, we need to erase it here.
+       m.pop_back();
        archive_node::archive_node_cit first = n.find_first("m");
        archive_node::archive_node_cit last = n.find_last("m");
        ++last;
-       for (archive_node::archive_node_cit i=first; i<last; ++i) {
+       for (archive_node::archive_node_cit i=first; i != last; ++i) {
                ex e;
                n.find_ex_by_loc(i, e, sym_lst);
                m.push_back(e);
        }
 }
+GINAC_BIND_UNARCHIVER(matrix);
 
 void matrix::archive(archive_node &n) const
 {
@@ -134,8 +137,6 @@ void matrix::archive(archive_node &n) const
        }
 }
 
-DEFAULT_UNARCHIVE(matrix)
-
 //////////
 // functions overriding virtual functions from base classes
 //////////
index 8544c9d..e48f3d8 100644 (file)
@@ -27,6 +27,7 @@
 #include <string>
 #include "basic.h"
 #include "ex.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -124,6 +125,10 @@ public:
        ex real_part() const;
        ex imag_part() const;
 
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        bool match_same_type(const basic & other) const;
        unsigned return_type() const { return return_types::noncommutative; };
@@ -170,6 +175,7 @@ protected:
        unsigned col;             ///< number of columns
        exvector m;               ///< representation (cols indexed first)
 };
+GINAC_DECLARE_UNARCHIVER(matrix); 
 
 
 // wrapper functions around member functions
index ad31139..53c3811 100644 (file)
@@ -113,8 +113,6 @@ mul::mul(const ex & lh, const ex & mh, const ex & rh)
 // archiving
 //////////
 
-DEFAULT_ARCHIVING(mul)
-
 //////////
 // functions overriding virtual functions from base classes
 //////////
@@ -1210,4 +1208,6 @@ std::auto_ptr<epvector> mul::expandchildren(unsigned options) const
        return std::auto_ptr<epvector>(0); // nothing has changed
 }
 
+GINAC_BIND_UNARCHIVER(mul);
+
 } // namespace GiNaC
index a11b29b..bfcd886 100644 (file)
@@ -98,6 +98,7 @@ protected:
        static bool can_be_further_expanded(const ex & e);
        std::auto_ptr<epvector> expandchildren(unsigned options) const;
 };
+GINAC_DECLARE_UNARCHIVER(mul);
 
 } // namespace GiNaC
 
index 2c0d736..dcc5f8c 100644 (file)
@@ -92,8 +92,7 @@ ncmul::ncmul(std::auto_ptr<exvector> vp) : inherited(vp)
 // archiving
 //////////
 
-DEFAULT_ARCHIVING(ncmul)
-       
+
 //////////
 // functions overriding virtual functions from base classes
 //////////
@@ -652,4 +651,6 @@ ex hold_ncmul(const exvector & v)
                                               status_flags::evaluated);
 }
 
+GINAC_BIND_UNARCHIVER(ncmul);
+
 } // namespace GiNaC
index 9101427..5e0a5d1 100644 (file)
@@ -24,6 +24,7 @@
 #define __GINAC_NCMUL_H__
 
 #include "exprseq.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -86,6 +87,7 @@ protected:
 public:
        const exvector & get_factors() const;
 };
+GINAC_DECLARE_UNARCHIVER(ncmul);
 
 // friend funtions 
 
index 5649353..1c9b420 100644 (file)
@@ -278,8 +278,9 @@ static const cln::cl_F read_real_float(std::istream& s)
        return x;
 }
 
-numeric::numeric(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void numeric::read_archive(const archive_node &n, lst &sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        value = 0;
        
        // Read number as string
@@ -324,6 +325,7 @@ numeric::numeric(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
        }
        setflag(status_flags::evaluated | status_flags::expanded);
 }
+GINAC_BIND_UNARCHIVER(numeric);
 
 static void write_real_float(std::ostream& s, const cln::cl_R& n)
 {
@@ -373,8 +375,6 @@ void numeric::archive(archive_node &n) const
        n.add_string("number", s.str());
 }
 
-DEFAULT_UNARCHIVE(numeric)
-
 //////////
 // functions overriding virtual functions from base classes
 //////////
index bf5c701..28bef0a 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "basic.h"
 #include "ex.h"
+#include "archive.h"
 
 #include <stdexcept>
 #include <vector>
@@ -122,6 +123,10 @@ public:
        ex conjugate() const;
        ex real_part() const;
        ex imag_part() const;
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        /** Implementation of ex::diff for a numeric always returns 0.
         *  @see ex::diff */
@@ -200,6 +205,7 @@ protected:
 protected:
        cln::cl_N value;
 };
+GINAC_DECLARE_UNARCHIVER(numeric); 
 
 
 // global constants
index ca9600f..cbe6324 100644 (file)
@@ -71,8 +71,9 @@ power::power() { }
 // archiving
 //////////
 
-power::power(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void power::read_archive(const archive_node &n, lst &sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        n.find_ex("basis", basis, sym_lst);
        n.find_ex("exponent", exponent, sym_lst);
 }
@@ -84,8 +85,6 @@ void power::archive(archive_node &n) const
        n.add_ex("exponent", exponent);
 }
 
-DEFAULT_UNARCHIVE(power)
-
 //////////
 // functions overriding virtual functions from base classes
 //////////
@@ -1061,4 +1060,6 @@ ex power::expand_mul(const mul & m, const numeric & n, unsigned options, bool fr
        return result;
 }
 
+GINAC_BIND_UNARCHIVER(power);
+
 } // namespace GiNaC
index f8d29c0..4a22ef4 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "basic.h"
 #include "ex.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -70,6 +71,10 @@ public:
        ex conjugate() const;
        ex real_part() const;
        ex imag_part() const;
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        ex derivative(const symbol & s) const;
        ex eval_ncmul(const exvector & v) const;
@@ -100,6 +105,7 @@ protected:
        ex basis;
        ex exponent;
 };
+GINAC_DECLARE_UNARCHIVER(power); 
 
 // wrapper functions
 
index 989fda8..15fac1f 100644 (file)
@@ -81,8 +81,9 @@ pseries::pseries(const ex &rel_, const epvector &ops_) : seq(ops_)
  *  Archiving
  */
 
-pseries::pseries(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void pseries::read_archive(const archive_node &n, lst &sym_lst) 
 {
+       inherited::read_archive(n, sym_lst);
        archive_node::archive_node_cit first = n.find_first("coeff");
        archive_node::archive_node_cit last = n.find_last("power");
        ++last;
@@ -113,7 +114,6 @@ void pseries::archive(archive_node &n) const
        n.add_ex("point", point);
 }
 
-DEFAULT_UNARCHIVE(pseries)
 
 //////////
 // functions overriding virtual functions from base classes
@@ -1284,4 +1284,6 @@ ex ex::series(const ex & r, int order, unsigned options) const
        return e;
 }
 
+GINAC_BIND_UNARCHIVER(pseries);
+
 } // namespace GiNaC
index b3d2716..e84cc5b 100644 (file)
@@ -60,6 +60,10 @@ public:
        ex imag_part() const;
        ex eval_integ() const;
        ex evalm() const;
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        ex derivative(const symbol & s) const;
 
@@ -115,6 +119,7 @@ protected:
        /** Expansion point */
        ex point;
 };
+GINAC_DECLARE_UNARCHIVER(pseries); 
 
 
 // utility functions
index 5a4d890..2f5ac70 100644 (file)
 
 namespace GiNaC {
 
-std::type_info const* find_tinfo_key(const std::string &class_name)
-{
-       return registered_class_info::find(class_name)->options.get_id();
-}
-
-unarch_func find_unarch_func(const std::string &class_name)
-{
-       return registered_class_info::find(class_name)->options.get_unarch_func();
-}
-
 } // namespace GiNaC
index 2bf97a5..caa5e84 100644 (file)
@@ -76,22 +76,16 @@ template<typename T> inline return_type_t make_return_type_t(const unsigned rl =
        return ret;
 }
 
-/** Unarchiving function (static member function of every GiNaC class). */
-typedef ex (*unarch_func)(const archive_node &n, lst &sym_lst);
-
-
 /** This class stores information about a registered GiNaC class. */
 class registered_class_options {
 public:
        registered_class_options(const char *n, const char *p, 
-                                const std::type_info& ti,
-                                unarch_func f)
-        : name(n), parent_name(p), tinfo_key(&ti), unarchive(f) {}
+                                const std::type_info& ti)
+        : name(n), parent_name(p), tinfo_key(&ti) { }
 
        const char *get_name() const { return name; }
        const char *get_parent_name() const { return parent_name; }
        std::type_info const* get_id() const { return tinfo_key; }
-       unarch_func get_unarch_func() const { return unarchive; }
        const std::vector<print_functor> &get_print_dispatch_table() const { return print_dispatch_table; }
 
        template <class Ctx, class T, class C>
@@ -126,7 +120,6 @@ private:
        const char *name;         /**< Class name. */
        const char *parent_name;  /**< Name of superclass. */
        std::type_info const* tinfo_key;        /**< Type information key. */
-       unarch_func unarchive;    /**< Pointer to unarchiving function. */
        std::vector<print_functor> print_dispatch_table; /**< Method table for print() dispatch */
 };
 
@@ -144,11 +137,6 @@ public: \
        virtual const GiNaC::registered_class_info &get_class_info() const { return classname::get_class_info_static(); } \
        virtual GiNaC::registered_class_info &get_class_info() { return classname::get_class_info_static(); } \
        virtual const char *class_name() const { return classname::get_class_info_static().options.get_name(); } \
-       \
-       classname(const GiNaC::archive_node &n, GiNaC::lst &sym_lst); \
-       virtual void archive(GiNaC::archive_node &n) const; \
-       static GiNaC::ex unarchive(const GiNaC::archive_node &n, GiNaC::lst &sym_lst); \
-       \
        class visitor { \
        public: \
                virtual void visit(const classname &) = 0; \
@@ -179,24 +167,17 @@ private:
 
 /** Macro for inclusion in the implementation of each registered class. */
 #define GINAC_IMPLEMENT_REGISTERED_CLASS(classname, supername) \
-       GiNaC::registered_class_info classname::reg_info = GiNaC::registered_class_info(GiNaC::registered_class_options(#classname, #supername, typeid(classname), &classname::unarchive)); 
+       GiNaC::registered_class_info classname::reg_info = GiNaC::registered_class_info(GiNaC::registered_class_options(#classname, #supername, typeid(classname))); 
 
 /** Macro for inclusion in the implementation of each registered class.
  *  Additional options can be specified. */
 #define GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(classname, supername, options) \
-       GiNaC::registered_class_info classname::reg_info = GiNaC::registered_class_info(GiNaC::registered_class_options(#classname, #supername, typeid(classname), &classname::unarchive).options);
+       GiNaC::registered_class_info classname::reg_info = GiNaC::registered_class_info(GiNaC::registered_class_options(#classname, #supername, typeid(classname)).options);
 
 /** Macro for inclusion in the implementation of each registered class.
  *  Additional options can be specified. */
 #define GINAC_IMPLEMENT_REGISTERED_CLASS_OPT_T(classname, supername, options) \
-       GiNaC::registered_class_info classname::reg_info = GiNaC::registered_class_info(GiNaC::registered_class_options(#classname, #supername, typeid(classname), &classname::unarchive).options);
-
-
-/** Find type information key by class name. */
-extern std::type_info const* find_tinfo_key(const std::string &class_name);
-
-/** Find unarchiving function by class name. */
-extern unarch_func find_unarch_func(const std::string &class_name);
+       GiNaC::registered_class_info classname::reg_info = GiNaC::registered_class_info(GiNaC::registered_class_options(#classname, #supername, typeid(classname)).options);
 
 
 /** Add or replace a print method. */
index b59f7ab..d345943 100644 (file)
@@ -55,8 +55,9 @@ relational::relational(const ex & lhs, const ex & rhs, operators oper) :
 // archiving
 //////////
 
-relational::relational(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void relational::read_archive(const archive_node& n, lst& sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        unsigned int opi;
        if (!(n.find_unsigned("op", opi)))
                throw (std::runtime_error("unknown relational operator in archive"));
@@ -64,6 +65,7 @@ relational::relational(const archive_node &n, lst &sym_lst) : inherited(n, sym_l
        n.find_ex("lh", lh, sym_lst);
        n.find_ex("rh", rh, sym_lst);
 }
+GINAC_BIND_UNARCHIVER(relational);
 
 void relational::archive(archive_node &n) const
 {
@@ -73,8 +75,6 @@ void relational::archive(archive_node &n) const
        n.add_unsigned("op", o);
 }
 
-DEFAULT_UNARCHIVE(relational)
-
 //////////
 // functions overriding virtual functions from base classes
 //////////
index 91cf519..b16b9d3 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "basic.h"
 #include "ex.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -59,6 +60,10 @@ public:
        ex subs(const exmap & m, unsigned options = 0) const;
        ex eval(int level=0) const;
 
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        ex eval_ncmul(const exvector & v) const;
        bool match_same_type(const basic & other) const;
@@ -100,6 +105,7 @@ protected:
        ex rh;
        operators o;
 };
+GINAC_DECLARE_UNARCHIVER(relational); 
 
 // utility functions
 
index 3987d80..67b29cb 100644 (file)
@@ -118,7 +118,6 @@ class structure : public basic, public ComparisonPolicy<T> {
 
        // helpers
        static const char *get_class_name() { return "structure"; }
-
        // constructors
 public:
        /** Construct structure as a copy of a given C++ structure. */
@@ -232,24 +231,6 @@ private:
 template <class T, template <class> class CP>
 structure<T, CP>::structure() { }
 
-/** Construct object from archive_node. */
-template <class T, template <class> class CP>
-structure<T, CP>::structure(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst) {}
-
-/** Unarchive the object. */
-template <class T, template <class> class CP>
-ex structure<T, CP>::unarchive(const archive_node &n, lst &sym_lst)
-{
-       return (new structure(n, sym_lst))->setflag(status_flags::dynallocated);
-}
-
-/** Archive the object. */
-template <class T, template <class> class CP>
-void structure<T, CP>::archive(archive_node &n) const
-{
-       inherited::archive(n);
-}
-
 /** Compare two structures of the same type. */
 template <class T, template <class> class CP>
 int structure<T, CP>::compare_same_type(const basic & other) const
@@ -261,7 +242,7 @@ int structure<T, CP>::compare_same_type(const basic & other) const
 }
 
 template <class T, template <class> class CP>
-registered_class_info structure<T, CP>::reg_info = registered_class_info(registered_class_options(structure::get_class_name(), "basic", typeid(structure<T, CP>), &structure::unarchive));
+registered_class_info structure<T, CP>::reg_info = registered_class_info(registered_class_options(structure::get_class_name(), "basic", typeid(structure<T, CP>)));
 
 
 } // namespace GiNaC
index 9a72991..aa8ebc0 100644 (file)
@@ -96,31 +96,28 @@ possymbol::possymbol(const std::string & initname, const std::string & texname)
 // archiving
 //////////
 
-/** Construct object from archive_node. */
-symbol::symbol(const archive_node &n, lst &sym_lst)
- : inherited(n, sym_lst), serial(next_serial++)
+/** Read object from archive_node. */
+void symbol::read_archive(const archive_node &n, lst &sym_lst)
 {
-       if (!n.find_string("name", name))
-               name = std::string("");
-       if (!n.find_string("TeXname", TeX_name))
-               TeX_name = std::string("");
-       setflag(status_flags::evaluated | status_flags::expanded);
-}
-
-/** Unarchive the object. */
-ex symbol::unarchive(const archive_node &n, lst &sym_lst)
-{
-       ex s = (new symbol(n, sym_lst))->setflag(status_flags::dynallocated);
+       inherited::read_archive(n, sym_lst);
+       serial = next_serial++;
+       std::string tmp_name;
+       n.find_string("name", tmp_name);
 
        // If symbol is in sym_lst, return the existing symbol
        for (lst::const_iterator it = sym_lst.begin(); it != sym_lst.end(); ++it) {
-               if (is_a<symbol>(*it) && (ex_to<symbol>(*it).name == ex_to<symbol>(s).name))
-                       return *it;
+               if (is_a<symbol>(*it) && (ex_to<symbol>(*it).name == tmp_name)) {
+                       *this = ex_to<symbol>(*it);
+                       return;
+               }
        }
+       name = tmp_name;
+       if (!n.find_string("TeXname", TeX_name))
+               TeX_name = std::string("");
+       setflag(status_flags::evaluated | status_flags::expanded);
 
-       // Otherwise add new symbol to list and return it
-       sym_lst.append(s);
-       return s;
+       setflag(status_flags::dynallocated);
+       sym_lst.append(*this);
 }
 
 /** Archive the object. */
@@ -328,6 +325,10 @@ static const std::string& get_default_TeX_name(const std::string& name)
                return name;
 }
 
+GINAC_BIND_UNARCHIVER(symbol);
+GINAC_BIND_UNARCHIVER(realsymbol);
+GINAC_BIND_UNARCHIVER(possymbol);
+
 //////////
 // static member variables
 //////////
index bd894c9..3537776 100644 (file)
@@ -28,6 +28,7 @@
 #include "basic.h"
 #include "ex.h"
 #include "ptr.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -36,7 +37,6 @@ namespace GiNaC {
 class symbol : public basic
 {
        GINAC_DECLARE_REGISTERED_CLASS(symbol, basic)
-
        // other constructors
 public:
        explicit symbol(const std::string & initname);
@@ -56,6 +56,10 @@ public:
        ex real_part() const;
        ex imag_part() const;
        bool is_polynomial(const ex & var) const;
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
@@ -81,6 +85,7 @@ protected:
 private:
        static unsigned next_serial;
 };
+GINAC_DECLARE_UNARCHIVER(symbol);
 
 
 /** Specialization of symbol to real domain */
@@ -99,6 +104,7 @@ public:
 
        realsymbol* duplicate() const { return new realsymbol(*this); }
 };
+GINAC_DECLARE_UNARCHIVER(realsymbol);
 
 
 /** Specialization of symbol to real domain */
@@ -113,6 +119,7 @@ public:
 
        possymbol* duplicate() const { return new possymbol(*this); }
 };
+GINAC_DECLARE_UNARCHIVER(possymbol);
 
 } // namespace GiNaC
 
index dd3029e..6b684c3 100644 (file)
@@ -82,8 +82,9 @@ symmetry::symmetry(symmetry_type t, const symmetry &c1, const symmetry &c2) :  t
 //////////
 
 /** Construct object from archive_node. */
-symmetry::symmetry(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void symmetry::read_archive(const archive_node &n, lst &sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        unsigned t;
        if (!(n.find_unsigned("type", t)))
                throw (std::runtime_error("unknown symmetry type in archive"));
@@ -110,6 +111,7 @@ symmetry::symmetry(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
                }
        }
 }
+GINAC_BIND_UNARCHIVER(symmetry);
 
 /** Archive the object. */
 void symmetry::archive(archive_node &n) const
@@ -133,8 +135,6 @@ void symmetry::archive(archive_node &n) const
        }
 }
 
-DEFAULT_UNARCHIVE(symmetry)
-
 //////////
 // functions overriding virtual functions from base classes
 //////////
index 5cd62c7..4b4fea5 100644 (file)
@@ -26,6 +26,7 @@
 #include <set>
 
 #include "ex.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -83,6 +84,10 @@ public:
        /** Check whether this node involves a cyclic symmetry. */
        bool has_cyclic() const;
 
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_tree(const print_tree & c, unsigned level) const;
@@ -99,6 +104,7 @@ private:
        /** Vector of child nodes. */
        exvector children;
 };
+GINAC_DECLARE_UNARCHIVER(symmetry); 
 
 
 // global functions
index 22b3e73..259af3e 100644 (file)
@@ -96,17 +96,12 @@ tensepsilon::tensepsilon(bool mink, bool ps) : minkowski(mink), pos_sig(ps)
 // archiving
 //////////
 
-DEFAULT_ARCHIVING(tensor)
-DEFAULT_ARCHIVING(tensdelta)
-DEFAULT_ARCHIVING(tensmetric)
-DEFAULT_ARCHIVING(spinmetric)
-DEFAULT_UNARCHIVE(minkmetric)
-DEFAULT_UNARCHIVE(tensepsilon)
-
-minkmetric::minkmetric(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void minkmetric::read_archive(const archive_node& n, lst& sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        n.find_bool("pos_sig", pos_sig);
 }
+GINAC_BIND_UNARCHIVER(minkmetric);
 
 void minkmetric::archive(archive_node &n) const
 {
@@ -114,11 +109,13 @@ void minkmetric::archive(archive_node &n) const
        n.add_bool("pos_sig", pos_sig);
 }
 
-tensepsilon::tensepsilon(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void tensepsilon::read_archive(const archive_node& n, lst& sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        n.find_bool("minkowski", minkowski);
        n.find_bool("pos_sig", pos_sig);
 }
+GINAC_BIND_UNARCHIVER(tensepsilon);
 
 void tensepsilon::archive(archive_node &n) const
 {
@@ -127,6 +124,10 @@ void tensepsilon::archive(archive_node &n) const
        n.add_bool("pos_sig", pos_sig);
 }
 
+GINAC_BIND_UNARCHIVER(tensdelta);
+GINAC_BIND_UNARCHIVER(tensmetric);
+GINAC_BIND_UNARCHIVER(spinmetric);
+
 //////////
 // functions overriding virtual functions from base classes
 //////////
index 37deaa5..33859b1 100644 (file)
@@ -24,6 +24,7 @@
 #define __GINAC_TENSOR_H__
 
 #include "ex.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -66,6 +67,7 @@ protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(tensdelta);
 
 
 /** This class represents a general metric tensor which can be used to
@@ -86,6 +88,7 @@ protected:
        unsigned return_type() const { return return_types::commutative; }
        void do_print(const print_context & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(tensmetric);
 
 
 /** This class represents a Minkowski metric tensor. It has all the
@@ -105,6 +108,10 @@ public:
        bool info(unsigned inf) const;
        ex eval_indexed(const basic & i) const;
 
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
        // non-virtual functions in this class
 protected:
        unsigned return_type() const { return return_types::commutative; }
@@ -115,6 +122,7 @@ protected:
 private:
        bool pos_sig; /**< If true, the metric is diag(-1,1,1...). Otherwise it is diag(1,-1,-1,...). */
 };
+GINAC_DECLARE_UNARCHIVER(minkmetric); 
 
 
 /** This class represents an antisymmetric spinor metric tensor which
@@ -131,11 +139,11 @@ public:
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 
-       // non-virtual functions in this class
 protected:
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
 };
+GINAC_DECLARE_UNARCHIVER(spinmetric);
 
 
 /** This class represents the totally antisymmetric epsilon tensor. If
@@ -155,6 +163,10 @@ public:
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
        // non-virtual functions in this class
 protected:
        unsigned return_type() const { return return_types::commutative; }
@@ -166,6 +178,7 @@ private:
        bool minkowski; /**< If true, tensor is in Minkowski-type space. Otherwise it is in a Euclidean space. */
        bool pos_sig;   /**< If true, the metric is assumed to be diag(-1,1,1...). Otherwise it is diag(1,-1,-1,...). This is only relevant if minkowski = true. */
 };
+GINAC_DECLARE_UNARCHIVER(tensepsilon); 
 
 
 // utility functions
index f44ed9f..64e5cdc 100644 (file)
@@ -443,6 +443,8 @@ library_init::~library_init()
        }
 }
 
+void library_init::init_unarchivers() { }
+
 // comment skeleton for header files
 
 
index c5d7e03..98c6758 100644 (file)
@@ -407,20 +407,6 @@ extern const ex _ex120;
 #define DEFAULT_CTOR(classname) \
 classname::classname() { setflag(status_flags::evaluated | status_flags::expanded); }
 
-#define DEFAULT_UNARCHIVE(classname) \
-ex classname::unarchive(const archive_node &n, lst &sym_lst) \
-{ \
-       return (new classname(n, sym_lst))->setflag(status_flags::dynallocated); \
-}
-
-#define DEFAULT_ARCHIVING(classname) \
-classname::classname(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst) {} \
-DEFAULT_UNARCHIVE(classname) \
-void classname::archive(archive_node &n) const \
-{ \
-       inherited::archive(n); \
-}
-
 #define DEFAULT_COMPARE(classname) \
 int classname::compare_same_type(const basic & other) const \
 { \
index 50eb67b..9409938 100644 (file)
@@ -55,11 +55,13 @@ wildcard::wildcard(unsigned l) : label(l)
 // archiving
 //////////
 
-wildcard::wildcard(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void wildcard::read_archive(const archive_node& n, lst& sym_lst)
 {
+       inherited::read_archive(n, sym_lst);
        n.find_unsigned("label", label);
        setflag(status_flags::evaluated | status_flags::expanded);
 }
+GINAC_BIND_UNARCHIVER(wildcard);
 
 void wildcard::archive(archive_node &n) const
 {
@@ -67,8 +69,6 @@ void wildcard::archive(archive_node &n) const
        n.add_unsigned("label", label);
 }
 
-DEFAULT_UNARCHIVE(wildcard)
-
 //////////
 // functions overriding virtual functions from base classes
 //////////
index 9729237..d8ac639 100644 (file)
@@ -24,6 +24,7 @@
 #define __GINAC_WILDCARD_H__
 
 #include "ex.h"
+#include "archive.h"
 
 namespace GiNaC {
 
@@ -43,6 +44,10 @@ public:
 public:
        bool match(const ex & pattern, exmap& repl_lst) const;
 
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms);
 protected:
        unsigned calchash() const;
 
@@ -59,6 +64,7 @@ protected:
 private:
        unsigned label; /**< Label used to distinguish different wildcards */
 };
+GINAC_DECLARE_UNARCHIVER(wildcard);
 
 
 // utility functions