|
GiNaC
1.6.2
|
00001 00005 /* 00006 * GiNaC Copyright (C) 1999-2011 Johannes Gutenberg University Mainz, Germany 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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) {} // hack for cint which always requires a default constructor 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 } // namespace GiNaC 00341 00342 #endif // ndef GINAC_ARCHIVE_H