The bug was reported by Vladimir V. Kisil <kisilv@maths.leeds.ac.uk>, see
<https://www.ginac.de/pipermail/ginac-devel/2019-September/002399.html>.
}
archive_node::archive_node_cit
}
archive_node::archive_node_cit
- archive_node::find_first(const std::string &name) const
-{
+archive_node::find_first(const std::string &name) const
+{
archive_atom name_atom = a.atomize(name);
for (auto i=props.begin(); i!=props.end(); ++i)
if (i->name == name_atom)
return i;
archive_atom name_atom = a.atomize(name);
for (auto i=props.begin(); i!=props.end(); ++i)
if (i->name == name_atom)
return i;
}
archive_node::archive_node_cit
}
archive_node::archive_node_cit
- archive_node::find_last(const std::string &name) const
+archive_node::find_last(const std::string &name) const
{
archive_atom name_atom = a.atomize(name);
for (auto i=props.end(); i!=props.begin();) {
{
archive_atom name_atom = a.atomize(name);
for (auto i=props.end(); i!=props.begin();) {
+archive_node::archive_node_cit_range
+archive_node::find_property_range(const std::string &name1, const std::string &name2) const
+{
+ archive_atom name1_atom = a.atomize(name1),
+ name2_atom = a.atomize(name2);
+ archive_node_cit_range range = {props.end(), props.end()};
+ for (auto i=props.begin(); i!=props.end(); ++i) {
+ if (i->name == name1_atom && range.begin == props.end()) {
+ range.begin = i;
+ }
+ if (i->name == name2_atom && range.begin != props.end()) {
+ range.end = i + 1;
+ }
+ }
+ return range;
+}
+
void archive_node::add_bool(const std::string &name, bool value)
{
props.push_back(property(a.atomize(name), PTYPE_BOOL, value));
void archive_node::add_bool(const std::string &name, bool value)
{
props.push_back(property(a.atomize(name), PTYPE_BOOL, value));
-void archive_node::find_ex_by_loc(archive_node_cit loc, ex &ret, lst &sym_lst)
- const
+void archive_node::find_ex_by_loc(archive_node_cit loc, ex &ret, lst &sym_lst) const
{
ret = a.get_node(loc->value).unarchive(sym_lst);
}
{
ret = a.get_node(loc->value).unarchive(sym_lst);
}
if (!found)
v.push_back(property_info(type, name));
i++;
if (!found)
v.push_back(property_info(type, name));
i++;
}
static synthesize_func find_factory_fcn(const std::string& name)
}
static synthesize_func find_factory_fcn(const std::string& name)
unsigned value; /**< Stored value. */
};
typedef std::vector<property>::const_iterator archive_node_cit;
unsigned value; /**< Stored value. */
};
typedef std::vector<property>::const_iterator archive_node_cit;
+ struct archive_node_cit_range {
+ archive_node_cit begin, end;
+ };
archive_node(archive &ar) : a(ar), has_expression(false) {}
archive_node(archive &ar, const ex &expr);
archive_node(archive &ar) : a(ar), has_expression(false) {}
archive_node(archive &ar, const ex &expr);
bool find_string(const std::string &name, std::string &ret, unsigned index = 0) const;
/** Find the location in the vector of properties of the first/last
bool find_string(const std::string &name, std::string &ret, unsigned index = 0) const;
/** Find the location in the vector of properties of the first/last
- * property with a given name. */
+ * property with a given name. */
archive_node_cit find_first(const std::string &name) const;
archive_node_cit find_last(const std::string &name) const;
archive_node_cit find_first(const std::string &name) const;
archive_node_cit find_last(const std::string &name) const;
+ /** Find a range of locations in the vector of properties. The result
+ * begins at the first property with name1 and ends one past the last
+ * property with name2. */
+ archive_node_cit_range find_property_range(const std::string &name1, const std::string &name2) const;
+
/** Retrieve property of type "ex" from node.
* @return "true" if property was found, "false" otherwise */
bool find_ex(const std::string &name, ex &ret, lst &sym_lst, unsigned index = 0) const;
/** Retrieve property of type "ex" from the node if it is known
/** Retrieve property of type "ex" from node.
* @return "true" if property was found, "false" otherwise */
bool find_ex(const std::string &name, ex &ret, lst &sym_lst, unsigned index = 0) const;
/** Retrieve property of type "ex" from the node if it is known
- * that this node in fact contains such a property at the given
- * location. This is much more efficient than the preceding function. */
+ * that this node in fact contains such a property at the given
+ * location. This is much more efficient than the preceding function. */
void find_ex_by_loc(archive_node_cit loc, ex &ret, lst &sym_lst) const;
/** Retrieve property of type "ex" from node, returning the node of
void find_ex_by_loc(archive_node_cit loc, ex &ret, lst &sym_lst) const;
/** Retrieve property of type "ex" from node, returning the node of
/** Retrieve expression from archive by index.
* @param sym_lst list of pre-defined symbols
* @param index index of expression
/** Retrieve expression from archive by index.
* @param sym_lst list of pre-defined symbols
* @param index index of expression
- * @see count_expressions */
+ * @see count_expressions */
ex unarchive_ex(const lst &sym_lst, unsigned index = 0) const;
/** Retrieve expression and its name from archive by index.
* @param sym_lst list of pre-defined symbols
* @param name receives the name of the expression
* @param index index of expression
ex unarchive_ex(const lst &sym_lst, unsigned index = 0) const;
/** Retrieve expression and its name from archive by index.
* @param sym_lst list of pre-defined symbols
* @param name receives the name of the expression
* @param index index of expression
- * @see count_expressions */
+ * @see count_expressions */
ex unarchive_ex(const lst &sym_lst, std::string &name, unsigned index = 0) const;
/** Return number of archived expressions. */
ex unarchive_ex(const lst &sym_lst, std::string &name, unsigned index = 0) const;
/** Return number of archived expressions. */
inherited::read_archive(n, sym_lst);
setflag(get_default_flags());
inherited::read_archive(n, sym_lst);
setflag(get_default_flags());
- archive_node::archive_node_cit first = n.find_first("seq");
- archive_node::archive_node_cit last = n.find_last("seq");
- ++last;
- this->reserve(this->seq, last - first);
- for (archive_node::archive_node_cit i=first; i<last; ++i) {
+ auto range = n.find_property_range("seq", "seq");
+ this->reserve(this->seq, range.end - range.begin);
+ for (archive_node::archive_node_cit i=range.begin; i<range.end; ++i) {
ex e;
n.find_ex_by_loc(i, e, sym_lst);
ex e;
n.find_ex_by_loc(i, e, sym_lst);
- this->seq.push_back(e);
+ this->seq.emplace_back(e);
void expairseq::read_archive(const archive_node &n, lst &sym_lst)
{
inherited::read_archive(n, sym_lst);
void expairseq::read_archive(const archive_node &n, lst &sym_lst)
{
inherited::read_archive(n, sym_lst);
- auto first = n.find_first("rest");
- auto last = n.find_last("coeff");
- ++last;
- seq.reserve((last-first)/2);
+ auto range = n.find_property_range("rest", "coeff");
+ seq.reserve((range.end-range.begin)/2);
- for (auto loc = first; loc < last;) {
+ for (auto loc = range.begin; loc < range.end;) {
ex rest;
ex coeff;
n.find_ex_by_loc(loc++, rest, sym_lst);
n.find_ex_by_loc(loc++, coeff, sym_lst);
ex rest;
ex coeff;
n.find_ex_by_loc(loc++, rest, sym_lst);
n.find_ex_by_loc(loc++, coeff, sym_lst);
- seq.push_back(expair(rest, coeff));
+ seq.emplace_back(expair(rest, coeff));
}
n.find_ex("overall_coeff", overall_coeff, sym_lst);
}
n.find_ex("overall_coeff", overall_coeff, sym_lst);
m.reserve(row * col);
// XXX: default ctor inserts a zero element, we need to erase it here.
m.pop_back();
m.reserve(row * col);
// XXX: default ctor inserts a zero element, we need to erase it here.
m.pop_back();
- auto first = n.find_first("m");
- auto last = n.find_last("m");
- ++last;
- for (auto i=first; i != last; ++i) {
+ auto range = n.find_property_range("m", "m");
+ for (auto i=range.begin; i != range.end; ++i) {
ex e;
n.find_ex_by_loc(i, e, sym_lst);
ex e;
n.find_ex_by_loc(i, e, sym_lst);
}
}
GINAC_BIND_UNARCHIVER(matrix);
}
}
GINAC_BIND_UNARCHIVER(matrix);
void pseries::read_archive(const archive_node &n, lst &sym_lst)
{
inherited::read_archive(n, sym_lst);
void pseries::read_archive(const archive_node &n, lst &sym_lst)
{
inherited::read_archive(n, sym_lst);
- auto first = n.find_first("coeff");
- auto last = n.find_last("power");
- ++last;
- seq.reserve((last-first)/2);
+ auto range = n.find_property_range("coeff", "power");
+ seq.reserve((range.end-range.begin)/2);
- for (auto loc = first; loc < last;) {
+ for (auto loc = range.begin; loc < range.end;) {
ex rest;
ex coeff;
n.find_ex_by_loc(loc++, rest, sym_lst);
n.find_ex_by_loc(loc++, coeff, sym_lst);
ex rest;
ex coeff;
n.find_ex_by_loc(loc++, rest, sym_lst);
n.find_ex_by_loc(loc++, coeff, sym_lst);
- seq.push_back(expair(rest, coeff));
+ seq.emplace_back(expair(rest, coeff));
}
n.find_ex("var", var, sym_lst);
}
n.find_ex("var", var, sym_lst);