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 &) */
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;
static basic & construct_from_double(double d);
static ptr<basic> 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:
// member variables
private:
- ptr<basic> bp; ///< pointer to basic object managed by this
+ mutable ptr<basic> bp; ///< pointer to basic object managed by this
#ifdef OBSCURE_CINT_HACK
public:
{
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