From: Christian Bauer Date: Sun, 24 Aug 2003 22:55:54 +0000 (+0000) Subject: - implemented object fusion as proposed by Richy X-Git-Tag: release_1-2-0~125 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=c69b9bb178e6445aae2cc19b2f188875a16e476b - implemented object fusion as proposed by Richy - unit(), content() and primpart() take a "const ex &" instead of a "const symbol &". degree(), coeff(), collect() etc. have dropped the restriction to symbols a long time ago, so there's no reason for these function to keep it. --- diff --git a/ginac/ex.cpp b/ginac/ex.cpp index e3e54c13..1af7f214 100644 --- a/ginac/ex.cpp +++ b/ginac/ex.cpp @@ -242,6 +242,19 @@ void ex::makewriteable() GINAC_ASSERT(bp->refcount == 1); } +/** Share equal objects between expressions. + * @see ex::compare(const basic &) */ +void ex::share(const ex & other) const +{ + if ((bp->flags & status_flags::not_shareable) || (other.bp->flags & status_flags::not_shareable)) + return; + + if (bp->refcount <= other.bp->refcount) + bp = other.bp; + else + other.bp = bp; +} + /** Helper function for the ex-from-basic constructor. This is where GiNaC's * automatic evaluator and memory management are implemented. * @see ex::ex(const basic &) */ diff --git a/ginac/ex.h b/ginac/ex.h index 38dcf732..ee891a2f 100644 --- a/ginac/ex.h +++ b/ginac/ex.h @@ -304,11 +304,11 @@ public: ex numer_denom() const; // polynomial algorithms - ex unit(const symbol &x) const; - ex content(const symbol &x) const; + ex unit(const ex &x) const; + ex content(const ex &x) const; numeric integer_content() const; - ex primpart(const symbol &x) const; - ex primpart(const symbol &x, const ex &cont) const; + ex primpart(const ex &x) const; + ex primpart(const ex &x, const ex &cont) const; ex smod(const numeric &xi) const { return bp->smod(xi); } numeric max_coefficient() const; @@ -345,6 +345,7 @@ private: static basic & construct_from_double(double d); static ptr construct_from_string_and_lst(const std::string &s, const ex &l); void makewriteable(); + void share(const ex & other) const; #ifdef OBSCURE_CINT_HACK public: @@ -368,7 +369,7 @@ protected: // member variables private: - ptr bp; ///< pointer to basic object managed by this + mutable ptr bp; ///< pointer to basic object managed by this #ifdef OBSCURE_CINT_HACK public: @@ -481,7 +482,14 @@ int ex::compare(const ex & other) const { if (bp == other.bp) // trivial case: both expressions point to same basic return 0; - return bp->compare(*other.bp); + const int cmpval = bp->compare(*other.bp); + if (cmpval == 0) { + // Expressions point to different, but equal, trees: conserve + // memory and make subsequent compare() operations faster by + // making both expression point to the same tree. + share(other); + } + return cmpval; } inline