So people who don't use (un)archiving don't need to bother with it.
}
// 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);
}
// archiving
//////////
-DEFAULT_ARCHIVING(add)
+GINAC_BIND_UNARCHIVER(add);
//////////
// functions overriding virtual functions from base classes
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
}
}
+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
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()
{
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
//////////
/** 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
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;
// 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;
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
// 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;
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
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). */
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
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
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
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
// 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;
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
// 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:
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. */
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
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. */
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
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
// 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
{
#include <string>
#include "basic.h"
#include "ex.h"
+#include "archive.h"
namespace GiNaC {
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);
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;
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;
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;
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
{
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
*
* @see utils.cpp */
class library_init {
+ static void init_unarchivers();
public:
library_init();
~library_init();
// 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;
n.add_ex("overall_coeff", overall_coeff);
}
-DEFAULT_UNARCHIVE(expairseq)
//////////
// functions overriding virtual functions from base classes
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;
// archiving
//////////
-DEFAULT_ARCHIVING(fail)
-
//////////
// functions overriding virtual functions from base classes
//////////
DEFAULT_COMPARE(fail)
DEFAULT_PRINT(fail, "FAIL")
+GINAC_BIND_UNARCHIVER(fail);
} // namespace GiNaC
#define __GINAC_FAIL_H__
#include "basic.h"
+#include "archive.h"
namespace GiNaC {
protected:
void do_print(const print_context & c, unsigned level) const;
};
+GINAC_DECLARE_UNARCHIVER(fail);
} // namespace GiNaC
// 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;
++i;
}
}
+GINAC_BIND_UNARCHIVER(fderivative);
void fderivative::archive(archive_node &n) const
{
}
}
-DEFAULT_UNARCHIVE(fderivative)
//////////
// functions overriding virtual functions from base classes
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;
protected:
paramset parameter_set; /**< Set of parameter numbers with respect to which to take the derivative */
};
+GINAC_DECLARE_UNARCHIVER(fderivative);
} // namespace GiNaC
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;
protected:
unsigned serial;
};
+GINAC_DECLARE_UNARCHIVER(function);
// utility functions/macros
//////////
/** 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)) {
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
{
n.add_string("name", registered_functions()[serial].name);
}
+GINAC_BIND_UNARCHIVER(function);
+
//////////
// functions overriding virtual functions from base classes
//////////
// 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
{
n.add_bool("dotted", dotted);
}
-DEFAULT_UNARCHIVE(idx)
-DEFAULT_UNARCHIVE(varidx)
-DEFAULT_UNARCHIVE(spinidx)
-
//////////
// functions overriding virtual functions from base classes
//////////
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;
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
// 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;
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
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;
protected:
bool dotted;
};
+GINAC_DECLARE_UNARCHIVER(spinidx);
// utility functions
// 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;
const_cast<symmetry &>(ex_to<symmetry>(symtree)).validate(seq.size() - 1);
}
}
+GINAC_BIND_UNARCHIVER(indexed);
void indexed::archive(archive_node &n) const
{
n.add_ex("symmetry", symtree);
}
-DEFAULT_UNARCHIVE(indexed)
-
//////////
// functions overriding virtual functions from base classes
//////////
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;
protected:
ex symtree; /**< Index symmetry (tree of symmetry objects) */
};
+GINAC_DECLARE_UNARCHIVER(indexed);
class spmapkey {
// 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);
n.add_ex("f", f);
}
-DEFAULT_UNARCHIVE(integral)
-
//////////
// functions overriding virtual functions from base classes
//////////
return *this;
}
+GINAC_BIND_UNARCHIVER(integral);
} // namespace GiNaC
#include "basic.h"
#include "ex.h"
+#include "archive.h"
namespace GiNaC {
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;
ex b;
ex f;
};
+GINAC_DECLARE_UNARCHIVER(integral);
// utility functions
*/
#include "lst.h"
+#include "archive.h"
namespace GiNaC {
return inherited::info(inf);
}
+GINAC_BIND_UNARCHIVER(lst);
+
} // namespace GiNaC
// defined in lst.cpp
template<> bool lst::info(unsigned inf) const;
+GINAC_DECLARE_UNARCHIVER(lst);
} // namespace GiNaC
// 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
{
}
}
-DEFAULT_UNARCHIVE(matrix)
-
//////////
// functions overriding virtual functions from base classes
//////////
#include <string>
#include "basic.h"
#include "ex.h"
+#include "archive.h"
namespace GiNaC {
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; };
unsigned col; ///< number of columns
exvector m; ///< representation (cols indexed first)
};
+GINAC_DECLARE_UNARCHIVER(matrix);
// wrapper functions around member functions
// archiving
//////////
-DEFAULT_ARCHIVING(mul)
-
//////////
// functions overriding virtual functions from base classes
//////////
return std::auto_ptr<epvector>(0); // nothing has changed
}
+GINAC_BIND_UNARCHIVER(mul);
+
} // namespace GiNaC
static bool can_be_further_expanded(const ex & e);
std::auto_ptr<epvector> expandchildren(unsigned options) const;
};
+GINAC_DECLARE_UNARCHIVER(mul);
} // namespace GiNaC
// archiving
//////////
-DEFAULT_ARCHIVING(ncmul)
-
+
//////////
// functions overriding virtual functions from base classes
//////////
status_flags::evaluated);
}
+GINAC_BIND_UNARCHIVER(ncmul);
+
} // namespace GiNaC
#define __GINAC_NCMUL_H__
#include "exprseq.h"
+#include "archive.h"
namespace GiNaC {
public:
const exvector & get_factors() const;
};
+GINAC_DECLARE_UNARCHIVER(ncmul);
// friend funtions
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
}
setflag(status_flags::evaluated | status_flags::expanded);
}
+GINAC_BIND_UNARCHIVER(numeric);
static void write_real_float(std::ostream& s, const cln::cl_R& n)
{
n.add_string("number", s.str());
}
-DEFAULT_UNARCHIVE(numeric)
-
//////////
// functions overriding virtual functions from base classes
//////////
#include "basic.h"
#include "ex.h"
+#include "archive.h"
#include <stdexcept>
#include <vector>
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 */
protected:
cln::cl_N value;
};
+GINAC_DECLARE_UNARCHIVER(numeric);
// global constants
// 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);
}
n.add_ex("exponent", exponent);
}
-DEFAULT_UNARCHIVE(power)
-
//////////
// functions overriding virtual functions from base classes
//////////
return result;
}
+GINAC_BIND_UNARCHIVER(power);
+
} // namespace GiNaC
#include "basic.h"
#include "ex.h"
+#include "archive.h"
namespace GiNaC {
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;
ex basis;
ex exponent;
};
+GINAC_DECLARE_UNARCHIVER(power);
// wrapper functions
* 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;
n.add_ex("point", point);
}
-DEFAULT_UNARCHIVE(pseries)
//////////
// functions overriding virtual functions from base classes
return e;
}
+GINAC_BIND_UNARCHIVER(pseries);
+
} // namespace GiNaC
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;
/** Expansion point */
ex point;
};
+GINAC_DECLARE_UNARCHIVER(pseries);
// utility functions
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
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>
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 */
};
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; \
/** 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. */
// 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"));
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
{
n.add_unsigned("op", o);
}
-DEFAULT_UNARCHIVE(relational)
-
//////////
// functions overriding virtual functions from base classes
//////////
#include "basic.h"
#include "ex.h"
+#include "archive.h"
namespace GiNaC {
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;
ex rh;
operators o;
};
+GINAC_DECLARE_UNARCHIVER(relational);
// utility functions
// helpers
static const char *get_class_name() { return "structure"; }
-
// constructors
public:
/** Construct structure as a copy of a given C++ structure. */
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
}
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
// 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. */
return name;
}
+GINAC_BIND_UNARCHIVER(symbol);
+GINAC_BIND_UNARCHIVER(realsymbol);
+GINAC_BIND_UNARCHIVER(possymbol);
+
//////////
// static member variables
//////////
#include "basic.h"
#include "ex.h"
#include "ptr.h"
+#include "archive.h"
namespace GiNaC {
class symbol : public basic
{
GINAC_DECLARE_REGISTERED_CLASS(symbol, basic)
-
// other constructors
public:
explicit symbol(const std::string & initname);
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;
private:
static unsigned next_serial;
};
+GINAC_DECLARE_UNARCHIVER(symbol);
/** Specialization of symbol to real domain */
realsymbol* duplicate() const { return new realsymbol(*this); }
};
+GINAC_DECLARE_UNARCHIVER(realsymbol);
/** Specialization of symbol to real domain */
possymbol* duplicate() const { return new possymbol(*this); }
};
+GINAC_DECLARE_UNARCHIVER(possymbol);
} // namespace GiNaC
//////////
/** 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"));
}
}
}
+GINAC_BIND_UNARCHIVER(symmetry);
/** Archive the object. */
void symmetry::archive(archive_node &n) const
}
}
-DEFAULT_UNARCHIVE(symmetry)
-
//////////
// functions overriding virtual functions from base classes
//////////
#include <set>
#include "ex.h"
+#include "archive.h"
namespace GiNaC {
/** 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;
/** Vector of child nodes. */
exvector children;
};
+GINAC_DECLARE_UNARCHIVER(symmetry);
// global functions
// 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
{
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
{
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
//////////
#define __GINAC_TENSOR_H__
#include "ex.h"
+#include "archive.h"
namespace GiNaC {
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
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
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; }
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
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
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; }
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
}
}
+void library_init::init_unarchivers() { }
+
// comment skeleton for header files
#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 \
{ \
// 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
{
n.add_unsigned("label", label);
}
-DEFAULT_UNARCHIVE(wildcard)
-
//////////
// functions overriding virtual functions from base classes
//////////
#define __GINAC_WILDCARD_H__
#include "ex.h"
+#include "archive.h"
namespace GiNaC {
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;
private:
unsigned label; /**< Label used to distinguish different wildcards */
};
+GINAC_DECLARE_UNARCHIVER(wildcard);
// utility functions