GiNaC  1.8.0
archive.cpp
Go to the documentation of this file.
1 
5 /*
6  * GiNaC Copyright (C) 1999-2020 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "archive.h"
24 #include "registrar.h"
25 #include "ex.h"
26 #include "lst.h"
27 #include "version.h"
28 
29 #include <iostream>
30 #include <stdexcept>
31 
32 namespace GiNaC {
33 
34 
35 void archive::archive_ex(const ex &e, const char *name)
36 {
37  // Create root node (which recursively archives the whole expression tree)
38  // and add it to the archive
39  archive_node_id id = add_node(archive_node(*this, e));
40 
41  // Add root node ID to list of archived expressions
42  archived_ex ae = archived_ex(atomize(name), id);
43  exprs.emplace_back(ae);
44 }
45 
46 
51 {
52  // Look if expression is known to be in some node already.
53  if (n.has_ex()) {
54  auto i = exprtable.find(n.get_ex());
55  if (i != exprtable.end())
56  return i->second;
57  nodes.push_back(n);
58  exprtable[n.get_ex()] = nodes.size() - 1;
59  return nodes.size() - 1;
60  }
61 
62  // Not found, add archive_node to nodes vector
63  nodes.push_back(n);
64  return nodes.size()-1;
65 }
66 
67 
70 {
71  if (id >= nodes.size())
72  throw (std::range_error("archive::get_node(): archive node ID out of range"));
73 
74  return nodes[id];
75 }
76 
77 
78 ex archive::unarchive_ex(const lst &sym_lst, const char *name) const
79 {
80  // Find root node
81  std::string name_string = name;
82  archive_atom id = atomize(name_string);
83  auto i = exprs.begin(), iend = exprs.end();
84  while (i != iend) {
85  if (i->name == id)
86  goto found;
87  i++;
88  }
89  throw (std::runtime_error("expression with name '" + name_string + "' not found in archive"));
90 
91 found:
92  // Recursively unarchive all nodes, starting at the root node
93  lst sym_lst_copy = sym_lst;
94  return nodes[i->root].unarchive(sym_lst_copy);
95 }
96 
97 ex archive::unarchive_ex(const lst &sym_lst, unsigned index) const
98 {
99  if (index >= exprs.size())
100  throw (std::range_error("index of archived expression out of range"));
101 
102  // Recursively unarchive all nodes, starting at the root node
103  lst sym_lst_copy = sym_lst;
104  return nodes[exprs[index].root].unarchive(sym_lst_copy);
105 }
106 
107 ex archive::unarchive_ex(const lst &sym_lst, std::string &name, unsigned index) const
108 {
109  if (index >= exprs.size())
110  throw (std::range_error("index of archived expression out of range"));
111 
112  // Return expression name
113  name = unatomize(exprs[index].name);
114 
115  // Recursively unarchive all nodes, starting at the root node
116  lst sym_lst_copy = sym_lst;
117  return nodes[exprs[index].root].unarchive(sym_lst_copy);
118 }
119 
120 unsigned archive::num_expressions() const
121 {
122  return exprs.size();
123 }
124 
125 const archive_node &archive::get_top_node(unsigned index) const
126 {
127  if (index >= exprs.size())
128  throw (std::range_error("index of archived expression out of range"));
129 
130  return nodes[exprs[index].root];
131 }
132 
133 
134 /*
135  * Archive file format
136  *
137  * - 4 bytes signature 'GARC'
138  * - unsigned version number
139  * - unsigned number of atoms
140  * - atom strings (each zero-terminated)
141  * - unsigned number of expressions
142  * - unsigned name atom
143  * - unsigned root node ID
144  * - unsigned number of nodes
145  * - unsigned number of properties
146  * - unsigned containing type (PTYPE_*) in its lower 3 bits and
147  * name atom in the upper bits
148  * - unsigned property value
149  *
150  * Unsigned quantities are stored in a compressed format:
151  * - numbers in the range 0x00..0x7f are stored verbatim (1 byte)
152  * - numbers larger than 0x7f are stored in 7-bit packets (1 byte per
153  * packet), starting with the LSBs; all bytes except the last one have
154  * their upper bit set
155  *
156  * Examples:
157  * 0x00 = 0x00
158  * .. ..
159  * 0x7f = 0x7f
160  * 0x80 0x01 = 0x80
161  * .. .. ..
162  * 0xff 0x01 = 0xff
163  * 0x80 0x02 = 0x100
164  * .. .. ..
165  * 0xff 0x02 = 0x17f
166  * 0x80 0x03 = 0x180
167  * .. .. ..
168  * 0xff 0x7f = 0x3fff
169  * 0x80 0x80 0x01 = 0x4000
170  * .. .. .. ..
171  */
172 
174 static void write_unsigned(std::ostream &os, unsigned val)
175 {
176  while (val >= 0x80) {
177  os.put((val & 0x7f) | 0x80);
178  val >>= 7;
179  }
180  os.put(val);
181 }
182 
184 static unsigned read_unsigned(std::istream &is)
185 {
186  unsigned char b;
187  unsigned ret = 0;
188  unsigned shift = 0;
189  do {
190  char b2;
191  is.get(b2);
192  b = b2;
193  ret |= (b & 0x7f) << shift;
194  shift += 7;
195  } while (b & 0x80);
196  return ret;
197 }
198 
200 std::ostream &operator<<(std::ostream &os, const archive_node &n)
201 {
202  // Write properties
203  unsigned num_props = n.props.size();
204  write_unsigned(os, num_props);
205  for (unsigned i=0; i<num_props; i++) {
206  write_unsigned(os, n.props[i].type | (n.props[i].name << 3));
207  write_unsigned(os, n.props[i].value);
208  }
209  return os;
210 }
211 
213 std::ostream &operator<<(std::ostream &os, const archive &ar)
214 {
215  // Write header
216  os.put('G'); // Signature
217  os.put('A');
218  os.put('R');
219  os.put('C');
221 
222  // Write atoms
223  unsigned num_atoms = ar.atoms.size();
224  write_unsigned(os, num_atoms);
225  for (unsigned i=0; i<num_atoms; i++)
226  os << ar.atoms[i] << std::ends;
227 
228  // Write expressions
229  unsigned num_exprs = ar.exprs.size();
230  write_unsigned(os, num_exprs);
231  for (unsigned i=0; i<num_exprs; i++) {
232  write_unsigned(os, ar.exprs[i].name);
233  write_unsigned(os, ar.exprs[i].root);
234  }
235 
236  // Write nodes
237  unsigned num_nodes = ar.nodes.size();
238  write_unsigned(os, num_nodes);
239  for (unsigned i=0; i<num_nodes; i++)
240  os << ar.nodes[i];
241  return os;
242 }
243 
245 std::istream &operator>>(std::istream &is, archive_node &n)
246 {
247  // Read properties
248  unsigned num_props = read_unsigned(is);
249  n.props.resize(num_props);
250  for (unsigned i=0; i<num_props; i++) {
251  unsigned name_type = read_unsigned(is);
252  n.props[i].type = (archive_node::property_type)(name_type & 7);
253  n.props[i].name = name_type >> 3;
254  n.props[i].value = read_unsigned(is);
255  }
256  return is;
257 }
258 
260 std::istream &operator>>(std::istream &is, archive &ar)
261 {
262  // Read header
263  char c1, c2, c3, c4;
264  is.get(c1); is.get(c2); is.get(c3); is.get(c4);
265  if (c1 != 'G' || c2 != 'A' || c3 != 'R' || c4 != 'C')
266  throw (std::runtime_error("not a GiNaC archive (signature not found)"));
267  constexpr unsigned max_version = GINACLIB_ARCHIVE_VERSION;
268  constexpr unsigned min_version = GINACLIB_ARCHIVE_VERSION - GINACLIB_ARCHIVE_AGE;
269  unsigned version = read_unsigned(is);
270  if ((version > max_version) || (version < min_version))
271  throw (std::runtime_error("archive version " + std::to_string(version) + " cannot be read by this GiNaC library (which supports versions " + std::to_string(min_version) + " thru " + std::to_string(max_version)));
272 
273  // Read atoms
274  unsigned num_atoms = read_unsigned(is);
275  ar.atoms.resize(num_atoms);
276  for (unsigned i=0; i<num_atoms; i++) {
277  getline(is, ar.atoms[i], '\0');
278  ar.inverse_atoms[ar.atoms[i]] = i;
279  }
280 
281  // Read expressions
282  unsigned num_exprs = read_unsigned(is);
283  ar.exprs.resize(num_exprs);
284  for (unsigned i=0; i<num_exprs; i++) {
285  archive_atom name = read_unsigned(is);
286  archive_node_id root = read_unsigned(is);
287  ar.exprs[i] = archive::archived_ex(name, root);
288  }
289 
290  // Read nodes
291  unsigned num_nodes = read_unsigned(is);
292  ar.nodes.resize(num_nodes, ar);
293  for (unsigned i=0; i<num_nodes; i++)
294  is >> ar.nodes[i];
295  return is;
296 }
297 
298 
301 archive_atom archive::atomize(const std::string &s) const
302 {
303  // Search for string in inverse_atoms map.
304  inv_at_cit i = inverse_atoms.find(s);
305  if (i!=inverse_atoms.end())
306  return i->second;
307 
308  // Not found, add to atoms vector
309  archive_atom id = atoms.size();
310  atoms.push_back(s);
311  inverse_atoms[s] = id;
312  return id;
313 }
314 
316 const std::string &archive::unatomize(archive_atom id) const
317 {
318  if (id >= atoms.size())
319  throw (std::range_error("archive::unatomize(): atom ID out of range"));
320 
321  return atoms[id];
322 }
323 
324 
327 {
328  if (this != &other) {
329  // archive &a member doesn't get copied
330  props = other.props;
332  e = other.e;
333  }
334  return *this;
335 }
336 
337 
340  : a(ar), has_expression(true), e(expr)
341 {
342  expr.bp->archive(*this);
343 }
344 
345 
350 {
351  if (!has_expression || !other.has_expression)
352  return false;
353  return e.bp == other.e.bp;
354 }
355 
357 archive_node::find_first(const std::string &name) const
358 {
359  archive_atom name_atom = a.atomize(name);
360  for (auto i=props.begin(); i!=props.end(); ++i)
361  if (i->name == name_atom)
362  return i;
363  return props.end();
364 }
365 
367 archive_node::find_last(const std::string &name) const
368 {
369  archive_atom name_atom = a.atomize(name);
370  for (auto i=props.end(); i!=props.begin();) {
371  --i;
372  if (i->name == name_atom)
373  return i;
374  }
375  return props.end();
376 }
377 
379 archive_node::find_property_range(const std::string &name1, const std::string &name2) const
380 {
381  archive_atom name1_atom = a.atomize(name1),
382  name2_atom = a.atomize(name2);
383  archive_node_cit_range range = {props.end(), props.end()};
384  for (auto i=props.begin(); i!=props.end(); ++i) {
385  if (i->name == name1_atom && range.begin == props.end()) {
386  range.begin = i;
387  }
388  if (i->name == name2_atom && range.begin != props.end()) {
389  range.end = i + 1;
390  }
391  }
392  return range;
393 }
394 
395 void archive_node::add_bool(const std::string &name, bool value)
396 {
397  props.emplace_back(property(a.atomize(name), PTYPE_BOOL, value));
398 }
399 
400 void archive_node::add_unsigned(const std::string &name, unsigned value)
401 {
402  props.emplace_back(property(a.atomize(name), PTYPE_UNSIGNED, value));
403 }
404 
405 void archive_node::add_string(const std::string &name, const std::string &value)
406 {
407  props.emplace_back(property(a.atomize(name), PTYPE_STRING, a.atomize(value)));
408 }
409 
410 void archive_node::add_ex(const std::string &name, const ex &value)
411 {
412  // Recursively create an archive_node and add its ID to the properties of this node
414  props.emplace_back(property(a.atomize(name), PTYPE_NODE, id));
415 }
416 
417 
418 bool archive_node::find_bool(const std::string &name, bool &ret, unsigned index) const
419 {
420  archive_atom name_atom = a.atomize(name);
421  auto i = props.begin(), iend = props.end();
422  unsigned found_index = 0;
423  while (i != iend) {
424  if (i->type == PTYPE_BOOL && i->name == name_atom) {
425  if (found_index == index) {
426  ret = i->value;
427  return true;
428  }
429  found_index++;
430  }
431  i++;
432  }
433  return false;
434 }
435 
436 bool archive_node::find_unsigned(const std::string &name, unsigned &ret, unsigned index) const
437 {
438  archive_atom name_atom = a.atomize(name);
439  auto i = props.begin(), iend = props.end();
440  unsigned found_index = 0;
441  while (i != iend) {
442  if (i->type == PTYPE_UNSIGNED && i->name == name_atom) {
443  if (found_index == index) {
444  ret = i->value;
445  return true;
446  }
447  found_index++;
448  }
449  i++;
450  }
451  return false;
452 }
453 
454 bool archive_node::find_string(const std::string &name, std::string &ret, unsigned index) const
455 {
456  archive_atom name_atom = a.atomize(name);
457  auto i = props.begin(), iend = props.end();
458  unsigned found_index = 0;
459  while (i != iend) {
460  if (i->type == PTYPE_STRING && i->name == name_atom) {
461  if (found_index == index) {
462  ret = a.unatomize(i->value);
463  return true;
464  }
465  found_index++;
466  }
467  i++;
468  }
469  return false;
470 }
471 
472 void archive_node::find_ex_by_loc(archive_node_cit loc, ex &ret, lst &sym_lst) const
473 {
474  ret = a.get_node(loc->value).unarchive(sym_lst);
475 }
476 
477 bool archive_node::find_ex(const std::string &name, ex &ret, lst &sym_lst, unsigned index) const
478 {
479  archive_atom name_atom = a.atomize(name);
480  auto i = props.begin(), iend = props.end();
481  unsigned found_index = 0;
482  while (i != iend) {
483  if (i->type == PTYPE_NODE && i->name == name_atom) {
484  if (found_index == index) {
485  ret = a.get_node(i->value).unarchive(sym_lst);
486  return true;
487  }
488  found_index++;
489  }
490  i++;
491  }
492  return false;
493 }
494 
495 const archive_node &archive_node::find_ex_node(const std::string &name, unsigned index) const
496 {
497  archive_atom name_atom = a.atomize(name);
498  auto i = props.begin(), iend = props.end();
499  unsigned found_index = 0;
500  while (i != iend) {
501  if (i->type == PTYPE_NODE && i->name == name_atom) {
502  if (found_index == index)
503  return a.get_node(i->value);
504  found_index++;
505  }
506  i++;
507  }
508  throw (std::runtime_error("property with name '" + name + "' not found in archive node"));
509 }
510 
511 
513 {
514  v.clear();
515  auto i = props.begin(), iend = props.end();
516  while (i != iend) {
517  property_type type = i->type;
518  std::string name = a.unatomize(i->name);
519 
520  auto a = v.begin(), aend = v.end();
521  bool found = false;
522  while (a != aend) {
523  if (a->type == type && a->name == name) {
524  a->count++;
525  found = true;
526  break;
527  }
528  ++a;
529  }
530  if (!found)
531  v.emplace_back(property_info(type, name));
532  i++;
533  }
534 }
535 
536 static synthesize_func find_factory_fcn(const std::string& name)
537 {
538  static unarchive_table_t the_table;
539  synthesize_func ret = the_table.find(name);
540  return ret;
541 }
542 
545 {
546  // Already unarchived? Then return cached unarchived expression.
547  if (has_expression)
548  return e;
549 
550  // Find instantiation function for class specified in node
551  std::string class_name;
552  if (!find_string("class", class_name))
553  throw (std::runtime_error("archive node contains no class name"));
554 
555  // Call instantiation function
556  synthesize_func factory_fcn = find_factory_fcn(class_name);
557  ptr<basic> obj(factory_fcn());
558  obj->setflag(status_flags::dynallocated);
559  obj->read_archive(*this, sym_lst);
560  e = ex(*obj);
561  has_expression = true;
562  return e;
563 }
564 
567 
569 {
570  if (usecount == 0)
571  unarch_map = new unarchive_map_t();
572  ++usecount;
573 }
574 
575 synthesize_func unarchive_table_t::find(const std::string& classname) const
576 {
577  unarchive_map_t::const_iterator i = unarch_map->find(classname);
578  if (i != unarch_map->end())
579  return i->second;
580  throw std::runtime_error(std::string("no unarchiving function for \"")
581  + classname + "\" class");
582 }
583 
584 void unarchive_table_t::insert(const std::string& classname, synthesize_func f)
585 {
586  if (unarch_map->find(classname) != unarch_map->end())
587  throw std::runtime_error(std::string("Class \"" + classname
588  + "\" is already registered"));
589  unarch_map->operator[](classname) = f;
590 }
591 
593 {
594  if (--usecount == 0)
595  delete unarch_map;
596 }
597 
598 
600 {
601  atoms.clear();
602  inverse_atoms.clear();
603  exprs.clear();
604  nodes.clear();
605  exprtable.clear();
606 }
607 
608 
611 {
612  for_each(nodes.begin(), nodes.end(), std::mem_fun_ref(&archive_node::forget));
613 }
614 
617 {
618  has_expression = false;
619  e = 0;
620 }
621 
622 
624 void archive::printraw(std::ostream &os) const
625 {
626  // Dump atoms
627  os << "Atoms:\n";
628  {
629  std::vector<std::string>::const_iterator i = atoms.begin(), iend = atoms.end();
630  archive_atom id = 0;
631  while (i != iend) {
632  os << " " << id << " " << *i << std::endl;
633  i++; id++;
634  }
635  }
636  os << std::endl;
637 
638  // Dump expressions
639  os << "Expressions:\n";
640  {
641  auto i = exprs.begin(), iend = exprs.end();
642  unsigned index = 0;
643  while (i != iend) {
644  os << " " << index << " \"" << unatomize(i->name) << "\" root node " << i->root << std::endl;
645  i++; index++;
646  }
647  }
648  os << std::endl;
649 
650  // Dump nodes
651  os << "Nodes:\n";
652  {
653  auto i = nodes.begin(), iend = nodes.end();
654  archive_node_id id = 0;
655  while (i != iend) {
656  os << " " << id << " ";
657  i->printraw(os);
658  i++; id++;
659  }
660  }
661 }
662 
664 void archive_node::printraw(std::ostream &os) const
665 {
666  // Dump cached unarchived expression
667  if (has_expression)
668  os << "(basic * " << e.bp << " = " << e << ")\n";
669  else
670  os << "\n";
671 
672  // Dump properties
673  auto i = props.begin(), iend = props.end();
674  while (i != iend) {
675  os << " ";
676  switch (i->type) {
677  case PTYPE_BOOL: os << "bool"; break;
678  case PTYPE_UNSIGNED: os << "unsigned"; break;
679  case PTYPE_STRING: os << "string"; break;
680  case PTYPE_NODE: os << "node"; break;
681  default: os << "<unknown>"; break;
682  }
683  os << " \"" << a.unatomize(i->name) << "\" " << i->value << std::endl;
684  i++;
685  }
686 }
687 
688 
689 } // namespace GiNaC
unsigned num_expressions() const
Return number of archived expressions.
Definition: archive.cpp:120
std::vector< property > props
Vector of stored properties.
Definition: archive.h:157
Archived expression descriptor.
Definition: archive.h:312
static void write_unsigned(std::ostream &os, unsigned val)
Write unsigned integer quantity to stream.
Definition: archive.cpp:174
bool has_expression
Flag indicating whether a cached unarchived representation of this node exists.
Definition: archive.h:160
archive_node_cit find_last(const std::string &name) const
Definition: archive.cpp:367
ex unarchive_ex(const lst &sym_lst, const char *name) const
Retrieve expression from archive by name.
Definition: archive.cpp:78
void get_properties(propinfovector &v) const
Return vector of properties stored in node.
Definition: archive.cpp:512
void insert(const std::string &classname, synthesize_func f)
Definition: archive.cpp:584
std::vector< property >::const_iterator archive_node_cit
Definition: archive.h:84
static synthesize_func find_factory_fcn(const std::string &name)
Definition: archive.cpp:536
Definition: add.cpp:38
std::ostream & operator<<(std::ostream &os, const archive_node &n)
Write archive_node to binary data stream.
Definition: archive.cpp:200
const archive_node & operator=(const archive_node &other)
Assignment operator of archive_node.
Definition: archive.cpp:326
Archiving of GiNaC expressions.
std::map< std::string, archive_atom > inverse_atoms
Definition: archive.h:334
#define GINACLIB_ARCHIVE_AGE
Definition: version.h:78
void add_bool(const std::string &name, bool value)
Add property of type "bool" to node.
Definition: archive.cpp:395
std::map< ex, archive_node_id, ex_is_less > exprtable
Map of stored expressions to nodes for faster archiving.
Definition: archive.h:337
property_type
Property data types.
Definition: archive.h:55
archive_node_id add_node(const archive_node &n)
Add archive_node to archive if the corresponding expression is not already archived.
Definition: archive.cpp:50
std::vector< archive_node > nodes
Vector of archived nodes.
Definition: archive.h:309
static const bool value
Definition: factor.cpp:231
void find_ex_by_loc(archive_node_cit loc, ex &ret, lst &sym_lst) const
Retrieve property of type "ex" from the node if it is known that this node in fact contains such a pr...
Definition: archive.cpp:472
archive_node & get_node(archive_node_id id)
Retrieve archive_node by ID.
Definition: archive.cpp:69
bool find_string(const std::string &name, std::string &ret, unsigned index=0) const
Retrieve property of type "string" from node.
Definition: archive.cpp:454
std::map< std::string, archive_atom >::const_iterator inv_at_cit
The map of from strings to indices of the atoms vectors allows for faster archiving.
Definition: archive.h:333
GiNaC&#39;s class registrar (for class basic and all classes derived from it).
void archive_ex(const ex &e, const char *name)
Archive an expression.
Definition: archive.cpp:35
basic *(* synthesize_func)()
Definition: archive.h:166
static unarchive_map_t * unarch_map
Definition: archive.h:172
bool find_unsigned(const std::string &name, unsigned &ret, unsigned index=0) const
Retrieve property of type "unsigned" from node.
Definition: archive.cpp:436
void forget()
Delete cached unarchived expressions in all archive_nodes (mainly for debugging). ...
Definition: archive.cpp:610
archive_node_cit find_first(const std::string &name) const
Find the location in the vector of properties of the first/last property with a given name...
Definition: archive.cpp:357
archive_node(archive &ar)
Definition: archive.h:89
std::istream & operator>>(std::istream &is, archive_node &n)
Read archive_node from binary data stream.
Definition: archive.cpp:245
bool find_bool(const std::string &name, bool &ret, unsigned index=0) const
Retrieve property of type "bool" from node.
Definition: archive.cpp:418
void clear()
Clear all archived expressions.
Definition: archive.cpp:599
synthesize_func find(const std::string &classname) const
Definition: archive.cpp:575
const archive_node & get_top_node(unsigned index=0) const
Return reference to top node of an expression specified by index.
Definition: archive.cpp:125
archive_node_cit_range find_property_range(const std::string &name1, const std::string &name2) const
Find a range of locations in the vector of properties.
Definition: archive.cpp:379
void forget()
Delete cached unarchived expressions from node (for debugging).
Definition: archive.cpp:616
Archived property (data type, name and associated data)
Definition: archive.h:76
void add_string(const std::string &name, const std::string &value)
Add property of type "string" to node.
Definition: archive.cpp:405
size_t n
Definition: factor.cpp:1463
bool has_same_ex_as(const archive_node &other) const
Check if the archive_node stores the same expression as another archive_node.
Definition: archive.cpp:349
Interface to GiNaC&#39;s light-weight expression handles.
void add_ex(const std::string &name, const ex &value)
Add property of type "ex" to node.
Definition: archive.cpp:410
GiNaC library version information.
Definition of GiNaC&#39;s lst.
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
Definition: archive.h:48
Lightweight wrapper for GiNaC&#39;s symbolic objects.
Definition: ex.h:72
std::vector< std::string > atoms
Vector of atomized strings (using a vector allows faster unarchiving).
Definition: archive.h:329
std::map< std::string, synthesize_func > unarchive_map_t
Definition: archive.h:167
static unsigned read_unsigned(std::istream &is)
Read unsigned integer quantity from stream.
Definition: archive.cpp:184
Wrapper template for making GiNaC classes out of STL containers.
Definition: container.h:73
bool find_ex(const std::string &name, ex &ret, lst &sym_lst, unsigned index=0) const
Retrieve property of type "ex" from node.
Definition: archive.cpp:477
unsigned archive_node_id
Numerical ID value to refer to an archive_node.
Definition: archive.h:35
unsigned archive_atom
Numerical ID value to refer to a string.
Definition: archive.h:42
void printraw(std::ostream &os) const
Print archive to stream in ugly raw format (for debugging).
Definition: archive.cpp:624
const std::string & unatomize(archive_atom id) const
Unatomize a string (i.e.
Definition: archive.cpp:316
ex unarchive(lst &sym_lst) const
Convert archive node to GiNaC expression.
Definition: archive.cpp:544
ptr< basic > bp
pointer to basic object managed by this
Definition: ex.h:251
const archive_node & find_ex_node(const std::string &name, unsigned index=0) const
Retrieve property of type "ex" from node, returning the node of the sub-expression.
Definition: archive.cpp:495
heap-allocated (i.e. created by new if we want to be clever and bypass the stack, ...
Definition: flags.h:202
archive & a
Reference to the archive to which this node belongs.
Definition: archive.h:154
Information about a stored property.
Definition: archive.h:65
#define GINACLIB_ARCHIVE_VERSION
Definition: version.h:77
This class holds archived versions of GiNaC expressions (class ex).
Definition: archive.h:254
archive_atom atomize(const std::string &s) const
Atomize a string (i.e.
Definition: archive.cpp:301
std::vector< archived_ex > exprs
Vector of archived expression descriptors.
Definition: archive.h:321
void printraw(std::ostream &os) const
Output archive_node to stream in ugly raw format (for debugging).
Definition: archive.cpp:664
ex e
The cached unarchived representation of this node (if any).
Definition: archive.h:163
Class of (intrusively) reference-counted pointers that support copy-on-write semantics.
Definition: ptr.h:56
void add_unsigned(const std::string &name, unsigned value)
Add property of type "unsigned int" to node.
Definition: archive.cpp:400
std::vector< property_info > propinfovector
Definition: archive.h:73

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