X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fadd.cpp;h=79994e11c5ddf47e54b84daf883b014b1f1410a4;hp=fd83de1134876f448835f9e48722f990c04402a5;hb=6eb7dee7ea9e83d3e0599aec9ab7c6084a47b71c;hpb=2bf56ec52a7bed4ac3d02be8887b0287b5acd189;ds=sidebyside diff --git a/ginac/add.cpp b/ginac/add.cpp index fd83de11..79994e11 100644 --- a/ginac/add.cpp +++ b/ginac/add.cpp @@ -86,6 +86,13 @@ add::add(const epvector & v, const ex & oc) GINAC_ASSERT(is_canonical()); } +add::add(epvector && vp) +{ + overall_coeff = _ex0; + construct_from_epvector(std::move(vp)); + GINAC_ASSERT(is_canonical()); +} + add::add(epvector && vp, const ex & oc) { overall_coeff = oc; @@ -307,18 +314,18 @@ ex add::coeff(const ex & s, int n) const if (!restcoeff.is_zero()) { if (do_clifford) { if (clifford_max_label(restcoeff) == -1) { - coeffseq_cliff.push_back(combine_ex_with_coeff_to_pair(ncmul(restcoeff, dirac_ONE(rl)), i.coeff)); + coeffseq_cliff.push_back(expair(ncmul(restcoeff, dirac_ONE(rl)), i.coeff)); } else { - coeffseq_cliff.push_back(combine_ex_with_coeff_to_pair(restcoeff, i.coeff)); + coeffseq_cliff.push_back(expair(restcoeff, i.coeff)); nonscalar = true; } } - coeffseq.push_back(combine_ex_with_coeff_to_pair(restcoeff, i.coeff)); + coeffseq.push_back(expair(restcoeff, i.coeff)); } } - return (new add(nonscalar ? std::move(coeffseq_cliff) : std::move(coeffseq), - n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated); + return dynallocate(nonscalar ? std::move(coeffseq_cliff) : std::move(coeffseq), + n==0 ? overall_coeff : _ex0); } /** Perform automatic term rewriting rules in this class. In the following @@ -326,15 +333,19 @@ ex add::coeff(const ex & s, int n) const * an expression that contain a plain number. * - +(;c) -> c * - +(x;0) -> x - * - * @param level cut-off in recursive evaluation */ -ex add::eval(int level) const + */ +ex add::eval() const { - epvector evaled = evalchildren(level); + if (flags & status_flags::evaluated) { + GINAC_ASSERT(seq.size()>0); + GINAC_ASSERT(seq.size()>1 || !overall_coeff.is_zero()); + return *this; + } + + const epvector evaled = evalchildren(); if (unlikely(!evaled.empty())) { - // do more evaluation later - return (new add(std::move(evaled), overall_coeff))-> - setflag(status_flags::dynallocated); + // start over evaluating a new object + return dynallocate(std::move(evaled), overall_coeff); } #ifdef DO_GINAC_ASSERT @@ -342,13 +353,7 @@ ex add::eval(int level) const GINAC_ASSERT(!is_exactly_a(i.rest)); } #endif // def DO_GINAC_ASSERT - - if (flags & status_flags::evaluated) { - GINAC_ASSERT(seq.size()>0); - GINAC_ASSERT(seq.size()>1 || !overall_coeff.is_zero()); - return *this; - } - + int seq_size = seq.size(); if (seq_size == 0) { // +(;c) -> c @@ -377,8 +382,7 @@ ex add::eval(int level) const else s.push_back(it); } - return (new add(std::move(s), ex_to(overall_coeff).add_dyn(oc))) - ->setflag(status_flags::dynallocated); + return dynallocate(std::move(s), ex_to(overall_coeff).add_dyn(oc)); } return this->hold(); @@ -411,7 +415,7 @@ ex add::evalm() const if (all_matrices) return sum + overall_coeff; else - return (new add(std::move(s), overall_coeff))->setflag(status_flags::dynallocated); + return dynallocate(std::move(s), overall_coeff); } ex add::conjugate() const @@ -452,8 +456,7 @@ ex add::real_part() const if (!rp.is_zero()) v.push_back(split_ex_to_pair(rp)); } - return (new add(std::move(v), overall_coeff.real_part())) - -> setflag(status_flags::dynallocated); + return dynallocate(std::move(v), overall_coeff.real_part()); } ex add::imag_part() const @@ -470,8 +473,7 @@ ex add::imag_part() const if (!ip.is_zero()) v.push_back(split_ex_to_pair(ip)); } - return (new add(std::move(v), overall_coeff.imag_part())) - -> setflag(status_flags::dynallocated); + return dynallocate(std::move(v), overall_coeff.imag_part()); } ex add::eval_ncmul(const exvector & v) const @@ -495,9 +497,9 @@ ex add::derivative(const symbol & y) const // than the default implementation in basic::derivative() although // if performs the same function (differentiate each term). for (auto & it : seq) - s.push_back(combine_ex_with_coeff_to_pair(it.rest.diff(y), it.coeff)); + s.push_back(expair(it.rest.diff(y), it.coeff)); - return (new add(std::move(s), _ex0))->setflag(status_flags::dynallocated); + return dynallocate(std::move(s)); } int add::compare_same_type(const basic & other) const @@ -524,13 +526,13 @@ return_type_t add::return_type_tinfo() const // Note: do_index_renaming is ignored because it makes no sense for an add. ex add::thisexpairseq(const epvector & v, const ex & oc, bool do_index_renaming) const { - return (new add(v,oc))->setflag(status_flags::dynallocated); + return dynallocate(v, oc); } // Note: do_index_renaming is ignored because it makes no sense for an add. ex add::thisexpairseq(epvector && vp, const ex & oc, bool do_index_renaming) const { - return (new add(std::move(vp), oc))->setflag(status_flags::dynallocated); + return dynallocate(std::move(vp), oc); } expair add::split_ex_to_pair(const ex & e) const @@ -538,12 +540,12 @@ expair add::split_ex_to_pair(const ex & e) const if (is_exactly_a(e)) { const mul &mulref(ex_to(e)); const ex &numfactor = mulref.overall_coeff; - mul *mulcopyp = new mul(mulref); - mulcopyp->overall_coeff = _ex1; - mulcopyp->clearflag(status_flags::evaluated); - mulcopyp->clearflag(status_flags::hash_calculated); - mulcopyp->setflag(status_flags::dynallocated); - return expair(*mulcopyp,numfactor); + if (numfactor.is_equal(_ex1)) + return expair(e, _ex1); + mul & mulcopy = dynallocate(mulref); + mulcopy.overall_coeff = _ex1; + mulcopy.clearflag(status_flags::evaluated | status_flags::hash_calculated); + return expair(mulcopy, numfactor); } return expair(e,_ex1); } @@ -555,20 +557,20 @@ expair add::combine_ex_with_coeff_to_pair(const ex & e, if (is_exactly_a(e)) { const mul &mulref(ex_to(e)); const ex &numfactor = mulref.overall_coeff; - mul *mulcopyp = new mul(mulref); - mulcopyp->overall_coeff = _ex1; - mulcopyp->clearflag(status_flags::evaluated); - mulcopyp->clearflag(status_flags::hash_calculated); - mulcopyp->setflag(status_flags::dynallocated); + if (likely(numfactor.is_equal(_ex1))) + return expair(e, c); + mul & mulcopy = dynallocate(mulref); + mulcopy.overall_coeff = _ex1; + mulcopy.clearflag(status_flags::evaluated | status_flags::hash_calculated); if (c.is_equal(_ex1)) - return expair(*mulcopyp, numfactor); - else if (numfactor.is_equal(_ex1)) - return expair(*mulcopyp, c); + return expair(mulcopy, numfactor); else - return expair(*mulcopyp, ex_to(numfactor).mul_dyn(ex_to(c))); + return expair(mulcopy, ex_to(numfactor).mul_dyn(ex_to(c))); } else if (is_exactly_a(e)) { if (c.is_equal(_ex1)) return expair(e, _ex1); + if (e.is_equal(_ex1)) + return expair(c, _ex1); return expair(ex_to(e).mul_dyn(ex_to(c)), _ex1); } return expair(e, c); @@ -593,7 +595,7 @@ ex add::recombine_pair_to_ex(const expair & p) const if (ex_to(p.coeff).is_equal(*_num1_p)) return p.rest; else - return (new mul(p.rest,p.coeff))->setflag(status_flags::dynallocated); + return dynallocate(p.rest, p.coeff); } ex add::expand(unsigned options) const @@ -602,8 +604,7 @@ ex add::expand(unsigned options) const if (expanded.empty()) return (options == 0) ? setflag(status_flags::expanded) : *this; - return (new add(std::move(expanded), overall_coeff))->setflag(status_flags::dynallocated | - (options == 0 ? status_flags::expanded : 0)); + return dynallocate(std::move(expanded), overall_coeff).setflag(options == 0 ? status_flags::expanded : 0); } } // namespace GiNaC