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

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