From 454b1d9b6baeab44188a5bee5725a9816afe7a5f Mon Sep 17 00:00:00 2001 From: Christian Bauer Date: Thu, 20 Feb 2003 17:50:43 +0000 Subject: [PATCH] let_op() is no longer the default implementation of op(). Rationale: let_op() needs to clear status_flags::hash_calculated, otherwise we could end up with equal objects that have different hash values. But clearing hash_calculated on a read-only op() access would be inefficient. let_op() is now only implemented by lst and matrix. --- ginac/basic.cpp | 3 ++- ginac/container.pl | 23 +++++++++++++++++++++-- ginac/expairseq.cpp | 5 ----- ginac/expairseq.h | 1 - ginac/exprseq_suppl.cpp | 4 ++-- ginac/idx.cpp | 11 ++++++++++- ginac/idx.h | 3 ++- ginac/matrix.cpp | 10 ++++++++++ ginac/matrix.h | 1 + ginac/pseries.cpp | 6 +----- ginac/pseries.h | 1 - 11 files changed, 49 insertions(+), 19 deletions(-) diff --git a/ginac/basic.cpp b/ginac/basic.cpp index 9fd73982..70237930 100644 --- a/ginac/basic.cpp +++ b/ginac/basic.cpp @@ -179,12 +179,13 @@ unsigned basic::nops() const /** Return operand/member at position i. */ ex basic::op(int i) const { - return (const_cast(this))->let_op(i); + throw(std::runtime_error(std::string("op() not implemented by ") + class_name())); } /** Return modifyable operand/member at position i. */ ex & basic::let_op(int i) { + ensure_if_modifiable(); throw(std::runtime_error(std::string("let_op() not implemented by ") + class_name())); } diff --git a/ginac/container.pl b/ginac/container.pl index c30342d9..84c0a49d 100755 --- a/ginac/container.pl +++ b/ginac/container.pl @@ -106,12 +106,29 @@ END_OF_SORT_IMPLEMENTATION } if ($let_op) { - $LET_OP_IMPLEMENTATION=<=0); + GINAC_ASSERT(i=0); GINAC_ASSERT(i=0); GINAC_ASSERT(i(duplicate()); + copy->setflag(status_flags::dynallocated); + copy->clearflag(status_flags::hash_calculated); + copy->value = f(value); + return *copy; +} + /** Returns order relation between two indices of the same type. The order * must be such that dummy indices lie next to each other. */ int idx::compare_same_type(const basic & other) const diff --git a/ginac/idx.h b/ginac/idx.h index fe7b5194..7fc743b5 100644 --- a/ginac/idx.h +++ b/ginac/idx.h @@ -51,7 +51,8 @@ public: void print(const print_context & c, unsigned level = 0) const; bool info(unsigned inf) const; unsigned nops() const; - ex & let_op(int i); + ex op(int i) const; + ex map(map_function & f) const; ex evalf(int level = 0) const; ex subs(const lst & ls, const lst & lr, unsigned options = 0) const; diff --git a/ginac/matrix.cpp b/ginac/matrix.cpp index 57cd8894..67d99c97 100644 --- a/ginac/matrix.cpp +++ b/ginac/matrix.cpp @@ -199,11 +199,21 @@ unsigned matrix::nops() const } /** returns matrix entry at position (i/col, i%col). */ +ex matrix::op(int i) const +{ + GINAC_ASSERT(i>=0); + GINAC_ASSERT(i=0); GINAC_ASSERT(i= seq.size()) throw (std::out_of_range("op() out of range")); - return seq[i].rest * power(var - point, seq[i].coeff); -} -ex & pseries::let_op(int i) -{ - throw (std::logic_error("let_op() not defined for pseries")); + return seq[i].rest * power(var - point, seq[i].coeff); } /** Return degree of highest power of the series. This is usually the exponent diff --git a/ginac/pseries.h b/ginac/pseries.h index 37ac5796..17ae934a 100644 --- a/ginac/pseries.h +++ b/ginac/pseries.h @@ -46,7 +46,6 @@ public: unsigned precedence(void) const {return 38;} // for clarity just below add::precedence unsigned nops(void) const; ex op(int i) const; - ex & let_op(int i); int degree(const ex &s) const; int ldegree(const ex &s) const; ex coeff(const ex &s, int n = 1) const; -- 2.50.0