From f10b253437b350a2c5897bd7e65a27914a32f068 Mon Sep 17 00:00:00 2001 From: Christian Bauer Date: Thu, 10 Jun 2004 02:18:34 +0000 Subject: [PATCH] ncmul::expand() doesn't allocate a new object unless necessary --- ginac/ncmul.cpp | 47 +++++++++++++++++++++++++++++++++++------------ ginac/ncmul.h | 2 +- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/ginac/ncmul.cpp b/ginac/ncmul.cpp index 005cc16f..3bc8b214 100644 --- a/ginac/ncmul.cpp +++ b/ginac/ncmul.cpp @@ -127,7 +127,8 @@ typedef std::vector intvector; ex ncmul::expand(unsigned options) const { // First, expand the children - exvector expanded_seq = expandchildren(options); + std::auto_ptr vp = expandchildren(options); + const exvector &expanded_seq = vp.get() ? *vp : this->seq; // Now, look for all the factors that are sums and remember their // position and number of terms. @@ -151,9 +152,13 @@ ex ncmul::expand(unsigned options) const } // If there are no sums, we are done - if (number_of_adds == 0) - return (new ncmul(expanded_seq, true))-> - setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)); + if (number_of_adds == 0) { + if (vp.get()) + return (new ncmul(vp))-> + setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)); + else + return *this; + } // Now, form all possible products of the terms of the sums with the // remaining factors, and add them together @@ -561,16 +566,34 @@ unsigned ncmul::return_type_tinfo() const // non-virtual functions in this class ////////// -exvector ncmul::expandchildren(unsigned options) const +std::auto_ptr ncmul::expandchildren(unsigned options) const { - exvector s; - s.reserve(seq.size()); - exvector::const_iterator it = seq.begin(), itend = seq.end(); - while (it != itend) { - s.push_back(it->expand(options)); - it++; + const_iterator cit = this->seq.begin(), end = this->seq.end(); + while (cit != end) { + const ex & expanded_ex = cit->expand(options); + if (!are_ex_trivially_equal(*cit, expanded_ex)) { + + // copy first part of seq which hasn't changed + std::auto_ptr s(new exvector(this->seq.begin(), cit)); + reserve(*s, this->seq.size()); + + // insert changed element + s->push_back(expanded_ex); + ++cit; + + // copy rest + while (cit != end) { + s->push_back(cit->expand(options)); + ++cit; + } + + return s; + } + + ++cit; } - return s; + + return std::auto_ptr(0); // nothing has changed } const exvector & ncmul::get_factors() const diff --git a/ginac/ncmul.h b/ginac/ncmul.h index 46a7aae1..436ae8c0 100644 --- a/ginac/ncmul.h +++ b/ginac/ncmul.h @@ -80,7 +80,7 @@ protected: void do_print_csrc(const print_context & c, unsigned level) const; size_t count_factors(const ex & e) const; void append_factors(exvector & v, const ex & e) const; - exvector expandchildren(unsigned options) const; + std::auto_ptr expandchildren(unsigned options) const; public: const exvector & get_factors() const; }; -- 2.49.0