- changed old-style power() to new-style pow()
[ginac.git] / ginac / archive.h
1 /** @file archive.h
2  *
3  *  Archiving of GiNaC expressions. */
4
5 /*
6  *  GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #ifndef __GINAC_ARCHIVE_H__
24 #define __GINAC_ARCHIVE_H__
25
26 #include <ginac/ex.h>
27
28 #include <string>
29 #include <vector>
30
31 class ostream;
32 class istream;
33
34 #ifndef NO_GINAC_NAMESPACE
35 namespace GiNaC {
36 #endif // ndef NO_GINAC_NAMESPACE
37
38 class lst;
39 class archive;
40
41
42 /** Numerical ID value to refer to an archive_node. */
43 typedef unsigned int archive_node_id;
44
45 /** Numerical ID value to refer to a string. */
46 typedef unsigned int archive_atom;
47
48
49 /** This class stores all properties needed to record/retrieve the state
50  *  of one object of class basic (or a derived class). Each property is
51  *  addressed by its name and data type. */
52 class archive_node
53 {
54         friend ostream &operator<<(ostream &os, const archive_node &ar);
55         friend istream &operator>>(istream &is, archive_node &ar);
56
57 public:
58         archive_node(archive &ar) : a(ar), has_expression(false) {}
59         archive_node(archive &ar, const ex &expr);
60         ~archive_node() {}
61
62         archive_node(const archive_node &other);
63         const archive_node &operator=(const archive_node &other);
64
65         bool has_same_ex_as(const archive_node &other) const;
66
67         void add_bool(const string &name, bool value);
68         void add_unsigned(const string &name, unsigned int value);
69         void add_string(const string &name, const string &value);
70         void add_ex(const string &name, const ex &value);
71
72         bool find_bool(const string &name, bool &ret) const;
73         bool find_unsigned(const string &name, unsigned int &ret) const;
74         bool find_string(const string &name, string &ret) const;
75         bool find_ex(const string &name, ex &ret, const lst &sym_lst, unsigned int index = 0) const;
76
77         ex unarchive(const lst &sym_lst) const;
78
79         void forget(void);
80         void dump(ostream &os) const;
81
82 private:
83         /** Property data types */
84         enum property_type {
85                 PTYPE_BOOL,
86                 PTYPE_UNSIGNED,
87                 PTYPE_STRING,
88                 PTYPE_NODE
89         };
90
91         /** Archived property (data type, name and associated data) */
92         struct property {
93                 property() {}
94                 property(archive_atom n, property_type t, unsigned int v) : type(t), name(n), value(v) {}
95                 ~property() {}
96
97                 property(const property &other) : type(other.type), name(other.name), value(other.value) {}
98                 const property &operator=(const property &other);
99
100                 property_type type;     /**< Data type of property. */
101                 archive_atom name;      /**< Name of property. */
102                 unsigned int value;     /**< Stored value. */
103         };
104
105         /** Reference to the archive to which this node belongs. */
106         archive &a;
107
108         /** Vector of stored properties. */
109         vector<property> props;
110
111         /** Flag indicating whether a cached unarchived representation of this node exists. */
112         mutable bool has_expression;
113
114         /** The cached unarchived representation of this node (if any). */
115         mutable ex e;
116 };
117
118
119 /** This class holds archived versions of GiNaC expressions (class ex).
120  *  An archive can be constructed from an expression and then written to
121  *  a stream; or it can be read from a stream and then unarchived, yielding
122  *  back the expression. Archives can hold multiple expressions which can
123  *  be referred to by name or index number. The main component of the
124  *  archive class is a vector of archive_nodes which each store one object
125  *  of class basic (or a derived class). */
126 class archive
127 {
128         friend ostream &operator<<(ostream &os, const archive &ar);
129         friend istream &operator>>(istream &is, archive &ar);
130
131 public:
132         archive() {}
133         ~archive() {}
134
135         /** Construct archive from expression using the default name "ex". */
136         archive(const ex &e) {archive_ex(e, "ex");}
137
138         /** Construct archive from expression using the specified name. */
139         archive(const ex &e, const char *n) {archive_ex(e, n);}
140
141         archive_node_id add_node(const archive_node &n);
142         archive_node &get_node(archive_node_id id);
143
144         void archive_ex(const ex &e, const char *name);
145         ex unarchive_ex(const lst &sym_lst, const char *name) const;
146         ex unarchive_ex(const lst &sym_lst, unsigned int index = 0) const;
147         ex unarchive_ex(const lst &sym_lst, string &name, unsigned int index = 0) const;
148         unsigned int num_expressions(void) const;
149
150         void clear(void);
151
152         void forget(void);
153         void dump(ostream &os) const;
154
155 private:
156         /** Vector of archived nodes. */
157         vector<archive_node> nodes;
158
159         /** Archived expression descriptor. */
160         struct archived_ex {
161                 archived_ex() {}
162                 archived_ex(archive_atom n, archive_node_id node) : name(n), root(node) {}
163
164                 archive_atom name;              /**< Name of expression. */
165                 archive_node_id root;   /**< ID of root node. */
166         };
167
168         /** Vector of archived expression descriptors. */
169         vector<archived_ex> exprs;
170
171 public:
172         archive_atom atomize(const string &s) const;
173         const string &unatomize(archive_atom id) const;
174
175 private:
176         /** Vector of atomized strings (using a vector allows faster unarchiving). */
177         mutable vector<string> atoms;
178 };
179
180
181 ostream &operator<<(ostream &os, const archive &ar);
182 istream &operator>>(istream &is, archive &ar);
183
184
185 #ifndef NO_GINAC_NAMESPACE
186 } // namespace GiNaC
187 #endif // ndef NO_GINAC_NAMESPACE
188
189 #endif // ndef __GINAC_ARCHIVE_H__