It turned out that ex::operator[] const dispatched to non-const
basic::operator[] because
* member variable ex::bp is non-const and
* ptr<T>::operator*() returns a non-const T &.
As a result, indexing failed for multiply referenced objects.
Thanks to Vitaly Magerya <vmagerya@gmail.com> for reporting this.
return result;
}
+// Bug in collect()
+// cf. https://www.ginac.de/pipermail/ginac-list/2021-March/002337.html
+static unsigned exam_collect_multiply_referenced_lst()
+{
+ unsigned result = 0;
+ symbol x("x"), y("y");
+ ex a = x + y;
+ ex l = lst{x, y};
+ ex l2 = l; // make l a multiply referenced object
+
+ try {
+ ex b = collect(a, l);
+ } catch (const std::runtime_error & e) {
+ clog << "collect(" << ", " << l << ") threw a runtime_error("
+ << e.what() << ")" << endl;
+ ++result;
+ }
+
+ return result;
+}
+
unsigned exam_paranoia()
{
unsigned result = 0;
result += exam_paranoia24(); cout << '.' << flush;
result += exam_paranoia25(); cout << '.' << flush;
result += exam_paranoia26(); cout << '.' << flush;
+ result += exam_collect_multiply_referenced_lst(); cout << '.' << flush;
return result;
}
// operand access
size_t nops() const { return bp->nops(); }
ex op(size_t i) const { return bp->op(i); }
- ex operator[](const ex & index) const { return (*bp)[index]; }
- ex operator[](size_t i) const { return (*bp)[i]; }
+ ex operator[](const ex & index) const { return (const_cast<const basic&>(*bp))[index]; }
+ ex operator[](size_t i) const { return (const_cast<const basic&>(*bp))[i]; }
ex & let_op(size_t i);
ex & operator[](const ex & index);
ex & operator[](size_t i);