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

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