00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef GINAC_ARCHIVE_H
00024 #define GINAC_ARCHIVE_H
00025
00026 #include "ex.h"
00027
00028 #include <iosfwd>
00029 #include <map>
00030 #include <string>
00031 #include <vector>
00032
00033 namespace GiNaC {
00034
00035 class archive;
00036
00037
00039 typedef unsigned archive_node_id;
00040
00042 typedef unsigned archive_atom;
00043
00044
00048 class archive_node
00049 {
00050 friend std::ostream &operator<<(std::ostream &os, const archive_node &ar);
00051 friend std::istream &operator>>(std::istream &is, archive_node &ar);
00052
00053 public:
00055 enum property_type {
00056 PTYPE_BOOL,
00057 PTYPE_UNSIGNED,
00058 PTYPE_STRING,
00059 PTYPE_NODE
00060 };
00061
00065 struct property_info {
00066 property_info() {}
00067 property_info(property_type t, const std::string &n, unsigned c = 1) : type(t), name(n), count(c) {}
00068
00069 property_type type;
00070 std::string name;
00071 unsigned count;
00072 };
00073 typedef std::vector<property_info> propinfovector;
00074
00076 struct property {
00077 property() {}
00078 property(archive_atom n, property_type t, unsigned v) : type(t), name(n), value(v) {}
00079
00080 property_type type;
00081 archive_atom name;
00082 unsigned value;
00083 };
00084 typedef std::vector<property>::const_iterator archive_node_cit;
00085
00086 archive_node() : a(*dummy_ar_creator()), has_expression(false) {}
00087 archive_node(archive &ar) : a(ar), has_expression(false) {}
00088 archive_node(archive &ar, const ex &expr);
00089
00090 const archive_node &operator=(const archive_node &other);
00091
00093 void add_bool(const std::string &name, bool value);
00094
00096 void add_unsigned(const std::string &name, unsigned value);
00097
00099 void add_string(const std::string &name, const std::string &value);
00100
00102 void add_ex(const std::string &name, const ex &value);
00103
00106 bool find_bool(const std::string &name, bool &ret, unsigned index = 0) const;
00107
00110 bool find_unsigned(const std::string &name, unsigned &ret, unsigned index = 0) const;
00111
00114 bool find_string(const std::string &name, std::string &ret, unsigned index = 0) const;
00115
00118 archive_node_cit find_first(const std::string &name) const;
00119 archive_node_cit find_last(const std::string &name) const;
00120
00123 bool find_ex(const std::string &name, ex &ret, lst &sym_lst, unsigned index = 0) const;
00124
00128 void find_ex_by_loc(archive_node_cit loc, ex &ret, lst &sym_lst) const;
00129
00132 const archive_node &find_ex_node(const std::string &name, unsigned index = 0) const;
00133
00135 void get_properties(propinfovector &v) const;
00136
00137 ex unarchive(lst &sym_lst) const;
00138 bool has_same_ex_as(const archive_node &other) const;
00139 bool has_ex() const {return has_expression;}
00140 ex get_ex() const {return e;}
00141
00142 void forget();
00143 void printraw(std::ostream &os) const;
00144
00145 private:
00146 static archive* dummy_ar_creator();
00147
00149 archive &a;
00150
00152 std::vector<property> props;
00153
00155 mutable bool has_expression;
00156
00158 mutable ex e;
00159 };
00160
00161 typedef basic* (*synthesize_func)();
00162 typedef std::map<std::string, synthesize_func> unarchive_map_t;
00163
00164 class unarchive_table_t
00165 {
00166 static int usecount;
00167 static unarchive_map_t* unarch_map;
00168 public:
00169 unarchive_table_t();
00170 ~unarchive_table_t();
00171 synthesize_func find(const std::string& classname) const;
00172 void insert(const std::string& classname, synthesize_func f);
00173 };
00174 static unarchive_table_t unarch_table_instance;
00175
00214 #define GINAC_DECLARE_UNARCHIVER(classname) \
00215 class classname ## _unarchiver \
00216 { \
00217 static int usecount; \
00218 public: \
00219 static GiNaC::basic* create(); \
00220 classname ## _unarchiver(); \
00221 ~ classname ## _unarchiver(); \
00222 }; \
00223 static classname ## _unarchiver classname ## _unarchiver_instance
00224
00225 #define GINAC_BIND_UNARCHIVER(classname) \
00226 classname ## _unarchiver::classname ## _unarchiver() \
00227 { \
00228 static GiNaC::unarchive_table_t table; \
00229 if (usecount++ == 0) { \
00230 table.insert(std::string(#classname), \
00231 &(classname ## _unarchiver::create)); \
00232 } \
00233 } \
00234 GiNaC::basic* classname ## _unarchiver::create() \
00235 { \
00236 return new classname(); \
00237 } \
00238 classname ## _unarchiver::~ classname ## _unarchiver() { } \
00239 int classname ## _unarchiver::usecount = 0
00240
00241
00249 class archive
00250 {
00251 friend std::ostream &operator<<(std::ostream &os, const archive &ar);
00252 friend std::istream &operator>>(std::istream &is, archive &ar);
00253
00254 public:
00255 archive() {}
00256 ~archive() {}
00257
00259 archive(const ex &e) {archive_ex(e, "ex");}
00260
00262 archive(const ex &e, const char *n) {archive_ex(e, n);}
00263
00267 void archive_ex(const ex &e, const char *name);
00268
00272 ex unarchive_ex(const lst &sym_lst, const char *name) const;
00273
00278 ex unarchive_ex(const lst &sym_lst, unsigned index = 0) const;
00279
00285 ex unarchive_ex(const lst &sym_lst, std::string &name, unsigned index = 0) const;
00286
00288 unsigned num_expressions() const;
00289
00291 const archive_node &get_top_node(unsigned index = 0) const;
00292
00294 void clear();
00295
00296 archive_node_id add_node(const archive_node &n);
00297 archive_node &get_node(archive_node_id id);
00298
00299 void forget();
00300 void printraw(std::ostream &os) const;
00301
00302 private:
00304 std::vector<archive_node> nodes;
00305
00307 struct archived_ex {
00308 archived_ex() {}
00309 archived_ex(archive_atom n, archive_node_id node) : name(n), root(node) {}
00310
00311 archive_atom name;
00312 archive_node_id root;
00313 };
00314
00316 std::vector<archived_ex> exprs;
00317
00318 public:
00319 archive_atom atomize(const std::string &s) const;
00320 const std::string &unatomize(archive_atom id) const;
00321
00322 private:
00324 mutable std::vector<std::string> atoms;
00328 typedef std::map<std::string, archive_atom>::const_iterator inv_at_cit;
00329 mutable std::map<std::string, archive_atom> inverse_atoms;
00330
00332 typedef std::map<ex, archive_node_id, ex_is_less>::iterator mapit;
00333 mutable std::map<ex, archive_node_id, ex_is_less> exprtable;
00334 };
00335
00336
00337 std::ostream &operator<<(std::ostream &os, const archive &ar);
00338 std::istream &operator>>(std::istream &is, archive &ar);
00339
00340 }
00341
00342 #endif // ndef GINAC_ARCHIVE_H