GiNaC  1.6.2
archive.h
Go to the documentation of this file.
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

This page is part of the GiNaC developer's reference. It was generated automatically by doxygen. For an introduction, see the tutorial.