GiNaC 1.8.7
archive.cpp
Go to the documentation of this file.
1
5/*
6 * GiNaC Copyright (C) 1999-2023 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
32namespace GiNaC {
33
34
35void 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
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
78ex 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
91found:
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
97ex 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
107ex 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
121{
122 return exprs.size();
123}
124
125const 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
174static 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
184static 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
200std::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
213std::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
245std::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
260std::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);
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
301archive_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
316const 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
357archive_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
367archive_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
379archive_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
395void archive_node::add_bool(const std::string &name, bool value)
396{
397 props.emplace_back(property(a.atomize(name), PTYPE_BOOL, value));
398}
399
400void archive_node::add_unsigned(const std::string &name, unsigned value)
401{
402 props.emplace_back(property(a.atomize(name), PTYPE_UNSIGNED, value));
403}
404
405void 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
410void 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
418bool 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
436bool 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
454bool 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
473{
474 ret = a.get_node(loc->value).unarchive(sym_lst);
475}
476
477bool 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
495const 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
536static 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)
572 ++usecount;
573}
574
575synthesize_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
584void 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_fn(&archive_node::forget));
613}
614
617{
618 has_expression = false;
619 e = 0;
620}
621
622
624void 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
664void 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
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:664
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:512
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:436
void add_unsigned(const std::string &name, unsigned value)
Add property of type "unsigned int" to node.
Definition: archive.cpp:400
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
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
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
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 forget()
Delete cached unarchived expressions from node (for debugging).
Definition: archive.cpp:616
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:495
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:454
void add_ex(const std::string &name, const ex &value)
Add property of type "ex" to node.
Definition: archive.cpp:410
void add_bool(const std::string &name, bool value)
Add property of type "bool" to node.
Definition: archive.cpp:395
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
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:367
const archive_node & operator=(const archive_node &other)
Assignment operator of archive_node.
Definition: archive.cpp:326
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 & 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:544
void add_string(const std::string &name, const std::string &value)
Add property of type "string" to node.
Definition: archive.cpp:405
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:50
archive_atom atomize(const std::string &s) const
Atomize a string (i.e.
Definition: archive.cpp:301
void forget()
Delete cached unarchived expressions in all archive_nodes (mainly for debugging).
Definition: archive.cpp:610
ex unarchive_ex(const lst &sym_lst, const char *name) const
Retrieve expression from archive by name.
Definition: archive.cpp:78
void clear()
Clear all archived expressions.
Definition: archive.cpp:599
void archive_ex(const ex &e, const char *name)
Archive an expression.
Definition: archive.cpp:35
unsigned num_expressions() const
Return number of archived expressions.
Definition: archive.cpp:120
const std::string & unatomize(archive_atom id) const
Unatomize a string (i.e.
Definition: archive.cpp:316
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:125
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:69
void printraw(std::ostream &os) const
Print archive to stream in ugly raw format (for debugging).
Definition: archive.cpp:624
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:72
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: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:584
synthesize_func find(const std::string &classname) const
Definition: archive.cpp:575
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:38
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:200
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:174
static unsigned read_unsigned(std::istream &is)
Read unsigned integer quantity from stream.
Definition: archive.cpp:184
std::istream & operator>>(std::istream &is, archive_node &n)
Read archive_node from binary data stream.
Definition: archive.cpp:245
static synthesize_func find_factory_fcn(const std::string &name)
Definition: archive.cpp:536
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.