Improve method of setting status_flags::dynallocated.
authorRichard Kreckel <kreckel@ginac.de>
Mon, 30 Nov 2015 22:06:53 +0000 (23:06 +0100)
committerRichard Kreckel <kreckel@ginac.de>
Tue, 1 Dec 2015 22:29:01 +0000 (23:29 +0100)
There seems to be no way to obsolete the need to mark an object derived
from basic and handled by ex as being 'on the heap', at least none that
doesn't have significant performance impact. Having said that, this
patch aims at making this process simpler and more intuitive.

Where, before, one would return from a function returning an ex with
        return (new mul(a, b))->setflag(status_flags::dynallocated);
this patch lets us return with
        return dynallocate<mul>(a, b);
which should be much clearer. In any case, it involves less typing.

The two points where the status_flags::dynallocated are set are now
  * the dynallocate<B>(args...) template function and
  * the virtual duplicate() member functions.

This patch rolls out the new functionality throughout the library.

34 files changed:
check/exam_factor.cpp
check/exam_mod_gcd.cpp
ginac/add.cpp
ginac/basic.cpp
ginac/basic.h
ginac/clifford.cpp
ginac/color.cpp
ginac/ex.cpp
ginac/expairseq.cpp
ginac/function.cppy
ginac/idx.cpp
ginac/indexed.cpp
ginac/inifcns.cpp
ginac/inifcns_trans.cpp
ginac/integral.cpp
ginac/matrix.cpp
ginac/mul.cpp
ginac/ncmul.cpp
ginac/normal.cpp
ginac/numeric.cpp
ginac/operators.cpp
ginac/parser/parse_binop_rhs.cpp
ginac/polynomial/collect_vargs.cpp
ginac/polynomial/divide_in_z_p.cpp
ginac/polynomial/euclid_gcd_wrap.h
ginac/power.cpp
ginac/power.h
ginac/pseries.cpp
ginac/registrar.h
ginac/relational.cpp
ginac/symbol.h
ginac/symmetry.cpp
ginac/tensor.cpp
ginac/utils.cpp

index bed95aa17057632dccc1b75a0c374e72538a0f22..754deea7f8addb9fd44a3a87f25654dcd130bf77 100644 (file)
@@ -184,7 +184,7 @@ static unsigned exam_factor3()
 
 static unsigned check_factorization(const exvector& factors)
 {
-       ex e = (new mul(factors))->setflag(status_flags::dynallocated);
+       ex e = dynallocate<mul>(factors);
        ex ef = factor(e.expand());
        if (ef.nops() != factors.size()) {
                clog << "wrong number of factors, expected " << factors.size() <<
index 7415daec2a6376e1f9c6bfd96c340397abd4d551..ed210e05bc754b5fc0cb0933fc5830a8c6c5beb0 100644 (file)
@@ -91,7 +91,7 @@ static ex upoly_to_ex(const upoly& p, const symbol& x)
        exvector tv(p.size());
        for (std::size_t i = 0; i < p.size(); ++i)
                tv[i] = pow(x, i)*numeric(p[i]);
-       return (new add(tv))->setflag(status_flags::dynallocated);
+       return dynallocate<add>(tv);
 }
 
 static upoly make_random_upoly(const std::size_t deg)
index a32ae8036a4c29f17591d69be30b90afdf38e80c..978757fb2816011d2dc96ab817a70aa192b42e79 100644 (file)
@@ -317,8 +317,8 @@ ex add::coeff(const ex & s, int n) const
                }
        }
 
-       return (new add(nonscalar ? std::move(coeffseq_cliff) : std::move(coeffseq),
-                       n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated);
+       return dynallocate<add>(nonscalar ? std::move(coeffseq_cliff) : std::move(coeffseq),
+                               n==0 ? overall_coeff : _ex0);
 }
 
 /** Perform automatic term rewriting rules in this class.  In the following
@@ -333,8 +333,7 @@ ex add::eval(int level) const
        epvector evaled = evalchildren(level);
        if (unlikely(!evaled.empty())) {
                // do more evaluation later
-               return (new add(std::move(evaled), overall_coeff))->
-                       setflag(status_flags::dynallocated);
+               return dynallocate<add>(std::move(evaled), overall_coeff);
        }
 
 #ifdef DO_GINAC_ASSERT
@@ -377,8 +376,7 @@ ex add::eval(int level) const
                        else
                                s.push_back(it);
                }
-               return (new add(std::move(s), ex_to<numeric>(overall_coeff).add_dyn(oc)))
-                       ->setflag(status_flags::dynallocated);
+               return dynallocate<add>(std::move(s), ex_to<numeric>(overall_coeff).add_dyn(oc));
        }
        
        return this->hold();
@@ -411,7 +409,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<add>(std::move(s), overall_coeff);
 }
 
 ex add::conjugate() const
@@ -452,8 +450,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<add>(std::move(v), overall_coeff.real_part());
 }
 
 ex add::imag_part() const
@@ -470,8 +467,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<add>(std::move(v), overall_coeff.imag_part());
 }
 
 ex add::eval_ncmul(const exvector & v) const
@@ -497,7 +493,7 @@ ex add::derivative(const symbol & y) const
        for (auto & it : seq)
                s.push_back(combine_ex_with_coeff_to_pair(it.rest.diff(y), it.coeff));
 
-       return (new add(std::move(s), _ex0))->setflag(status_flags::dynallocated);
+       return dynallocate<add>(std::move(s), _ex0);
 }
 
 int add::compare_same_type(const basic & other) const
@@ -524,13 +520,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<add>(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<add>(std::move(vp), oc);
 }
 
 expair add::split_ex_to_pair(const ex & e) const
@@ -540,12 +536,10 @@ expair add::split_ex_to_pair(const ex & e) const
                const ex &numfactor = mulref.overall_coeff;
                if (numfactor.is_equal(_ex1))
                        return expair(e, _ex1);
-               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);
+               mul & mulcopy = dynallocate<mul>(mulref);
+               mulcopy.overall_coeff = _ex1;
+               mulcopy.clearflag(status_flags::evaluated | status_flags::hash_calculated);
+               return expair(mulcopy, numfactor);
        }
        return expair(e,_ex1);
 }
@@ -559,15 +553,13 @@ expair add::combine_ex_with_coeff_to_pair(const ex & e,
                const ex &numfactor = mulref.overall_coeff;
                if (numfactor.is_equal(_ex1))
                        return expair(e, c);
-               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);
+               mul & mulcopy = dynallocate<mul>(mulref);
+               mulcopy.overall_coeff = _ex1;
+               mulcopy.clearflag(status_flags::evaluated | status_flags::hash_calculated);
                if (c.is_equal(_ex1))
-                       return expair(*mulcopyp, numfactor);
+                       return expair(mulcopy, numfactor);
                else
-                       return expair(*mulcopyp, ex_to<numeric>(numfactor).mul_dyn(ex_to<numeric>(c)));
+                       return expair(mulcopy, ex_to<numeric>(numfactor).mul_dyn(ex_to<numeric>(c)));
        } else if (is_exactly_a<numeric>(e)) {
                if (c.is_equal(_ex1))
                        return expair(e, _ex1);
@@ -597,7 +589,7 @@ ex add::recombine_pair_to_ex(const expair & p) const
        if (ex_to<numeric>(p.coeff).is_equal(*_num1_p))
                return p.rest;
        else
-               return (new mul(p.rest,p.coeff))->setflag(status_flags::dynallocated);
+               return dynallocate<mul>(p.rest, p.coeff);
 }
 
 ex add::expand(unsigned options) const
@@ -606,8 +598,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<add>(std::move(expanded), overall_coeff).setflag(options == 0 ? status_flags::expanded : 0);
 }
 
 } // namespace GiNaC
index 01d369716f30870d2bf8e0eeab2441278647e97c..96cfd14c46fcd7458aff878993b7496f196950c3 100644 (file)
@@ -309,7 +309,6 @@ ex basic::map(map_function & f) const
        }
 
        if (copy) {
-               copy->setflag(status_flags::dynallocated);
                copy->clearflag(status_flags::hash_calculated | status_flags::expanded);
                return *copy;
        } else
@@ -384,7 +383,7 @@ ex basic::collect(const ex & s, bool distributed) const
                        exvector resv;
                        for (auto & mi : cmap)
                                resv.push_back((mi.first)*(mi.second));
-                       return (new add(resv))->setflag(status_flags::dynallocated);
+                       return dynallocate<add>(resv);
 
                } else {
 
@@ -625,7 +624,6 @@ ex basic::subs(const exmap & m, unsigned options) const
 
                                // Something changed, clone the object
                                basic *copy = duplicate();
-                               copy->setflag(status_flags::dynallocated);
                                copy->clearflag(status_flags::hash_calculated | status_flags::expanded);
 
                                // Substitute the changed operand
index b629f066d26bcc72d89de1a39723892f10b6617b..a8062c15c81d4460e86f571a4ecb636d3c9df5f0 100644 (file)
@@ -33,6 +33,7 @@
 #include <set>
 #include <typeinfo> // for typeid
 #include <vector>
+#include <utility>
 
 namespace GiNaC {
 
@@ -126,7 +127,12 @@ public: // only const functions please (may break reference counting)
        /** Create a clone of this object on the heap.  One can think of this as
         *  simulating a virtual copy constructor which is needed for instance by
         *  the refcounted construction of an ex from a basic. */
-       virtual basic * duplicate() const { return new basic(*this); }
+       virtual basic * duplicate() const
+       {
+               basic * bp = new basic(*this);
+               bp->setflag(status_flags::dynallocated);
+               return bp;
+       }
 
        // evaluation
        virtual ex eval(int level = 0) const;
@@ -296,7 +302,6 @@ protected:
        mutable unsigned hashvalue;         ///< hash value
 };
 
-
 // global variables
 
 extern int max_recursion_level;
@@ -318,6 +323,31 @@ inline bool is_exactly_a(const basic & obj)
        return typeid(T) == typeid(obj);
 }
 
+/** Constructs a new (class basic or derived) B object on the heap.
+ *
+ *  This function picks the object's ctor based on the given argument types.
+ *
+ *  This helps the constructor of ex from basic (or a derived class B) because
+ *  then the constructor doesn't have to duplicate the object onto the heap.
+ *  See ex::construct_from_basic(const basic &) for more information.
+ */
+template<class B, typename... Args>
+inline B & dynallocate(Args &&... args)
+{
+       return const_cast<B &>(static_cast<const B &>((new B(std::forward<Args>(args)...))->setflag(status_flags::dynallocated)));
+}
+/** Constructs a new (class basic or derived) B object on the heap.
+ *
+ *  This function is needed for GiNaC classes which have public ctors from
+ *  initializer lists of expressions (which are not a type and not captured
+ *  by the variadic template version).
+ */
+template<class B>
+inline B & dynallocate(std::initializer_list<ex> il)
+{
+       return const_cast<B &>(static_cast<const B &>((new B(il))->setflag(status_flags::dynallocated)));
+}
+
 } // namespace GiNaC
 
 #endif // ndef GINAC_BASIC_H
index 4b3c07948daf1d7566913a4b2223b5237a2dff37..f50062695232401a51205eb128c44223956eebae 100644 (file)
@@ -321,7 +321,7 @@ static void base_and_index(const ex & c, ex & b, ex & i)
                i = _ex0;
                b = _ex1;
        } else { // slash object, generate new dummy index
-               varidx ix((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(c.op(1)).get_dim());
+               varidx ix(dynallocate<symbol>(), ex_to<idx>(c.op(1)).get_dim());
                b = indexed(c.op(0), ix.toggle_variance());
                i = ix;
        }
@@ -661,7 +661,7 @@ ex clifford::eval_ncmul(const exvector & v) const
                        } else if (!a_is_cliffordunit && !b_is_cliffordunit && ag.is_equal(bg)) {
 
                                // a\ a\ -> a^2
-                               varidx ix((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(a.op(1)).minimal_dim(ex_to<idx>(b.op(1))));
+                               varidx ix(dynallocate<symbol>(), ex_to<idx>(a.op(1)).minimal_dim(ex_to<idx>(b.op(1))));
                                
                                a = indexed(ag, ix) * indexed(ag, ix.toggle_variance());
                                b = dirac_ONE(representation_label);
@@ -695,12 +695,12 @@ ex diracgamma5::conjugate() const
 
 ex diracgammaL::conjugate() const
 {
-       return (new diracgammaR)->setflag(status_flags::dynallocated);
+       return dynallocate<diracgammaR>();
 }
 
 ex diracgammaR::conjugate() const
 {
-       return (new diracgammaL)->setflag(status_flags::dynallocated);
+       return dynallocate<diracgammaL>();
 }
 
 //////////
@@ -709,7 +709,7 @@ ex diracgammaR::conjugate() const
 
 ex dirac_ONE(unsigned char rl)
 {
-       static ex ONE = (new diracone)->setflag(status_flags::dynallocated);
+       static ex ONE = dynallocate<diracone>();
        return clifford(ONE, rl);
 }
 
@@ -726,8 +726,7 @@ static unsigned get_dim_uint(const ex& e)
 
 ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl)
 {
-       //static ex unit = (new cliffordunit)->setflag(status_flags::dynallocated);
-       ex unit = (new cliffordunit)->setflag(status_flags::dynallocated);
+       ex unit = dynallocate<cliffordunit>();
 
        if (!is_a<idx>(mu))
                throw(std::invalid_argument("clifford_unit(): index of Clifford unit must be of type idx or varidx"));
@@ -741,10 +740,10 @@ ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl)
                unsigned n = M.rows();
                bool symmetric = true;
 
-               //static idx xi((new symbol)->setflag(status_flags::dynallocated), n),
-               //      chi((new symbol)->setflag(status_flags::dynallocated), n);
-               idx xi((new symbol)->setflag(status_flags::dynallocated), n),
-                       chi((new symbol)->setflag(status_flags::dynallocated), n);
+               //static idx xi(dynallocate<symbol>(), n),
+               //           chi(dynallocate<symbol>(), n);
+               idx xi(dynallocate<symbol>(), n),
+                   chi(dynallocate<symbol>(), n);
                if ((n ==  M.cols()) && (n == get_dim_uint(mu))) {
                        for (unsigned i = 0; i < n; i++) {
                                for (unsigned j = i+1; j < n; j++) {
@@ -758,10 +757,10 @@ ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl)
                        throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be a square matrix with the same dimensions as index"));
                }
        } else if (indices.size() == 0) { // a tensor or other expression without indices
-               //static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(mu).get_dim()),
-               //      chi((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(mu).get_dim());
-               varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(mu).get_dim()),
-                       chi((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(mu).get_dim());
+               //static varidx xi(dynallocate<symbol>(), ex_to<idx>(mu).get_dim()),
+               //              chi(dynallocate<symbol>(), ex_to<idx>(mu).get_dim());
+               varidx xi(dynallocate<symbol>(), ex_to<idx>(mu).get_dim()),
+                      chi(dynallocate<symbol>(), ex_to<idx>(mu).get_dim());
                return clifford(unit, mu, indexed(metr, xi, chi), rl);
        }  else 
                throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be of type tensor, matrix or an expression with two free indices"));
@@ -769,31 +768,31 @@ ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl)
 
 ex dirac_gamma(const ex & mu, unsigned char rl)
 {
-       static ex gamma = (new diracgamma)->setflag(status_flags::dynallocated);
+       static ex gamma = dynallocate<diracgamma>();
 
        if (!is_a<varidx>(mu))
                throw(std::invalid_argument("dirac_gamma(): index of Dirac gamma must be of type varidx"));
 
-       static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim()),
-               chi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim());
-       return clifford(gamma, mu, indexed((new minkmetric)->setflag(status_flags::dynallocated), symmetric2(), xi, chi), rl);
+       static varidx xi(dynallocate<symbol>(), ex_to<varidx>(mu).get_dim()),
+                     chi(dynallocate<symbol>(), ex_to<varidx>(mu).get_dim());
+       return clifford(gamma, mu, indexed(dynallocate<minkmetric>(), symmetric2(), xi, chi), rl);
 }
 
 ex dirac_gamma5(unsigned char rl)
 {
-       static ex gamma5 = (new diracgamma5)->setflag(status_flags::dynallocated);
+       static ex gamma5 = dynallocate<diracgamma5>();
        return clifford(gamma5, rl);
 }
 
 ex dirac_gammaL(unsigned char rl)
 {
-       static ex gammaL = (new diracgammaL)->setflag(status_flags::dynallocated);
+       static ex gammaL = dynallocate<diracgammaL>();
        return clifford(gammaL, rl);
 }
 
 ex dirac_gammaR(unsigned char rl)
 {
-       static ex gammaR = (new diracgammaR)->setflag(status_flags::dynallocated);
+       static ex gammaR = dynallocate<diracgammaR>();
        return clifford(gammaR, rl);
 }
 
@@ -803,9 +802,9 @@ ex dirac_slash(const ex & e, const ex & dim, unsigned char rl)
        // vector as its base expression and a (dummy) index that just serves
        // for storing the space dimensionality
 
-       static varidx xi((new symbol)->setflag(status_flags::dynallocated), dim),
-               chi((new symbol)->setflag(status_flags::dynallocated), dim);
-   return clifford(e, varidx(0, dim), indexed((new minkmetric)->setflag(status_flags::dynallocated), symmetric2(), xi, chi), rl);
+       static varidx xi(dynallocate<symbol>(), dim),
+                     chi(dynallocate<symbol>(), dim);
+       return clifford(e, varidx(0, dim), indexed(dynallocate<minkmetric>(), symmetric2(), xi, chi), rl);
 }
 
 /** Extract representation label from tinfo key (as returned by
@@ -1335,11 +1334,11 @@ ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d,
        } else {
                if (is_a<indexed>(G)) {
                        D = ex_to<idx>(G.op(1)).get_dim();
-                       varidx mu((new symbol)->setflag(status_flags::dynallocated), D);
+                       varidx mu(dynallocate<symbol>(), D);
                        cu = clifford_unit(mu, G, rl);
                } else if (is_a<matrix>(G)) {
                        D = ex_to<matrix>(G).rows(); 
-                       idx mu((new symbol)->setflag(status_flags::dynallocated), D);
+                       idx mu(dynallocate<symbol>(), D);
                        cu = clifford_unit(mu, G, rl);
                } else throw(std::invalid_argument("clifford_moebius_map(): metric should be an indexed object, matrix, or a Clifford unit"));
                
index dcc106dacda8309fec7f86c90ed295225a9f805d..0f7723e359d92f5dad7af8d14bf7f2f0406b7185 100644 (file)
@@ -474,13 +474,13 @@ bool su3f::contract_with(exvector::iterator self, exvector::iterator other, exve
 
 ex color_ONE(unsigned char rl)
 {
-       static ex ONE = (new su3one)->setflag(status_flags::dynallocated);
+       static ex ONE = dynallocate<su3one>();
        return color(ONE, rl);
 }
 
 ex color_T(const ex & a, unsigned char rl)
 {
-       static ex t = (new su3t)->setflag(status_flags::dynallocated);
+       static ex t = dynallocate<su3t>();
 
        if (!is_a<idx>(a))
                throw(std::invalid_argument("indices of color_T must be of type idx"));
@@ -492,7 +492,7 @@ ex color_T(const ex & a, unsigned char rl)
 
 ex color_f(const ex & a, const ex & b, const ex & c)
 {
-       static ex f = (new su3f)->setflag(status_flags::dynallocated);
+       static ex f = dynallocate<su3f>();
 
        if (!is_a<idx>(a) || !is_a<idx>(b) || !is_a<idx>(c))
                throw(std::invalid_argument("indices of color_f must be of type idx"));
@@ -504,7 +504,7 @@ ex color_f(const ex & a, const ex & b, const ex & c)
 
 ex color_d(const ex & a, const ex & b, const ex & c)
 {
-       static ex d = (new su3d)->setflag(status_flags::dynallocated);
+       static ex d = dynallocate<su3d>();
 
        if (!is_a<idx>(a) || !is_a<idx>(b) || !is_a<idx>(c))
                throw(std::invalid_argument("indices of color_d must be of type idx"));
@@ -595,7 +595,7 @@ ex color_trace(const ex & e, const std::set<unsigned char> & rls)
                        //   + 1/2 h_a(n-1)_an_k Tr T_a1 .. T_a(n-2) T_k
                        const ex &last_index = e.op(num - 1).op(1);
                        const ex &next_to_last_index = e.op(num - 2).op(1);
-                       idx summation_index((new symbol)->setflag(status_flags::dynallocated), 8);
+                       idx summation_index(dynallocate<symbol>(), 8);
 
                        exvector v1;
                        v1.reserve(num - 2);
index 648283001d861b2547bd5b0a8a585f6102e263f4..7bd8410b6d4f50dc2751557bb41dcb3471efa51c 100644 (file)
@@ -401,10 +401,7 @@ basic & ex::construct_from_int(int i)
        case 12:
                return *const_cast<numeric *>(_num12_p);
        default:
-               basic *bp = new numeric(i);
-               bp->setflag(status_flags::dynallocated);
-               GINAC_ASSERT(bp->get_refcount() == 0);
-               return *bp;
+               return dynallocate<numeric>(i);
        }
 }
        
@@ -438,10 +435,7 @@ basic & ex::construct_from_uint(unsigned int i)
        case 12:
                return *const_cast<numeric *>(_num12_p);
        default:
-               basic *bp = new numeric(i);
-               bp->setflag(status_flags::dynallocated);
-               GINAC_ASSERT(bp->get_refcount() == 0);
-               return *bp;
+               return dynallocate<numeric>(i);
        }
 }
        
@@ -499,10 +493,7 @@ basic & ex::construct_from_long(long i)
        case 12:
                return *const_cast<numeric *>(_num12_p);
        default:
-               basic *bp = new numeric(i);
-               bp->setflag(status_flags::dynallocated);
-               GINAC_ASSERT(bp->get_refcount() == 0);
-               return *bp;
+               return dynallocate<numeric>(i);
        }
 }
        
@@ -536,19 +527,13 @@ basic & ex::construct_from_ulong(unsigned long i)
        case 12:
                return *const_cast<numeric *>(_num12_p);
        default:
-               basic *bp = new numeric(i);
-               bp->setflag(status_flags::dynallocated);
-               GINAC_ASSERT(bp->get_refcount() == 0);
-               return *bp;
+               return dynallocate<numeric>(i);
        }
 }
        
 basic & ex::construct_from_double(double d)
 {
-       basic *bp = new numeric(d);
-       bp->setflag(status_flags::dynallocated);
-       GINAC_ASSERT(bp->get_refcount() == 0);
-       return *bp;
+       return dynallocate<numeric>(d);
 }
 
 //////////
index 44031d4575dd4ed890a65d91abbc5a3069a572c7..84b756f9d762e64721bd612485b8be4622a9706c 100644 (file)
@@ -246,7 +246,7 @@ ex expairseq::eval(int level) const
 
        epvector evaled = evalchildren(level);
        if (!evaled.empty())
-               return (new expairseq(std::move(evaled), overall_coeff))->setflag(status_flags::dynallocated | status_flags::evaluated);
+               return dynallocate<expairseq>(std::move(evaled), overall_coeff).setflag(status_flags::evaluated);
        else
                return this->hold();
 }
index 7030bca66afc6759a1264b244142132e692ec317..00e4b2a677333bc7ad5481f1e44c8a3373fe7682 100644 (file)
@@ -792,8 +792,7 @@ ex function::power(const ex & power_param) const // power of function
                }
        }
        // No power function defined? Fall back to returning a power object.
-       return (new GiNaC::power(*this, power_param))->setflag(status_flags::dynallocated |
-                                                              status_flags::evaluated);
+       return dynallocate<GiNaC::power>(*this, power_param).setflag(status_flags::evaluated);
 }
 
 ex function::expand(unsigned options) const
index d75e1326f4f63ad5c3e25d460743c9a63a977984..e0a9073c0b6510f0c3c3fabe1d19aba2c4f59d26 100644 (file)
@@ -260,7 +260,6 @@ ex idx::map(map_function & f) const
                return *this;
        else {
                idx *copy = duplicate();
-               copy->setflag(status_flags::dynallocated);
                copy->clearflag(status_flags::hash_calculated);
                copy->value = mapped_value;
                return *copy;
@@ -385,7 +384,7 @@ ex idx::subs(const exmap & m, unsigned options) const
                idx *i_copy = duplicate();
                i_copy->value = it->second;
                i_copy->clearflag(status_flags::hash_calculated);
-               return i_copy->setflag(status_flags::dynallocated);
+               return *i_copy;
        }
 
        // None, substitute objects in value (not in dimension)
@@ -396,7 +395,7 @@ ex idx::subs(const exmap & m, unsigned options) const
        idx *i_copy = duplicate();
        i_copy->value = subsed_value;
        i_copy->clearflag(status_flags::hash_calculated);
-       return i_copy->setflag(status_flags::dynallocated);
+       return *i_copy;
 }
 
 /** Implementation of ex::diff() for an index always returns 0.
@@ -463,7 +462,7 @@ ex idx::replace_dim(const ex & new_dim) const
        idx *i_copy = duplicate();
        i_copy->dim = new_dim;
        i_copy->clearflag(status_flags::hash_calculated);
-       return i_copy->setflag(status_flags::dynallocated);
+       return *i_copy;
 }
 
 ex idx::minimal_dim(const idx & other) const
@@ -476,7 +475,7 @@ ex varidx::toggle_variance() const
        varidx *i_copy = duplicate();
        i_copy->covariant = !i_copy->covariant;
        i_copy->clearflag(status_flags::hash_calculated);
-       return i_copy->setflag(status_flags::dynallocated);
+       return *i_copy;
 }
 
 ex spinidx::toggle_dot() const
@@ -484,7 +483,7 @@ ex spinidx::toggle_dot() const
        spinidx *i_copy = duplicate();
        i_copy->dotted = !i_copy->dotted;
        i_copy->clearflag(status_flags::hash_calculated);
-       return i_copy->setflag(status_flags::dynallocated);
+       return *i_copy;
 }
 
 ex spinidx::toggle_variance_dot() const
@@ -493,7 +492,7 @@ ex spinidx::toggle_variance_dot() const
        i_copy->covariant = !i_copy->covariant;
        i_copy->dotted = !i_copy->dotted;
        i_copy->clearflag(status_flags::hash_calculated);
-       return i_copy->setflag(status_flags::dynallocated);
+       return *i_copy;
 }
 
 //////////
index 675dd7c60453185e5d72107bfbc828f04e64a841..ca4beff53f63d2b57761c4380ae68a9b89829b1c 100644 (file)
@@ -1232,7 +1232,7 @@ ex simplify_indexed(const ex & e, exvector & free_indices, exvector & dummy_indi
                }
 
                // Add all resulting terms
-               ex sum_symm = (new add(result))->setflag(status_flags::dynallocated);
+               ex sum_symm = dynallocate<add>(result);
                if (sum_symm.is_zero())
                        free_indices.clear();
                return sum_symm;
@@ -1471,20 +1471,17 @@ lst rename_dummy_indices_uniquely(const exvector & va, const exvector & vb)
                new_indices.reserve(2*common_indices.size());
                exvector::const_iterator ip = common_indices.begin(), ipend = common_indices.end();
                while (ip != ipend) {
-                       ex newsym=(new symbol)->setflag(status_flags::dynallocated);
+                       ex newsym = dynallocate<symbol>();
                        ex newidx;
                        if(is_exactly_a<spinidx>(*ip))
-                               newidx = (new spinidx(newsym, ex_to<spinidx>(*ip).get_dim(),
-                                               ex_to<spinidx>(*ip).is_covariant(),
-                                               ex_to<spinidx>(*ip).is_dotted()))
-                                       -> setflag(status_flags::dynallocated);
+                               newidx = dynallocate<spinidx>(newsym, ex_to<spinidx>(*ip).get_dim(),
+                                                             ex_to<spinidx>(*ip).is_covariant(),
+                                                             ex_to<spinidx>(*ip).is_dotted());
                        else if (is_exactly_a<varidx>(*ip))
-                               newidx = (new varidx(newsym, ex_to<varidx>(*ip).get_dim(),
-                                               ex_to<varidx>(*ip).is_covariant()))
-                                       -> setflag(status_flags::dynallocated);
+                               newidx = dynallocate<varidx>(newsym, ex_to<varidx>(*ip).get_dim(),
+                                                            ex_to<varidx>(*ip).is_covariant());
                        else
-                               newidx = (new idx(newsym, ex_to<idx>(*ip).get_dim()))
-                                       -> setflag(status_flags::dynallocated);
+                               newidx = dynallocate<idx>(newsym, ex_to<idx>(*ip).get_dim());
                        old_indices.push_back(*ip);
                        new_indices.push_back(newidx);
                        if(is_a<varidx>(*ip)) {
index cff14f4388f9c71cfa59608041939e358a6c02ae..850ed04a5515e666f18ca3e42aa25a7957196bf7 100644 (file)
@@ -310,7 +310,7 @@ static ex abs_expand(const ex & arg, unsigned options)
                        else
                                prodseq.push_back(abs(*i));
                }
-               return (new mul(prodseq))->setflag(status_flags::dynallocated | status_flags::expanded);
+               return dynallocate<mul>(prodseq).setflag(status_flags::expanded);
        }
 
        if (options & expand_options::expand_function_args)
index d7fa377e269395d6b6b2c0af0591f44242c1a363..dd84418974b1c34c377894ced74a6906b258d519 100644 (file)
@@ -98,7 +98,7 @@ static ex exp_expand(const ex & arg, unsigned options)
                for (const_iterator i = exp_arg.begin(); i != exp_arg.end(); ++i)
                        prodseq.push_back(exp(*i));
 
-               return (new mul(prodseq))->setflag(status_flags::dynallocated | status_flags::expanded);
+               return dynallocate<mul>(prodseq).setflag(status_flags::expanded);
        }
 
        return exp(exp_arg).hold();
@@ -243,7 +243,7 @@ static ex log_series(const ex &arg,
                        // (sadly, to generate them, we have to start from the beginning)
                        if (n == 0 && coeff == 1) {
                                epvector epv;
-                               ex acc = (new pseries(rel, epv))->setflag(status_flags::dynallocated);
+                               ex acc = dynallocate<pseries>(rel, epv);
                                epv.reserve(2);
                                epv.push_back(expair(-1, _ex0));
                                epv.push_back(expair(Order(_ex1), order));
index 016be2ca726f0f14a714e9c754d2a022dad26c55..81e7adefcb3208f72af6e61746a1ec1ba239bd46 100644 (file)
@@ -48,8 +48,7 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(integral, basic,
 //////////
 
 integral::integral()
-               : 
-               x((new symbol())->setflag(status_flags::dynallocated))
+               : x(dynallocate<symbol>())
 {}
 
 //////////
@@ -162,8 +161,7 @@ ex integral::eval(int level) const
        if (are_ex_trivially_equal(eintvar,x) && are_ex_trivially_equal(ea,a) &&
            are_ex_trivially_equal(eb,b) && are_ex_trivially_equal(ef,f))
                return this->hold();
-       return (new integral(eintvar, ea, eb, ef))
-               ->setflag(status_flags::dynallocated | status_flags::evaluated);
+       return dynallocate<integral>(eintvar, ea, eb, ef).setflag(status_flags::evaluated);
 }
 
 ex integral::evalf(int level) const
@@ -195,8 +193,7 @@ ex integral::evalf(int level) const
            are_ex_trivially_equal(f, ef))
                        return *this;
                else
-                       return (new integral(x, ea, eb, ef))
-                               ->setflag(status_flags::dynallocated);
+                       return dynallocate<integral>(x, ea, eb, ef);
 }
 
 int integral::max_integration_level = 15;
@@ -414,8 +411,7 @@ ex integral::expand(unsigned options) const
                return *this;
        }
 
-       const basic & newint = (new integral(x, newa, newb, newf))
-               ->setflag(status_flags::dynallocated);
+       const integral & newint = dynallocate<integral>(x, newa, newb, newf);
        if (options == 0)
                newint.setflag(status_flags::expanded);
        return newint;
@@ -448,8 +444,7 @@ ex integral::conjugate() const
            are_ex_trivially_equal(f, conjf))
                return *this;
 
-       return (new integral(x, conja, conjb, conjf))
-               ->setflag(status_flags::dynallocated);
+       return dynallocate<integral>(x, conja, conjb, conjf);
 }
 
 ex integral::eval_integ() const
index 50f4631546a5795216287f27c9b9f272731fefa6..7d054cf1346c85b2346f1f9644ad9ae29bccd2c9 100644 (file)
@@ -245,8 +245,7 @@ ex matrix::eval(int level) const
                for (unsigned c=0; c<col; ++c)
                        m2[r*col+c] = m[r*col+c].eval(level);
        
-       return (new matrix(row, col, std::move(m2)))->setflag(status_flags::dynallocated |
-                                                             status_flags::evaluated);
+       return dynallocate<matrix>(row, col, std::move(m2)).setflag(status_flags::evaluated);
 }
 
 ex matrix::subs(const exmap & mp, unsigned options) const
@@ -1572,8 +1571,7 @@ ex lst_to_matrix(const lst & l)
        }
 
        // Allocate and fill matrix
-       matrix &M = *new matrix(rows, cols);
-       M.setflag(status_flags::dynallocated);
+       matrix & M = dynallocate<matrix>(rows, cols);
 
        unsigned i = 0;
        for (auto & itr : l) {
@@ -1593,8 +1591,7 @@ ex diag_matrix(const lst & l)
        size_t dim = l.nops();
 
        // Allocate and fill matrix
-       matrix &M = *new matrix(dim, dim);
-       M.setflag(status_flags::dynallocated);
+       matrix & M = dynallocate<matrix>(dim, dim);
 
        unsigned i = 0;
        for (auto & it : l) {
@@ -1610,8 +1607,7 @@ ex diag_matrix(std::initializer_list<ex> l)
        size_t dim = l.size();
 
        // Allocate and fill matrix
-       matrix &M = *new matrix(dim, dim);
-       M.setflag(status_flags::dynallocated);
+       matrix & M = dynallocate<matrix>(dim, dim);
 
        unsigned i = 0;
        for (auto & it : l) {
@@ -1624,8 +1620,8 @@ ex diag_matrix(std::initializer_list<ex> l)
 
 ex unit_matrix(unsigned r, unsigned c)
 {
-       matrix &Id = *new matrix(r, c);
-       Id.setflag(status_flags::dynallocated | status_flags::evaluated);
+       matrix & Id = dynallocate<matrix>(r, c);
+       Id.setflag(status_flags::evaluated);
        for (unsigned i=0; i<r && i<c; i++)
                Id(i,i) = _ex1;
 
@@ -1634,8 +1630,8 @@ ex unit_matrix(unsigned r, unsigned c)
 
 ex symbolic_matrix(unsigned r, unsigned c, const std::string & base_name, const std::string & tex_base_name)
 {
-       matrix &M = *new matrix(r, c);
-       M.setflag(status_flags::dynallocated | status_flags::evaluated);
+       matrix & M = dynallocate<matrix>(r, c);
+       M.setflag(status_flags::evaluated);
 
        bool long_format = (r > 10 || c > 10);
        bool single_row = (r == 1 || c == 1);
@@ -1676,8 +1672,8 @@ ex reduced_matrix(const matrix& m, unsigned r, unsigned c)
 
        const unsigned rows = m.rows()-1;
        const unsigned cols = m.cols()-1;
-       matrix &M = *new matrix(rows, cols);
-       M.setflag(status_flags::dynallocated | status_flags::evaluated);
+       matrix & M = dynallocate<matrix>(rows, cols);
+       M.setflag(status_flags::evaluated);
 
        unsigned ro = 0;
        unsigned ro2 = 0;
@@ -1705,8 +1701,8 @@ ex sub_matrix(const matrix&m, unsigned r, unsigned nr, unsigned c, unsigned nc)
        if (r+nr>m.rows() || c+nc>m.cols())
                throw std::runtime_error("sub_matrix(): index out of bounds");
 
-       matrix &M = *new matrix(nr, nc);
-       M.setflag(status_flags::dynallocated | status_flags::evaluated);
+       matrix & M = dynallocate<matrix>(nr, nc);
+       M.setflag(status_flags::evaluated);
 
        for (unsigned ro=0; ro<nr; ++ro) {
                for (unsigned co=0; co<nc; ++co) {
index c899ee11f25248cc0edd547f8149bd1a556c512f..48d64787e164f0078212af441b72599ff1492e47 100644 (file)
@@ -435,7 +435,7 @@ ex mul::coeff(const ex & s, int n) const
                for (auto & it : seq)
                        coeffseq.push_back(recombine_pair_to_ex(it).coeff(s,n));
                coeffseq.push_back(overall_coeff);
-               return (new mul(coeffseq))->setflag(status_flags::dynallocated);
+               return dynallocate<mul>(coeffseq);
        }
        
        bool coeff_found = false;
@@ -451,7 +451,7 @@ ex mul::coeff(const ex & s, int n) const
        }
        if (coeff_found) {
                coeffseq.push_back(overall_coeff);
-               return (new mul(coeffseq))->setflag(status_flags::dynallocated);
+               return dynallocate<mul>(coeffseq);
        }
        
        return _ex0;
@@ -471,8 +471,7 @@ ex mul::eval(int level) const
        epvector evaled = evalchildren(level);
        if (unlikely(!evaled.empty())) {
                // do more evaluation later
-               return (new mul(std::move(evaled), overall_coeff))->
-                       setflag(status_flags::dynallocated);
+               return dynallocate<mul>(std::move(evaled), overall_coeff);
        }
 
        if (flags & status_flags::evaluated) {
@@ -501,10 +500,9 @@ ex mul::eval(int level) const
                for (auto & it : addref.seq) {
                        distrseq.push_back(addref.combine_pair_with_coeff_to_pair(it, overall_coeff));
                }
-               return (new add(std::move(distrseq),
-                               ex_to<numeric>(addref.overall_coeff).
-                               mul_dyn(ex_to<numeric>(overall_coeff)))
-                      )->setflag(status_flags::dynallocated | status_flags::evaluated);
+               return dynallocate<add>(std::move(distrseq),
+                                        ex_to<numeric>(addref.overall_coeff).mul_dyn(ex_to<numeric>(overall_coeff)))
+                       .setflag(status_flags::evaluated);
        } else if ((seq_size >= 2) && (! (flags & status_flags::expanded))) {
                // Strip the content and the unit part from each term. Thus
                // things like (-x+a)*(3*x-3*a) automagically turn into - 3*(x-a)^2
@@ -554,14 +552,13 @@ ex mul::eval(int level) const
 
                        // divide add by the number in place to save at least 2 .eval() calls
                        const add& addref = ex_to<add>(i->rest);
-                       add* primitive = new add(addref);
-                       primitive->setflag(status_flags::dynallocated);
-                       primitive->clearflag(status_flags::hash_calculated);
-                       primitive->overall_coeff = ex_to<numeric>(primitive->overall_coeff).div_dyn(c);
-                       for (epvector::iterator ai = primitive->seq.begin(); ai != primitive->seq.end(); ++ai)
+                       add & primitive = dynallocate<add>(addref);
+                       primitive.clearflag(status_flags::hash_calculated);
+                       primitive.overall_coeff = ex_to<numeric>(primitive.overall_coeff).div_dyn(c);
+                       for (epvector::iterator ai = primitive.seq.begin(); ai != primitive.seq.end(); ++ai)
                                ai->coeff = ex_to<numeric>(ai->coeff).div_dyn(c);
                        
-                       s.push_back(expair(*primitive, _ex1));
+                       s.push_back(expair(primitive, _ex1));
 
                        ++i;
                        ++j;
@@ -571,8 +568,7 @@ ex mul::eval(int level) const
                                s.push_back(*j);
                                ++j;
                        }
-                       return (new mul(std::move(s), ex_to<numeric>(overall_coeff).mul_dyn(oc))
-                              )->setflag(status_flags::dynallocated);
+                       return dynallocate<mul>(std::move(s), ex_to<numeric>(overall_coeff).mul_dyn(oc));
                }
        }
 
@@ -664,11 +660,11 @@ ex mul::evalm() const
                // into that matrix.
                matrix m = ex_to<matrix>(the_matrix->rest);
                s.erase(the_matrix);
-               ex scalar = (new mul(std::move(s), overall_coeff))->setflag(status_flags::dynallocated);
+               ex scalar = dynallocate<mul>(std::move(s), overall_coeff);
                return m.mul_scalar(scalar);
 
        } else
-               return (new mul(std::move(s), overall_coeff))->setflag(status_flags::dynallocated);
+               return dynallocate<mul>(std::move(s), overall_coeff);
 }
 
 ex mul::eval_ncmul(const exvector & v) const
@@ -888,11 +884,11 @@ ex mul::derivative(const symbol & s) const
                expair ep = split_ex_to_pair(power(i->rest, i->coeff - _ex1) *
                                             i->rest.diff(s));
                ep.swap(*i2);
-               addseq.push_back((new mul(mulseq, overall_coeff * i->coeff))->setflag(status_flags::dynallocated));
+               addseq.push_back(dynallocate<mul>(mulseq, overall_coeff * i->coeff));
                ep.swap(*i2);
                ++i; ++i2;
        }
-       return (new add(addseq))->setflag(status_flags::dynallocated);
+       return dynallocate<add>(addseq);
 }
 
 int mul::compare_same_type(const basic & other) const
@@ -949,12 +945,12 @@ return_type_t mul::return_type_tinfo() const
 
 ex mul::thisexpairseq(const epvector & v, const ex & oc, bool do_index_renaming) const
 {
-       return (new mul(v, oc, do_index_renaming))->setflag(status_flags::dynallocated);
+       return dynallocate<mul>(v, oc, do_index_renaming);
 }
 
 ex mul::thisexpairseq(epvector && vp, const ex & oc, bool do_index_renaming) const
 {
-       return (new mul(std::move(vp), oc, do_index_renaming))->setflag(status_flags::dynallocated);
+       return dynallocate<mul>(std::move(vp), oc, do_index_renaming);
 }
 
 expair mul::split_ex_to_pair(const ex & e) const
@@ -998,7 +994,7 @@ ex mul::recombine_pair_to_ex(const expair & p) const
        if (ex_to<numeric>(p.coeff).is_equal(*_num1_p)) 
                return p.rest;
        else
-               return (new power(p.rest,p.coeff))->setflag(status_flags::dynallocated);
+               return dynallocate<power>(p.rest, p.coeff);
 }
 
 bool mul::expair_needs_further_processing(epp it)
@@ -1134,7 +1130,7 @@ ex mul::expand(unsigned options) const
                                }
 
                                // Compute the new overall coefficient and put it together:
-                               ex tmp_accu = (new add(distrseq, add1.overall_coeff*add2.overall_coeff))->setflag(status_flags::dynallocated);
+                               ex tmp_accu = dynallocate<add>(distrseq, add1.overall_coeff*add2.overall_coeff);
 
                                exvector add1_dummy_indices, add2_dummy_indices, add_indices;
                                lst dummy_subs;
@@ -1168,14 +1164,14 @@ ex mul::expand(unsigned options) const
                                        for (const auto & i1 : add1.seq) {
                                                // Don't push_back expairs which might have a rest that evaluates to a numeric,
                                                // since that would violate an invariant of expairseq:
-                                               const ex rest = (new mul(i1.rest, i2_new))->setflag(status_flags::dynallocated);
+                                               const ex rest = dynallocate<mul>(i1.rest, i2_new);
                                                if (is_exactly_a<numeric>(rest)) {
                                                        oc += ex_to<numeric>(rest).mul(ex_to<numeric>(i1.coeff).mul(ex_to<numeric>(i2.coeff)));
                                                } else {
                                                        distrseq2.push_back(expair(rest, ex_to<numeric>(i1.coeff).mul_dyn(ex_to<numeric>(i2.coeff))));
                                                }
                                        }
-                                       tmp_accu += (new add(distrseq2, oc))->setflag(status_flags::dynallocated);
+                                       tmp_accu += dynallocate<add>(std::move(distrseq2), oc);
                                }
                                last_expanded = tmp_accu;
                        } else {
@@ -1207,7 +1203,7 @@ ex mul::expand(unsigned options) const
                                factors.push_back(split_ex_to_pair(last_expanded.op(i)));
                        else
                                factors.push_back(split_ex_to_pair(rename_dummy_indices_uniquely(va, last_expanded.op(i))));
-                       ex term = (new mul(factors, overall_coeff))->setflag(status_flags::dynallocated);
+                       ex term = dynallocate<mul>(factors, overall_coeff);
                        if (can_be_further_expanded(term)) {
                                distrseq.push_back(term.expand());
                        } else {
@@ -1217,12 +1213,11 @@ ex mul::expand(unsigned options) const
                        }
                }
 
-               return ((new add(distrseq))->
-                       setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)));
+               return dynallocate<add>(distrseq).setflag(options == 0 ? status_flags::expanded : 0);
        }
 
        non_adds.push_back(split_ex_to_pair(last_expanded));
-       ex result = (new mul(non_adds, overall_coeff))->setflag(status_flags::dynallocated);
+       ex result = dynallocate<mul>(non_adds, overall_coeff);
        if (can_be_further_expanded(result)) {
                return result.expand();
        } else {
index 9ad55c57c80c427379afa83f9af6ab7f44e13653..c287a023248192da06a6a828cd072f00f4142459 100644 (file)
@@ -146,8 +146,7 @@ ex ncmul::expand(unsigned options) const
        // If there are no sums, we are done
        if (number_of_adds == 0) {
                if (!v.empty())
-                       return (new ncmul(std::move(v)))->
-                               setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
+                       return dynallocate<ncmul>(std::move(v)).setflag(options == 0 ? status_flags::expanded : 0);
                else
                        return *this;
        }
@@ -179,8 +178,7 @@ ex ncmul::expand(unsigned options) const
                        term[positions_of_adds[i]] = rename_dummy_indices_uniquely(va, expanded_seq[positions_of_adds[i]].op(k[i]), true);
                }
 
-               distrseq.push_back((new ncmul(std::move(term)))->
-                                   setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)));
+               distrseq.push_back(dynallocate<ncmul>(std::move(term)).setflag(options == 0 ? status_flags::expanded : 0));
 
                // increment k[]
                int l = number_of_adds-1;
@@ -192,8 +190,7 @@ ex ncmul::expand(unsigned options) const
                        break;
        }
 
-       return (new add(distrseq))->
-               setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
+       return dynallocate<add>(distrseq).setflag(options == 0 ? status_flags::expanded : 0);
 }
 
 int ncmul::degree(const ex & s) const
@@ -233,7 +230,7 @@ ex ncmul::coeff(const ex & s, int n) const
                // if a non-zero power of s is found, the resulting product will be 0
                for (auto & it : seq)
                        coeffseq.push_back(it.coeff(s,n));
-               return (new ncmul(std::move(coeffseq)))->setflag(status_flags::dynallocated);
+               return dynallocate<ncmul>(std::move(coeffseq));
        }
                 
        bool coeff_found = false;
@@ -248,7 +245,7 @@ ex ncmul::coeff(const ex & s, int n) const
        }
 
        if (coeff_found)
-               return (new ncmul(std::move(coeffseq)))->setflag(status_flags::dynallocated);
+               return dynallocate<ncmul>(std::move(coeffseq));
        
        return _ex0;
 }
@@ -364,8 +361,8 @@ ex ncmul::eval(int level) const
                        else
                                noncommutativeseq.push_back(assocseq[i]);
                }
-               commutativeseq.push_back((new ncmul(std::move(noncommutativeseq)))->setflag(status_flags::dynallocated));
-               return (new mul(std::move(commutativeseq)))->setflag(status_flags::dynallocated);
+               commutativeseq.push_back(dynallocate<ncmul>(std::move(noncommutativeseq)));
+               return dynallocate<mul>(std::move(commutativeseq));
        }
                
        // ncmul(x1,y1,x2,y2) -> *(ncmul(x1,x2),ncmul(y1,y2))
@@ -419,13 +416,12 @@ ex ncmul::eval(int level) const
                exvector splitseq;
                splitseq.reserve(evv_num);
                for (i=0; i<evv_num; ++i)
-                       splitseq.push_back((new ncmul(evv[i]))->setflag(status_flags::dynallocated));
+                       splitseq.push_back(dynallocate<ncmul>(evv[i]));
                
-               return (new mul(splitseq))->setflag(status_flags::dynallocated);
+               return dynallocate<mul>(splitseq);
        }
        
-       return (new ncmul(assocseq))->setflag(status_flags::dynallocated |
-                                                                                 status_flags::evaluated);
+       return dynallocate<ncmul>(assocseq).setflag(status_flags::evaluated);
 }
 
 ex ncmul::evalm() const
@@ -451,17 +447,17 @@ ex ncmul::evalm() const
        }
 
 no_matrix:
-       return (new ncmul(std::move(s)))->setflag(status_flags::dynallocated);
+       return dynallocate<ncmul>(std::move(s));
 }
 
 ex ncmul::thiscontainer(const exvector & v) const
 {
-       return (new ncmul(v))->setflag(status_flags::dynallocated);
+       return dynallocate<ncmul>(v);
 }
 
 ex ncmul::thiscontainer(exvector && v) const
 {
-       return (new ncmul(std::move(v)))->setflag(status_flags::dynallocated);
+       return dynallocate<ncmul>(std::move(v));
 }
 
 ex ncmul::conjugate() const
@@ -480,7 +476,7 @@ ex ncmul::conjugate() const
                --i;
                ev.push_back(i->conjugate());
        }
-       return (new ncmul(std::move(ev)))->setflag(status_flags::dynallocated).eval();
+       return dynallocate<ncmul>(std::move(ev)).eval();
 }
 
 ex ncmul::real_part() const
@@ -509,10 +505,10 @@ ex ncmul::derivative(const symbol & s) const
        for (size_t i=0; i<num; ++i) {
                ex e = seq[i].diff(s);
                e.swap(ncmulseq[i]);
-               addseq.push_back((new ncmul(ncmulseq))->setflag(status_flags::dynallocated));
+               addseq.push_back(dynallocate<ncmul>(ncmulseq));
                e.swap(ncmulseq[i]);
        }
-       return (new add(addseq))->setflag(status_flags::dynallocated);
+       return dynallocate<add>(addseq);
 }
 
 int ncmul::compare_same_type(const basic & other) const
@@ -615,7 +611,7 @@ const exvector & ncmul::get_factors() const
 
 ex reeval_ncmul(const exvector & v)
 {
-       return (new ncmul(v))->setflag(status_flags::dynallocated);
+       return dynallocate<ncmul>(v);
 }
 
 ex hold_ncmul(const exvector & v)
@@ -625,8 +621,7 @@ ex hold_ncmul(const exvector & v)
        else if (v.size() == 1)
                return v[0];
        else
-               return (new ncmul(v))->setflag(status_flags::dynallocated |
-                                              status_flags::evaluated);
+               return dynallocate<ncmul>(v).setflag(status_flags::evaluated);
 }
 
 GINAC_BIND_UNARCHIVER(ncmul);
index c362a43afaf83265e27c06ffb8486aae27957a75..ccf11e8d589ed83ec95813f7881b7b259fead6c4 100644 (file)
@@ -280,13 +280,13 @@ static ex multiply_lcm(const ex &e, const numeric &lcm)
                        lcm_accum *= op_lcm;
                }
                v.push_back(lcm / lcm_accum);
-               return (new mul(v))->setflag(status_flags::dynallocated);
+               return dynallocate<mul>(v);
        } else if (is_exactly_a<add>(e)) {
                size_t num = e.nops();
                exvector v; v.reserve(num);
                for (size_t i=0; i<num; i++)
                        v.push_back(multiply_lcm(e.op(i), lcm));
-               return (new add(v))->setflag(status_flags::dynallocated);
+               return dynallocate<add>(v);
        } else if (is_exactly_a<power>(e)) {
                if (is_a<symbol>(e.op(0)))
                        return e * lcm;
@@ -386,7 +386,7 @@ ex quo(const ex &a, const ex &b, const ex &x, bool check_args)
                        term = rcoeff / blcoeff;
                else {
                        if (!divide(rcoeff, blcoeff, term, false))
-                               return (new fail())->setflag(status_flags::dynallocated);
+                               return dynallocate<fail>();
                }
                term *= power(x, rdeg - bdeg);
                v.push_back(term);
@@ -395,7 +395,7 @@ ex quo(const ex &a, const ex &b, const ex &x, bool check_args)
                        break;
                rdeg = r.degree(x);
        }
-       return (new add(v))->setflag(status_flags::dynallocated);
+       return dynallocate<add>(v);
 }
 
 
@@ -439,7 +439,7 @@ ex rem(const ex &a, const ex &b, const ex &x, bool check_args)
                        term = rcoeff / blcoeff;
                else {
                        if (!divide(rcoeff, blcoeff, term, false))
-                               return (new fail())->setflag(status_flags::dynallocated);
+                               return dynallocate<fail>();
                }
                term *= power(x, rdeg - bdeg);
                r -= (term * b).expand();
@@ -653,7 +653,7 @@ bool divide(const ex &a, const ex &b, ex &q, bool check_args)
                                else
                                        resv.push_back(a.op(j));
                        }
-                       q = (new mul(resv))->setflag(status_flags::dynallocated);
+                       q = dynallocate<mul>(resv);
                        return true;
                }
        } else if (is_exactly_a<power>(a)) {
@@ -697,7 +697,7 @@ bool divide(const ex &a, const ex &b, ex &q, bool check_args)
                v.push_back(term);
                r -= (term * b).expand();
                if (r.is_zero()) {
-                       q = (new add(v))->setflag(status_flags::dynallocated);
+                       q = dynallocate<add>(v);
                        return true;
                }
                rdeg = r.degree(x);
@@ -880,7 +880,7 @@ static bool divide_in_z(const ex &a, const ex &b, ex &q, sym_desc_vec::const_ite
                v.push_back(term);
                r -= (term * eb).expand();
                if (r.is_zero()) {
-                       q = (new add(v))->setflag(status_flags::dynallocated);
+                       q = dynallocate<add>(v);
 #if USE_REMEMBER
                        dr_remember[ex2(a, b)] = exbool(q, true);
 #endif
@@ -1210,7 +1210,7 @@ ex add::smod(const numeric &xi) const
        }
        GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
        numeric coeff = GiNaC::smod(ex_to<numeric>(overall_coeff), xi);
-       return (new add(std::move(newseq), coeff))->setflag(status_flags::dynallocated);
+       return dynallocate<add>(std::move(newseq), coeff);
 }
 
 ex mul::smod(const numeric &xi) const
@@ -1220,12 +1220,12 @@ ex mul::smod(const numeric &xi) const
                GINAC_ASSERT(!is_exactly_a<numeric>(recombine_pair_to_ex(it)));
        }
 #endif // def DO_GINAC_ASSERT
-       mul * mulcopyp = new mul(*this);
+       mul & mulcopy = dynallocate<mul>(*this);
        GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
-       mulcopyp->overall_coeff = GiNaC::smod(ex_to<numeric>(overall_coeff),xi);
-       mulcopyp->clearflag(status_flags::evaluated);
-       mulcopyp->clearflag(status_flags::hash_calculated);
-       return mulcopyp->setflag(status_flags::dynallocated);
+       mulcopy.overall_coeff = GiNaC::smod(ex_to<numeric>(overall_coeff),xi);
+       mulcopy.clearflag(status_flags::evaluated);
+       mulcopy.clearflag(status_flags::hash_calculated);
+       return mulcopy;
 }
 
 
@@ -1240,7 +1240,7 @@ static ex interpolate(const ex &gamma, const numeric &xi, const ex &x, int degre
                g.push_back(gi * power(x, i));
                e = (e - gi) * rxi;
        }
-       return (new add(g))->setflag(status_flags::dynallocated);
+       return dynallocate<add>(g);
 }
 
 /** Exception thrown by heur_gcd() to signal failure. */
@@ -1737,10 +1737,10 @@ static ex gcd_pf_mul(const ex& a, const ex& b, ex* ca, ex* cb)
                part_b = part_cb;
        }
        if (ca)
-               *ca = (new mul(acc_ca))->setflag(status_flags::dynallocated);
+               *ca = dynallocate<mul>(acc_ca);
        if (cb)
                *cb = part_b;
-       return (new mul(g))->setflag(status_flags::dynallocated);
+       return dynallocate<mul>(g);
 }
 
 /** Compute LCM (Least Common Multiple) of multivariate polynomials in Z[X].
@@ -1992,7 +1992,7 @@ static ex replace_with_symbol(const ex & e, exmap & repl, exmap & rev_lookup)
        // Otherwise create new symbol and add to list, taking care that the
        // replacement expression doesn't itself contain symbols from repl,
        // because subs() is not recursive
-       ex es = (new symbol)->setflag(status_flags::dynallocated);
+       ex es = dynallocate<symbol>();
        repl.insert(std::make_pair(es, e_replaced));
        rev_lookup.insert(std::make_pair(e_replaced, es));
        return es;
@@ -2016,7 +2016,7 @@ static ex replace_with_symbol(const ex & e, exmap & repl)
        // Otherwise create new symbol and add to list, taking care that the
        // replacement expression doesn't itself contain symbols from repl,
        // because subs() is not recursive
-       ex es = (new symbol)->setflag(status_flags::dynallocated);
+       ex es = dynallocate<symbol>();
        repl.insert(std::make_pair(es, e_replaced));
        return es;
 }
@@ -2035,15 +2035,15 @@ struct normal_map_function : public map_function {
 ex basic::normal(exmap & repl, exmap & rev_lookup, int level) const
 {
        if (nops() == 0)
-               return (new lst{replace_with_symbol(*this, repl, rev_lookup), _ex1})->setflag(status_flags::dynallocated);
+               return dynallocate<lst>({replace_with_symbol(*this, repl, rev_lookup), _ex1});
        else {
                if (level == 1)
-                       return (new lst{replace_with_symbol(*this, repl, rev_lookup), _ex1})->setflag(status_flags::dynallocated);
+                       return dynallocate<lst>({replace_with_symbol(*this, repl, rev_lookup), _ex1});
                else if (level == -max_recursion_level)
                        throw(std::runtime_error("max recursion level reached"));
                else {
                        normal_map_function map_normal(level - 1);
-                       return (new lst{replace_with_symbol(map(map_normal), repl, rev_lookup), _ex1})->setflag(status_flags::dynallocated);
+                       return dynallocate<lst>({replace_with_symbol(map(map_normal), repl, rev_lookup), _ex1});
                }
        }
 }
@@ -2053,7 +2053,7 @@ ex basic::normal(exmap & repl, exmap & rev_lookup, int level) const
  *  @see ex::normal */
 ex symbol::normal(exmap & repl, exmap & rev_lookup, int level) const
 {
-       return (new lst{*this, _ex1})->setflag(status_flags::dynallocated);
+       return dynallocate<lst>({*this, _ex1});
 }
 
 
@@ -2077,7 +2077,7 @@ ex numeric::normal(exmap & repl, exmap & rev_lookup, int level) const
        }
 
        // Denominator is always a real integer (see numeric::denom())
-       return (new lst{numex, denom()})->setflag(status_flags::dynallocated);
+       return dynallocate<lst>({numex, denom()});
 }
 
 
@@ -2095,11 +2095,11 @@ static ex frac_cancel(const ex &n, const ex &d)
 
        // Handle trivial case where denominator is 1
        if (den.is_equal(_ex1))
-               return (new lst{num, den})->setflag(status_flags::dynallocated);
+               return dynallocate<lst>({num, den});
 
        // Handle special cases where numerator or denominator is 0
        if (num.is_zero())
-               return (new lst{num, _ex1})->setflag(status_flags::dynallocated);
+               return dynallocate<lst>({num, _ex1});
        if (den.expand().is_zero())
                throw(std::overflow_error("frac_cancel: division by zero in frac_cancel"));
 
@@ -2138,7 +2138,7 @@ static ex frac_cancel(const ex &n, const ex &d)
 
        // Return result as list
 //std::clog << " returns num = " << num << ", den = " << den << ", pre_factor = " << pre_factor << std::endl;
-       return (new lst{num * pre_factor.numer(), den * pre_factor.denom()})->setflag(status_flags::dynallocated);
+       return dynallocate<lst>({num * pre_factor.numer(), den * pre_factor.denom()});
 }
 
 
@@ -2148,7 +2148,7 @@ static ex frac_cancel(const ex &n, const ex &d)
 ex add::normal(exmap & repl, exmap & rev_lookup, int level) const
 {
        if (level == 1)
-               return (new lst{replace_with_symbol(*this, repl, rev_lookup), _ex1})->setflag(status_flags::dynallocated);
+               return dynallocate<lst>({replace_with_symbol(*this, repl, rev_lookup), _ex1});
        else if (level == -max_recursion_level)
                throw(std::runtime_error("max recursion level reached"));
 
@@ -2205,7 +2205,7 @@ ex add::normal(exmap & repl, exmap & rev_lookup, int level) const
 ex mul::normal(exmap & repl, exmap & rev_lookup, int level) const
 {
        if (level == 1)
-               return (new lst{replace_with_symbol(*this, repl, rev_lookup), _ex1})->setflag(status_flags::dynallocated);
+               return dynallocate<lst>({replace_with_symbol(*this, repl, rev_lookup), _ex1});
        else if (level == -max_recursion_level)
                throw(std::runtime_error("max recursion level reached"));
 
@@ -2223,8 +2223,7 @@ ex mul::normal(exmap & repl, exmap & rev_lookup, int level) const
        den.push_back(n.op(1));
 
        // Perform fraction cancellation
-       return frac_cancel((new mul(num))->setflag(status_flags::dynallocated),
-                          (new mul(den))->setflag(status_flags::dynallocated));
+       return frac_cancel(dynallocate<mul>(num), dynallocate<mul>(den));
 }
 
 
@@ -2235,7 +2234,7 @@ ex mul::normal(exmap & repl, exmap & rev_lookup, int level) const
 ex power::normal(exmap & repl, exmap & rev_lookup, int level) const
 {
        if (level == 1)
-               return (new lst{replace_with_symbol(*this, repl, rev_lookup), _ex1})->setflag(status_flags::dynallocated);
+               return dynallocate<lst>({replace_with_symbol(*this, repl, rev_lookup), _ex1});
        else if (level == -max_recursion_level)
                throw(std::runtime_error("max recursion level reached"));
 
@@ -2249,12 +2248,12 @@ ex power::normal(exmap & repl, exmap & rev_lookup, int level) const
                if (n_exponent.info(info_flags::positive)) {
 
                        // (a/b)^n -> {a^n, b^n}
-                       return (new lst{power(n_basis.op(0), n_exponent), power(n_basis.op(1), n_exponent)})->setflag(status_flags::dynallocated);
+                       return dynallocate<lst>({power(n_basis.op(0), n_exponent), power(n_basis.op(1), n_exponent)});
 
                } else if (n_exponent.info(info_flags::negative)) {
 
                        // (a/b)^-n -> {b^n, a^n}
-                       return (new lst{power(n_basis.op(1), -n_exponent), power(n_basis.op(0), -n_exponent)})->setflag(status_flags::dynallocated);
+                       return dynallocate<lst>({power(n_basis.op(1), -n_exponent), power(n_basis.op(0), -n_exponent)});
                }
 
        } else {
@@ -2262,25 +2261,25 @@ ex power::normal(exmap & repl, exmap & rev_lookup, int level) const
                if (n_exponent.info(info_flags::positive)) {
 
                        // (a/b)^x -> {sym((a/b)^x), 1}
-                       return (new lst{replace_with_symbol(power(n_basis.op(0) / n_basis.op(1), n_exponent), repl, rev_lookup), _ex1})->setflag(status_flags::dynallocated);
+                       return dynallocate<lst>({replace_with_symbol(power(n_basis.op(0) / n_basis.op(1), n_exponent), repl, rev_lookup), _ex1});
 
                } else if (n_exponent.info(info_flags::negative)) {
 
                        if (n_basis.op(1).is_equal(_ex1)) {
 
                                // a^-x -> {1, sym(a^x)}
-                               return (new lst{_ex1, replace_with_symbol(power(n_basis.op(0), -n_exponent), repl, rev_lookup)})->setflag(status_flags::dynallocated);
+                               return dynallocate<lst>({_ex1, replace_with_symbol(power(n_basis.op(0), -n_exponent), repl, rev_lookup)});
 
                        } else {
 
                                // (a/b)^-x -> {sym((b/a)^x), 1}
-                               return (new lst{replace_with_symbol(power(n_basis.op(1) / n_basis.op(0), -n_exponent), repl, rev_lookup), _ex1})->setflag(status_flags::dynallocated);
+                               return dynallocate<lst>({replace_with_symbol(power(n_basis.op(1) / n_basis.op(0), -n_exponent), repl, rev_lookup), _ex1});
                        }
                }
        }
 
        // (a/b)^x -> {sym((a/b)^x, 1}
-       return (new lst{replace_with_symbol(power(n_basis.op(0) / n_basis.op(1), n_exponent), repl, rev_lookup), _ex1})->setflag(status_flags::dynallocated);
+       return dynallocate<lst>({replace_with_symbol(power(n_basis.op(0) / n_basis.op(1), n_exponent), repl, rev_lookup), _ex1});
 }
 
 
@@ -2296,7 +2295,7 @@ ex pseries::normal(exmap & repl, exmap & rev_lookup, int level) const
                        newseq.push_back(expair(restexp, it.coeff));
        }
        ex n = pseries(relational(var,point), std::move(newseq));
-       return (new lst{replace_with_symbol(n, repl, rev_lookup), _ex1})->setflag(status_flags::dynallocated);
+       return dynallocate<lst>({replace_with_symbol(n, repl, rev_lookup), _ex1});
 }
 
 
@@ -2628,7 +2627,7 @@ static ex find_common_factor(const ex & e, ex & factor, exmap & repl)
                                                        else
                                                                v.push_back(t.op(k));
                                                }
-                                               t = (new mul(v))->setflag(status_flags::dynallocated);
+                                               t = dynallocate<mul>(v);
                                                goto term_done;
                                        }
                                }
@@ -2638,7 +2637,7 @@ static ex find_common_factor(const ex & e, ex & factor, exmap & repl)
                        t = x;
 term_done:     ;
                }
-               return (new add(terms))->setflag(status_flags::dynallocated);
+               return dynallocate<add>(terms);
 
        } else if (is_exactly_a<mul>(e)) {
 
@@ -2648,7 +2647,7 @@ term_done:        ;
                for (size_t i=0; i<num; i++)
                        v.push_back(find_common_factor(e.op(i), factor, repl));
 
-               return (new mul(v))->setflag(status_flags::dynallocated);
+               return dynallocate<mul>(v);
 
        } else if (is_exactly_a<power>(e)) {
                const ex e_exp(e.op(1));
index c86369fbe000cc2f885dac04a19ddcddb9c56394..2bb92653fd2fc079098e6af8c08b05bc61ae6c74 100644 (file)
@@ -929,9 +929,8 @@ const numeric &numeric::add_dyn(const numeric &other) const
                return other;
        else if (&other==_num0_p)
                return *this;
-       
-       return static_cast<const numeric &>((new numeric(value + other.value))->
-                                           setflag(status_flags::dynallocated));
+
+       return dynallocate<numeric>(value + other.value);
 }
 
 
@@ -945,9 +944,8 @@ const numeric &numeric::sub_dyn(const numeric &other) const
        // hack is supposed to keep the number of distinct numeric objects low.
        if (&other==_num0_p || cln::zerop(other.value))
                return *this;
-       
-       return static_cast<const numeric &>((new numeric(value - other.value))->
-                                           setflag(status_flags::dynallocated));
+
+       return dynallocate<numeric>(value - other.value);
 }
 
 
@@ -964,8 +962,7 @@ const numeric &numeric::mul_dyn(const numeric &other) const
        else if (&other==_num1_p)
                return *this;
        
-       return static_cast<const numeric &>((new numeric(value * other.value))->
-                                           setflag(status_flags::dynallocated));
+       return dynallocate<numeric>(value * other.value);
 }
 
 
@@ -983,8 +980,8 @@ const numeric &numeric::div_dyn(const numeric &other) const
                return *this;
        if (cln::zerop(cln::the<cln::cl_N>(other.value)))
                throw std::overflow_error("division by zero");
-       return static_cast<const numeric &>((new numeric(value / other.value))->
-                                           setflag(status_flags::dynallocated));
+
+       return dynallocate<numeric>(value / other.value);
 }
 
 
@@ -1010,8 +1007,8 @@ const numeric &numeric::power_dyn(const numeric &other) const
                else
                        return *_num0_p;
        }
-       return static_cast<const numeric &>((new numeric(cln::expt(value, other.value)))->
-                                            setflag(status_flags::dynallocated));
+
+       return dynallocate<numeric>(cln::expt(value, other.value));
 }
 
 
index 85d13af666e25059c682df4e3e8f3abff0632c46..4cb57ec7d510586b04c3f84b9021afc09b5ff570 100644 (file)
@@ -37,7 +37,7 @@ namespace GiNaC {
 /** Used internally by operator+() to add two ex objects together. */
 static inline const ex exadd(const ex & lh, const ex & rh)
 {
-       return (new add(lh,rh))->setflag(status_flags::dynallocated);
+       return dynallocate<add>(lh, rh);
 }
 
 /** Used internally by operator*() to multiply two ex objects together. */
@@ -48,16 +48,16 @@ static inline const ex exmul(const ex & lh, const ex & rh)
        // only one of the elements.
        if (rh.return_type()==return_types::commutative ||
            lh.return_type()==return_types::commutative) {
-               return (new mul(lh,rh))->setflag(status_flags::dynallocated);
+               return dynallocate<mul>(lh, rh);
        } else {
-               return (new ncmul(lh,rh))->setflag(status_flags::dynallocated);
+               return dynallocate<ncmul>(lh, rh);
        }
 }
 
 /** Used internally by operator-() and friends to change the sign of an argument. */
 static inline const ex exminus(const ex & lh)
 {
-       return (new mul(lh,_ex_1))->setflag(status_flags::dynallocated);
+       return dynallocate<mul>(lh, _ex_1);
 }
 
 // binary arithmetic operators ex with ex
index b506ad81e9b1282c90975a133a81673daafbacc9..aad3a712cba598a4b98e3d2aba7ecde041bb644f 100644 (file)
@@ -121,9 +121,9 @@ static ex make_minus_expr(const exvector& args)
        exvector rest_args;
        rest_args.reserve(args.size() - 1);
        std::copy(args.begin() + 1, args.end(), std::back_inserter(rest_args));
-       ex rest_base = (new add(rest_args))->setflag(status_flags::dynallocated);
-       ex rest = (new mul(rest_base, *_num_1_p))->setflag(status_flags::dynallocated);
-       ex ret = (new add(args[0], rest))->setflag(status_flags::dynallocated);
+       ex rest_base = dynallocate<add>(rest_args);
+       ex rest = dynallocate<mul>(rest_base, *_num_1_p);
+       ex ret = dynallocate<add>(args[0], rest);
        return ret;
 }
 
@@ -132,20 +132,20 @@ static ex make_divide_expr(const exvector& args)
        exvector rest_args;
        rest_args.reserve(args.size() - 1);
        std::copy(args.begin() + 1, args.end(), std::back_inserter(rest_args));
-       ex rest_base = (new mul(rest_args))->setflag(status_flags::dynallocated);
+       ex rest_base = dynallocate<mul>(rest_args);
        ex rest = pow(rest_base, *_num_1_p);
-       return (new mul(args[0], rest))->setflag(status_flags::dynallocated);
+       return dynallocate<mul>(args[0], rest);
 }
 
 static ex make_binop_expr(const int binop, const exvector& args)
 {
        switch (binop) {
                case '+':
-                       return (new add(args))->setflag(status_flags::dynallocated);
+                       return dynallocate<add>(args);
                case '-':
                        return make_minus_expr(args);
                case '*':
-                       return (new mul(args))->setflag(status_flags::dynallocated);
+                       return dynallocate<mul>(args);
                case '/':
                        return make_divide_expr(args);
                case '^':
index c06b16ebb625363f39a69cf406c93dce574f86d2..9ff206ef04e696e53acad880f40066ed2d3d387d 100644 (file)
@@ -158,10 +158,10 @@ ex_collect_to_ex(const ex_collect_t& ec, const exvector& vars)
                                tv.push_back(power(vars[j], exp_vector[j]));
                }
                tv.push_back(ec[i].second);
-               ex tmp = (new mul(tv))->setflag(status_flags::dynallocated);
+               ex tmp = dynallocate<mul>(tv);
                ev.push_back(tmp);
        }
-       ex ret = (new add(ev))->setflag(status_flags::dynallocated);
+       ex ret = dynallocate<add>(ev);
        return ret;
 }
 
index 5caea0e982dba389a803982ba2da46afc803aa32..6407caff65d277a441629e1b0e8ffbc6881ba8f9 100644 (file)
@@ -101,7 +101,7 @@ bool divide_in_z_p(const ex &a, const ex &b, ex &q, const exvector& vars, const
                if (p != 0)
                        r = r.smod(numeric(p));
                if (r.is_zero()) {
-                       q = (new add(v))->setflag(status_flags::dynallocated);
+                       q = dynallocate<add>(v);
                        return true;
                }
                rdeg = r.degree(x);
index 810b594def36f7a44ff4e292b7eacef715c3d6d3..1daf576fd742bd44d0077f4bc30330fab2e491f2 100644 (file)
@@ -59,7 +59,7 @@ static ex umodpoly2ex(const umodpoly& a, const ex& var, const long p)
                const ex term = numeric(c)*power(var, i);
                ev.push_back(term);
        }
-       ex ret = (new add(ev))->setflag(status_flags::dynallocated);
+       ex ret = dynallocate<add>(ev);
        return ret;
 }
        
index 1a452e3fcc91f36a0e78ec767e6d3cf7efc410db..2aedc9bfbd28b7af727e7275b75edc30ae28a31b 100644 (file)
@@ -282,7 +282,7 @@ ex power::map(map_function & f) const
 
        if (!are_ex_trivially_equal(basis, mapped_basis)
         || !are_ex_trivially_equal(exponent, mapped_exponent))
-               return (new power(mapped_basis, mapped_exponent))->setflag(status_flags::dynallocated);
+               return dynallocate<power>(mapped_basis, mapped_exponent);
        else
                return *this;
 }
@@ -438,9 +438,7 @@ ex power::eval(int level) const
                        const bool exponent_is_crational = num_exponent->is_crational();
                        if (!basis_is_crational || !exponent_is_crational) {
                                // return a plain float
-                               return (new numeric(num_basis->power(*num_exponent)))->setflag(status_flags::dynallocated |
-                                                                                              status_flags::evaluated |
-                                                                                              status_flags::expanded);
+                               return dynallocate<numeric>(num_basis->power(*num_exponent));
                        }
 
                        const numeric res = num_basis->power(*num_exponent);
@@ -470,9 +468,9 @@ ex power::eval(int level) const
                                                const numeric res_bnum = bnum.power(*num_exponent);
                                                const numeric res_bden = bden.power(*num_exponent);
                                                if (res_bnum.is_integer())
-                                                       return (new mul(power(bden,-*num_exponent),res_bnum))->setflag(status_flags::dynallocated | status_flags::evaluated);
+                                                       return dynallocate<mul>(dynallocate<power>(bden,-*num_exponent),res_bnum).setflag(status_flags::evaluated);
                                                if (res_bden.is_integer())
-                                                       return (new mul(power(bnum,*num_exponent),res_bden.inverse()))->setflag(status_flags::dynallocated | status_flags::evaluated);
+                                                       return dynallocate<mul>(dynallocate<power>(bnum,*num_exponent),res_bden.inverse()).setflag(status_flags::evaluated);
                                        }
                                        return this->hold();
                                } else {
@@ -521,18 +519,17 @@ ex power::eval(int level) const
                        
                        if (canonicalizable && (icont != *_num1_p)) {
                                const add& addref = ex_to<add>(ebasis);
-                               add* addp = new add(addref);
-                               addp->setflag(status_flags::dynallocated);
-                               addp->clearflag(status_flags::hash_calculated);
-                               addp->overall_coeff = ex_to<numeric>(addp->overall_coeff).div_dyn(icont);
-                               for (auto & i : addp->seq)
+                               add & addp = dynallocate<add>(addref);
+                               addp.clearflag(status_flags::hash_calculated);
+                               addp.overall_coeff = ex_to<numeric>(addp.overall_coeff).div_dyn(icont);
+                               for (auto & i : addp.seq)
                                        i.coeff = ex_to<numeric>(i.coeff).div_dyn(icont);
 
                                const numeric c = icont.power(*num_exponent);
                                if (likely(c != *_num1_p))
-                                       return (new mul(power(*addp, *num_exponent), c))->setflag(status_flags::dynallocated);
+                                       return dynallocate<mul>(dynallocate<power>(addp, *num_exponent), c);
                                else
-                                       return power(*addp, *num_exponent);
+                                       return dynallocate<power>(addp, *num_exponent);
                        }
                }
 
@@ -545,23 +542,19 @@ ex power::eval(int level) const
                                const numeric & num_coeff = ex_to<numeric>(mulref.overall_coeff);
                                if (num_coeff.is_real()) {
                                        if (num_coeff.is_positive()) {
-                                               mul *mulp = new mul(mulref);
-                                               mulp->overall_coeff = _ex1;
-                                               mulp->setflag(status_flags::dynallocated);
-                                               mulp->clearflag(status_flags::evaluated);
-                                               mulp->clearflag(status_flags::hash_calculated);
-                                               return (new mul(power(*mulp,exponent),
-                                                               power(num_coeff,*num_exponent)))->setflag(status_flags::dynallocated);
+                                               mul & mulp = dynallocate<mul>(mulref);
+                                               mulp.overall_coeff = _ex1;
+                                               mulp.clearflag(status_flags::evaluated | status_flags::hash_calculated);
+                                               return dynallocate<mul>(dynallocate<power>(mulp, exponent),
+                                                                       dynallocate<power>(num_coeff, *num_exponent));
                                        } else {
                                                GINAC_ASSERT(num_coeff.compare(*_num0_p)<0);
                                                if (!num_coeff.is_equal(*_num_1_p)) {
-                                                       mul *mulp = new mul(mulref);
-                                                       mulp->overall_coeff = _ex_1;
-                                                       mulp->setflag(status_flags::dynallocated);
-                                                       mulp->clearflag(status_flags::evaluated);
-                                                       mulp->clearflag(status_flags::hash_calculated);
-                                                       return (new mul(power(*mulp,exponent),
-                                                                       power(abs(num_coeff),*num_exponent)))->setflag(status_flags::dynallocated);
+                                                       mul & mulp = dynallocate<mul>(mulref);
+                                                       mulp.overall_coeff = _ex_1;
+                                                       mulp.clearflag(status_flags::evaluated | status_flags::hash_calculated);
+                                                       return dynallocate<mul>(dynallocate<power>(mulp, exponent),
+                                                                               dynallocate<power>(abs(num_coeff), *num_exponent));
                                                }
                                        }
                                }
@@ -580,8 +573,7 @@ ex power::eval(int level) const
            are_ex_trivially_equal(eexponent,exponent)) {
                return this->hold();
        }
-       return (new power(ebasis, eexponent))->setflag(status_flags::dynallocated |
-                                                      status_flags::evaluated);
+       return dynallocate<power>(ebasis, eexponent).setflag(status_flags::evaluated);
 }
 
 ex power::evalf(int level) const
@@ -611,10 +603,10 @@ ex power::evalm() const
        const ex eexponent = exponent.evalm();
        if (is_a<matrix>(ebasis)) {
                if (is_exactly_a<numeric>(eexponent)) {
-                       return (new matrix(ex_to<matrix>(ebasis).pow(eexponent)))->setflag(status_flags::dynallocated);
+                       return dynallocate<matrix>(ex_to<matrix>(ebasis).pow(eexponent));
                }
        }
-       return (new power(ebasis, eexponent))->setflag(status_flags::dynallocated);
+       return dynallocate<power>(ebasis, eexponent);
 }
 
 bool power::has(const ex & other, unsigned options) const
@@ -682,14 +674,14 @@ ex power::conjugate() const
                if (are_ex_trivially_equal(exponent, newexponent)) {
                        return *this;
                }
-               return (new power(basis, newexponent))->setflag(status_flags::dynallocated);
+               return dynallocate<power>(basis, newexponent);
        }
        if (exponent.info(info_flags::integer)) {
                ex newbasis = basis.conjugate();
                if (are_ex_trivially_equal(basis, newbasis)) {
                        return *this;
                }
-               return (new power(newbasis, exponent))->setflag(status_flags::dynallocated);
+               return dynallocate<power>(newbasis, exponent);
        }
        return conjugate_function(*this).hold();
 }
@@ -852,7 +844,7 @@ ex power::expand(unsigned options) const
                if (prodseq.size() > 0) {
                        ex newbasis = coeff*mul(std::move(powseq));
                        ex_to<basic>(newbasis).setflag(status_flags::purely_indefinite);
-                       return ((new mul(std::move(prodseq)))->setflag(status_flags::dynallocated)*(new power(newbasis, exponent))->setflag(status_flags::dynallocated).expand(options)).expand(options);
+                       return dynallocate<mul>(std::move(prodseq)) * pow(newbasis, exponent);
                } else
                        ex_to<basic>(basis).setflag(status_flags::purely_indefinite);
        }
@@ -881,7 +873,7 @@ ex power::expand(unsigned options) const
                        distrseq.push_back(power(expanded_basis, a.overall_coeff));
                
                // Make sure that e.g. (x+y)^(1+a) -> x*(x+y)^a + y*(x+y)^a
-               ex r = (new mul(distrseq))->setflag(status_flags::dynallocated);
+               ex r = dynallocate<mul>(distrseq);
                return r.expand(options);
        }
        
@@ -890,7 +882,7 @@ ex power::expand(unsigned options) const
                if (are_ex_trivially_equal(basis,expanded_basis) && are_ex_trivially_equal(exponent,expanded_exponent)) {
                        return this->hold();
                } else {
-                       return (new power(expanded_basis,expanded_exponent))->setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
+                       return dynallocate<power>(expanded_basis, expanded_exponent).setflag(options == 0 ? status_flags::expanded : 0);
                }
        }
        
@@ -910,7 +902,7 @@ ex power::expand(unsigned options) const
        if (are_ex_trivially_equal(basis,expanded_basis) && are_ex_trivially_equal(exponent,expanded_exponent))
                return this->hold();
        else
-               return (new power(expanded_basis,expanded_exponent))->setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
+               return dynallocate<power>(expanded_basis, expanded_exponent).setflag(options == 0 ? status_flags::expanded : 0);
 }
 
 //////////
@@ -1228,7 +1220,7 @@ ex power::expand_add(const add & a, long n, unsigned options)
                                                if (c != *_num1_p)
                                                        factor = factor.mul(c);
                                        } else { // general case exponent[i] > 1
-                                               monomial.push_back((new power(r, exponent[i]))->setflag(status_flags::dynallocated));
+                                               monomial.push_back(dynallocate<power>(r, exponent[i]));
                                                if (c != *_num1_p)
                                                        factor = factor.mul(c.power(exponent[i]));
                                        }
@@ -1241,11 +1233,9 @@ ex power::expand_add(const add & a, long n, unsigned options)
        GINAC_ASSERT(result.size() == result_size);
 
        if (a.overall_coeff.is_zero()) {
-               return (new add(std::move(result)))->setflag(status_flags::dynallocated |
-                                                            status_flags::expanded);
+               return dynallocate<add>(std::move(result)).setflag(status_flags::expanded);
        } else {
-               return (new add(std::move(result), ex_to<numeric>(a.overall_coeff).power(n)))->setflag(status_flags::dynallocated |
-                                                                                                      status_flags::expanded);
+               return dynallocate<add>(std::move(result), ex_to<numeric>(a.overall_coeff).power(n)).setflag(status_flags::expanded);
        }
 }
 
@@ -1283,7 +1273,7 @@ ex power::expand_add_2(const add & a, unsigned options)
                                result.push_back(a.combine_ex_with_coeff_to_pair(expand_mul(ex_to<mul>(r), *_num2_p, options, true),
                                                                                 _ex1));
                        } else {
-                               result.push_back(a.combine_ex_with_coeff_to_pair((new power(r,_ex2))->setflag(status_flags::dynallocated),
+                               result.push_back(a.combine_ex_with_coeff_to_pair(dynallocate<power>(r, _ex2),
                                                                                 _ex1));
                        }
                } else {
@@ -1291,7 +1281,7 @@ ex power::expand_add_2(const add & a, unsigned options)
                                result.push_back(a.combine_ex_with_coeff_to_pair(expand_mul(ex_to<mul>(r), *_num2_p, options, true),
                                                                                 ex_to<numeric>(c).power_dyn(*_num2_p)));
                        } else {
-                               result.push_back(a.combine_ex_with_coeff_to_pair((new power(r,_ex2))->setflag(status_flags::dynallocated),
+                               result.push_back(a.combine_ex_with_coeff_to_pair(dynallocate<power>(r, _ex2),
                                                                                 ex_to<numeric>(c).power_dyn(*_num2_p)));
                        }
                }
@@ -1313,11 +1303,9 @@ ex power::expand_add_2(const add & a, unsigned options)
        GINAC_ASSERT(result.size() == result_size);
 
        if (a.overall_coeff.is_zero()) {
-               return (new add(std::move(result)))->setflag(status_flags::dynallocated |
-                                                            status_flags::expanded);
+               return dynallocate<add>(std::move(result)).setflag(status_flags::expanded);
        } else {
-               return (new add(std::move(result), ex_to<numeric>(a.overall_coeff).power(2)))->setflag(status_flags::dynallocated |
-                                                                                                      status_flags::expanded);
+               return dynallocate<add>(std::move(result), ex_to<numeric>(a.overall_coeff).power(2)).setflag(status_flags::expanded);
        }
 }
 
@@ -1361,7 +1349,7 @@ ex power::expand_mul(const mul & m, const numeric & n, unsigned options, bool fr
                distrseq.push_back(p);
        }
 
-       const mul & result = static_cast<const mul &>((new mul(distrseq, ex_to<numeric>(m.overall_coeff).power_dyn(n)))->setflag(status_flags::dynallocated));
+       const mul & result = dynallocate<mul>(std::move(distrseq), ex_to<numeric>(m.overall_coeff).power_dyn(n));
        if (need_reexpand)
                return ex(result).expand(options);
        if (from_expand)
index 0d8eb49e3965ecff5e4ae7d9bee72d475c07701c..1662ee0382065dc4312adc7879de8957f775aaf8 100644 (file)
@@ -115,12 +115,12 @@ GINAC_DECLARE_UNARCHIVER(power);
  *  @param e the exponent expression */
 inline ex pow(const ex & b, const ex & e)
 {
-       return power(b, e);
+       return dynallocate<power>(b, e);
 }
 template<typename T1, typename T2>
 inline ex pow(const T1 & b, const T2 & e)
 {
-       return power(ex(b), ex(e));
+       return dynallocate<power>(ex(b), ex(e));
 }
 
 /** Square root expression.  Returns a power-object with exponent 1/2. */
index 12b57d6b55e8c1a6379d171b8d250772a8140787..08809fd18c2af3e54806f1ac3febcb970fc8862e 100644 (file)
@@ -400,7 +400,7 @@ ex pseries::eval(int level) const
                new_seq.push_back(expair(it->rest.eval(level-1), it->coeff));
                ++it;
        }
-       return (new pseries(relational(var,point), std::move(new_seq)))->setflag(status_flags::dynallocated | status_flags::evaluated);
+       return dynallocate<pseries>(relational(var,point), std::move(new_seq)).setflag(status_flags::evaluated);
 }
 
 /** Evaluate coefficients numerically. */
@@ -420,7 +420,7 @@ ex pseries::evalf(int level) const
                new_seq.push_back(expair(it->rest.evalf(level-1), it->coeff));
                ++it;
        }
-       return (new pseries(relational(var,point), std::move(new_seq)))->setflag(status_flags::dynallocated | status_flags::evaluated);
+       return dynallocate<pseries>(relational(var,point), std::move(new_seq)).setflag(status_flags::evaluated);
 }
 
 ex pseries::conjugate() const
@@ -435,7 +435,7 @@ ex pseries::conjugate() const
                return *this;
        }
 
-       return (new pseries(var==newpoint, newseq ? std::move(*newseq) : seq))->setflag(status_flags::dynallocated);
+       return dynallocate<pseries>(var==newpoint, newseq ? std::move(*newseq) : seq);
 }
 
 ex pseries::real_part() const
@@ -450,7 +450,7 @@ ex pseries::real_part() const
        v.reserve(seq.size());
        for (auto & it : seq)
                v.push_back(expair((it.rest).real_part(), it.coeff));
-       return (new pseries(var==point, std::move(v)))->setflag(status_flags::dynallocated);
+       return dynallocate<pseries>(var==point, std::move(v));
 }
 
 ex pseries::imag_part() const
@@ -465,7 +465,7 @@ ex pseries::imag_part() const
        v.reserve(seq.size());
        for (auto & it : seq)
                v.push_back(expair((it.rest).imag_part(), it.coeff));
-       return (new pseries(var==point, std::move(v)))->setflag(status_flags::dynallocated);
+       return dynallocate<pseries>(var==point, std::move(v));
 }
 
 ex pseries::eval_integ() const
@@ -488,8 +488,7 @@ ex pseries::eval_integ() const
 
        ex newpoint = point.eval_integ();
        if (newseq || !are_ex_trivially_equal(newpoint, point))
-               return (new pseries(var==newpoint, std::move(*newseq)))
-                      ->setflag(status_flags::dynallocated);
+               return dynallocate<pseries>(var==newpoint, std::move(*newseq));
        return *this;
 }
 
@@ -516,7 +515,7 @@ ex pseries::evalm() const
                }
        }
        if (something_changed)
-               return (new pseries(var==point, std::move(newseq)))->setflag(status_flags::dynallocated);
+               return dynallocate<pseries>(var==point, std::move(newseq));
        else
                return *this;
 }
@@ -535,7 +534,7 @@ ex pseries::subs(const exmap & m, unsigned options) const
        newseq.reserve(seq.size());
        for (auto & it : seq)
                newseq.push_back(expair(it.rest.subs(m, options), it.coeff));
-       return (new pseries(relational(var,point.subs(m, options)), std::move(newseq)))->setflag(status_flags::dynallocated);
+       return dynallocate<pseries>(relational(var,point.subs(m, options)), std::move(newseq));
 }
 
 /** Implementation of ex::expand() for a power series.  It expands all the
@@ -548,8 +547,7 @@ ex pseries::expand(unsigned options) const
                if (!restexp.is_zero())
                        newseq.push_back(expair(restexp, it.coeff));
        }
-       return (new pseries(relational(var,point), std::move(newseq)))
-               ->setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
+       return dynallocate<pseries>(relational(var,point), std::move(newseq)).setflag(options == 0 ? status_flags::expanded : 0);
 }
 
 /** Implementation of ex::diff() for a power series.
@@ -823,8 +821,7 @@ ex pseries::mul_series(const pseries &other) const
        }
 
        if (seq.empty() || other.seq.empty()) {
-               return (new pseries(var==point, epvector()))
-                      ->setflag(status_flags::dynallocated);
+               return dynallocate<pseries>(var==point, epvector());
        }
        
        // Series multiplication
@@ -955,7 +952,7 @@ ex mul::series(const relational & r, int order, unsigned options) const
 
        if (degsum >= order) {
                epvector epv { expair(Order(_ex1), order) };
-               return (new pseries(r, std::move(epv)))->setflag(status_flags::dynallocated);
+               return dynallocate<pseries>(r, std::move(epv));
        }
 
        // Multiply with remaining terms
@@ -1022,8 +1019,7 @@ ex pseries::power_const(const numeric &p, int deg) const
        int numcoeff = deg - (p*ldeg).to_int();
        if (numcoeff <= 0) {
                epvector epv { expair(Order(_ex1), deg) };
-               return (new pseries(relational(var,point), std::move(epv)))
-                      ->setflag(status_flags::dynallocated);
+               return dynallocate<pseries>(relational(var,point), std::move(epv));
        }
        
        // O(x^n)^(-m) is undefined
@@ -1219,7 +1215,7 @@ ex integral::series(const relational & r, int order, unsigned options) const
        }
 
        // Expanding lower boundary
-       ex result = (new pseries(r, std::move(fexpansion)))->setflag(status_flags::dynallocated);
+       ex result = dynallocate<pseries>(r, std::move(fexpansion));
        ex aseries = (a-a.subs(r)).series(r, order, options);
        fseries = f.series(x == (a.subs(r)), order, options);
        for (size_t i=0; i<fseries.nops(); ++i) {
index 5e2b0e49fbd18e71d658b517e1fee26321533efe..f2f7e616ab772247934403a9e2e0ba9effaee657 100644 (file)
@@ -149,9 +149,14 @@ public: \
  *  registry (mainly needed for archiving). */
 #define GINAC_DECLARE_REGISTERED_CLASS(classname, supername) \
        GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(classname, supername) \
+       template<class B, typename... Args> friend B & dynallocate(Args &&... args); \
 public: \
        classname(); \
-       classname * duplicate() const override { return new classname(*this); } \
+       classname * duplicate() const override { \
+               classname * bp = new classname(*this); \
+               bp->setflag(status_flags::dynallocated); \
+               return bp; \
+       } \
        \
        void accept(GiNaC::visitor & v) const override \
        { \
index c5b42d3c33c9121b254bec6b920a11d6b8072e65..479522cf0ce8d301aea4f8eaca13ecab6fab1334 100644 (file)
@@ -171,7 +171,7 @@ ex relational::map(map_function & f) const
 
        if (!are_ex_trivially_equal(lh, mapped_lh)
         || !are_ex_trivially_equal(rh, mapped_rh))
-               return (new relational(mapped_lh, mapped_rh, o))->setflag(status_flags::dynallocated);
+               return dynallocate<relational>(mapped_lh, mapped_rh, o);
        else
                return *this;
 }
@@ -184,7 +184,7 @@ ex relational::eval(int level) const
        if (level == -max_recursion_level)
                throw(std::runtime_error("max recursion level reached"));
        
-       return (new relational(lh.eval(level-1),rh.eval(level-1),o))->setflag(status_flags::dynallocated | status_flags::evaluated);
+       return dynallocate<relational>(lh.eval(level-1), rh.eval(level-1), o).setflag(status_flags::evaluated);
 }
 
 ex relational::subs(const exmap & m, unsigned options) const
index 68b747e8abb899576607cf5179d44e15cbf52ff7..84320f277ef796c400d95e94c7035b87dd0a3b5e 100644 (file)
@@ -107,7 +107,12 @@ public:
        ex real_part() const override { return *this; }
        ex imag_part() const override { return 0; }
 
-       realsymbol* duplicate() const override { return new realsymbol(*this); }
+       realsymbol* duplicate() const override
+       {
+               realsymbol * bp = new realsymbol(*this);
+               bp->setflag(status_flags::dynallocated);
+               return bp;
+       }
 };
 GINAC_DECLARE_UNARCHIVER(realsymbol);
 
@@ -122,7 +127,12 @@ public:
 
        unsigned get_domain() const override { return domain::positive; }
 
-       possymbol* duplicate() const override { return new possymbol(*this); }
+       possymbol* duplicate() const override
+       {
+               possymbol * bp = new possymbol(*this);
+               bp->setflag(status_flags::dynallocated);
+               return bp;
+       }
 };
 GINAC_DECLARE_UNARCHIVER(possymbol);
 
index 146700397ec83d2b2f6738ea0d29abb909694327..20aa913713014bd478a3346bd2b55d87bb892187 100644 (file)
@@ -325,67 +325,67 @@ void symmetry::validate(unsigned n)
 
 static const symmetry & index0()
 {
-       static ex s = (new symmetry(0))->setflag(status_flags::dynallocated);
+       static ex s = dynallocate<symmetry>(0);
        return ex_to<symmetry>(s);
 }
 
 static const symmetry & index1()
 {
-       static ex s = (new symmetry(1))->setflag(status_flags::dynallocated);
+       static ex s = dynallocate<symmetry>(1);
        return ex_to<symmetry>(s);
 }
 
 static const symmetry & index2()
 {
-       static ex s = (new symmetry(2))->setflag(status_flags::dynallocated);
+       static ex s = dynallocate<symmetry>(2);
        return ex_to<symmetry>(s);
 }
 
 static const symmetry & index3()
 {
-       static ex s = (new symmetry(3))->setflag(status_flags::dynallocated);
+       static ex s = dynallocate<symmetry>(3);
        return ex_to<symmetry>(s);
 }
 
 const symmetry & not_symmetric()
 {
-       static ex s = (new symmetry)->setflag(status_flags::dynallocated);
+       static ex s = dynallocate<symmetry>();
        return ex_to<symmetry>(s);
 }
 
 const symmetry & symmetric2()
 {
-       static ex s = (new symmetry(symmetry::symmetric, index0(), index1()))->setflag(status_flags::dynallocated);
+       static ex s = dynallocate<symmetry>(symmetry::symmetric, index0(), index1());
        return ex_to<symmetry>(s);
 }
 
 const symmetry & symmetric3()
 {
-       static ex s = (new symmetry(symmetry::symmetric, index0(), index1()))->add(index2()).setflag(status_flags::dynallocated);
+       static ex s = dynallocate<symmetry>(symmetry::symmetric, index0(), index1()).add(index2());
        return ex_to<symmetry>(s);
 }
 
 const symmetry & symmetric4()
 {
-       static ex s = (new symmetry(symmetry::symmetric, index0(), index1()))->add(index2()).add(index3()).setflag(status_flags::dynallocated);
+       static ex s = dynallocate<symmetry>(symmetry::symmetric, index0(), index1()).add(index2()).add(index3());
        return ex_to<symmetry>(s);
 }
 
 const symmetry & antisymmetric2()
 {
-       static ex s = (new symmetry(symmetry::antisymmetric, index0(), index1()))->setflag(status_flags::dynallocated);
+       static ex s = dynallocate<symmetry>(symmetry::antisymmetric, index0(), index1());
        return ex_to<symmetry>(s);
 }
 
 const symmetry & antisymmetric3()
 {
-       static ex s = (new symmetry(symmetry::antisymmetric, index0(), index1()))->add(index2()).setflag(status_flags::dynallocated);
+       static ex s = dynallocate<symmetry>(symmetry::antisymmetric, index0(), index1()).add(index2());
        return ex_to<symmetry>(s);
 }
 
 const symmetry & antisymmetric4()
 {
-       static ex s = (new symmetry(symmetry::antisymmetric, index0(), index1()))->add(index2()).add(index3()).setflag(status_flags::dynallocated);
+       static ex s = dynallocate<symmetry>(symmetry::antisymmetric, index0(), index1()).add(index2()).add(index3());
        return ex_to<symmetry>(s);
 }
 
@@ -513,7 +513,7 @@ static ex symm(const ex & e, exvector::const_iterator first, exvector::const_ite
                }
                sum_v.push_back(term);
        }
-       ex sum = (new add(sum_v))->setflag(status_flags::dynallocated);
+       ex sum = dynallocate<add>(sum_v);
 
        delete[] iv;
        delete[] iv2;
index 0a57ae56b7916a12722808eeb4f08b1f2e9c306a..5f2c5506f15e0265e6e0a75fdb5eca27d9661efa 100644 (file)
@@ -576,7 +576,7 @@ bool tensepsilon::contract_with(exvector::iterator self, exvector::iterator othe
 
 ex delta_tensor(const ex & i1, const ex & i2)
 {
-       static ex delta = (new tensdelta)->setflag(status_flags::dynallocated);
+       static ex delta = dynallocate<tensdelta>();
 
        if (!is_a<idx>(i1) || !is_a<idx>(i2))
                throw(std::invalid_argument("indices of delta tensor must be of type idx"));
@@ -586,7 +586,7 @@ ex delta_tensor(const ex & i1, const ex & i2)
 
 ex metric_tensor(const ex & i1, const ex & i2)
 {
-       static ex metric = (new tensmetric)->setflag(status_flags::dynallocated);
+       static ex metric = dynallocate<tensmetric>();
 
        if (!is_a<varidx>(i1) || !is_a<varidx>(i2))
                throw(std::invalid_argument("indices of metric tensor must be of type varidx"));
@@ -596,8 +596,8 @@ ex metric_tensor(const ex & i1, const ex & i2)
 
 ex lorentz_g(const ex & i1, const ex & i2, bool pos_sig)
 {
-       static ex metric_neg = (new minkmetric(false))->setflag(status_flags::dynallocated);
-       static ex metric_pos = (new minkmetric(true))->setflag(status_flags::dynallocated);
+       static ex metric_neg = dynallocate<minkmetric>(false);
+       static ex metric_pos = dynallocate<minkmetric>(true);
 
        if (!is_a<varidx>(i1) || !is_a<varidx>(i2))
                throw(std::invalid_argument("indices of metric tensor must be of type varidx"));
@@ -607,7 +607,7 @@ ex lorentz_g(const ex & i1, const ex & i2, bool pos_sig)
 
 ex spinor_metric(const ex & i1, const ex & i2)
 {
-       static ex metric = (new spinmetric)->setflag(status_flags::dynallocated);
+       static ex metric = dynallocate<spinmetric>();
 
        if (!is_a<spinidx>(i1) || !is_a<spinidx>(i2))
                throw(std::invalid_argument("indices of spinor metric must be of type spinidx"));
@@ -619,7 +619,7 @@ ex spinor_metric(const ex & i1, const ex & i2)
 
 ex epsilon_tensor(const ex & i1, const ex & i2)
 {
-       static ex epsilon = (new tensepsilon)->setflag(status_flags::dynallocated);
+       static ex epsilon = dynallocate<tensepsilon>();
 
        if (!is_a<idx>(i1) || !is_a<idx>(i2))
                throw(std::invalid_argument("indices of epsilon tensor must be of type idx"));
@@ -638,7 +638,7 @@ ex epsilon_tensor(const ex & i1, const ex & i2)
 
 ex epsilon_tensor(const ex & i1, const ex & i2, const ex & i3)
 {
-       static ex epsilon = (new tensepsilon)->setflag(status_flags::dynallocated);
+       static ex epsilon = dynallocate<tensepsilon>();
 
        if (!is_a<idx>(i1) || !is_a<idx>(i2) || !is_a<idx>(i3))
                throw(std::invalid_argument("indices of epsilon tensor must be of type idx"));
@@ -657,8 +657,8 @@ ex epsilon_tensor(const ex & i1, const ex & i2, const ex & i3)
 
 ex lorentz_eps(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool pos_sig)
 {
-       static ex epsilon_neg = (new tensepsilon(true, false))->setflag(status_flags::dynallocated);
-       static ex epsilon_pos = (new tensepsilon(true, true))->setflag(status_flags::dynallocated);
+       static ex epsilon_neg = dynallocate<tensepsilon>(true, false);
+       static ex epsilon_pos = dynallocate<tensepsilon>(true, true);
 
        if (!is_a<varidx>(i1) || !is_a<varidx>(i2) || !is_a<varidx>(i3) || !is_a<varidx>(i4))
                throw(std::invalid_argument("indices of Lorentz epsilon tensor must be of type varidx"));
index f0029d1230beda254f83a244f0dd304b91842de0..374e22637223864cd05e682112cba68af31c9acf 100644 (file)
@@ -264,56 +264,56 @@ const ex _ex120 = _ex120;
 library_init::library_init()
 {
        if (count++==0) {
-               (_num_120_p = new numeric(-120))->setflag(status_flags::dynallocated);
-               (_num_60_p = new numeric(-60))->setflag(status_flags::dynallocated);
-               (_num_48_p = new numeric(-48))->setflag(status_flags::dynallocated);
-               (_num_30_p = new numeric(-30))->setflag(status_flags::dynallocated);
-               (_num_25_p = new numeric(-25))->setflag(status_flags::dynallocated);
-               (_num_24_p = new numeric(-24))->setflag(status_flags::dynallocated);
-               (_num_20_p = new numeric(-20))->setflag(status_flags::dynallocated);
-               (_num_18_p = new numeric(-18))->setflag(status_flags::dynallocated);
-               (_num_15_p = new numeric(-15))->setflag(status_flags::dynallocated);
-               (_num_12_p = new numeric(-12))->setflag(status_flags::dynallocated);
-               (_num_11_p = new numeric(-11))->setflag(status_flags::dynallocated);
-               (_num_10_p = new numeric(-10))->setflag(status_flags::dynallocated);
-               (_num_9_p = new numeric(-9))->setflag(status_flags::dynallocated);
-               (_num_8_p = new numeric(-8))->setflag(status_flags::dynallocated);
-               (_num_7_p = new numeric(-7))->setflag(status_flags::dynallocated);
-               (_num_6_p = new numeric(-6))->setflag(status_flags::dynallocated);
-               (_num_5_p = new numeric(-5))->setflag(status_flags::dynallocated);
-               (_num_4_p = new numeric(-4))->setflag(status_flags::dynallocated);
-               (_num_3_p = new numeric(-3))->setflag(status_flags::dynallocated);
-               (_num_2_p = new numeric(-2))->setflag(status_flags::dynallocated);
-               (_num_1_p = new numeric(-1))->setflag(status_flags::dynallocated);
-               (_num_1_2_p = new numeric(-1,2))->setflag(status_flags::dynallocated);
-               (_num_1_3_p = new numeric(-1,3))->setflag(status_flags::dynallocated);
-               (_num_1_4_p = new numeric(-1,4))->setflag(status_flags::dynallocated);
-               (_num0_p = new numeric(0))->setflag(status_flags::dynallocated);
+               _num_120_p = (const numeric *)&dynallocate<numeric>(-120);
+               _num_60_p = (const numeric *)&dynallocate<numeric>(-60);
+               _num_48_p = (const numeric *)&dynallocate<numeric>(-48);
+               _num_30_p = (const numeric *)&dynallocate<numeric>(-30);
+               _num_25_p = (const numeric *)&dynallocate<numeric>(-25);
+               _num_24_p = (const numeric *)&dynallocate<numeric>(-24);
+               _num_20_p = (const numeric *)&dynallocate<numeric>(-20);
+               _num_18_p = (const numeric *)&dynallocate<numeric>(-18);
+               _num_15_p = (const numeric *)&dynallocate<numeric>(-15);
+               _num_12_p = (const numeric *)&dynallocate<numeric>(-12);
+               _num_11_p = (const numeric *)&dynallocate<numeric>(-11);
+               _num_10_p = (const numeric *)&dynallocate<numeric>(-10);
+               _num_9_p = (const numeric *)&dynallocate<numeric>(-9);
+               _num_8_p = (const numeric *)&dynallocate<numeric>(-8);
+               _num_7_p = (const numeric *)&dynallocate<numeric>(-7);
+               _num_6_p = (const numeric *)&dynallocate<numeric>(-6);
+               _num_5_p = (const numeric *)&dynallocate<numeric>(-5);
+               _num_4_p = (const numeric *)&dynallocate<numeric>(-4);
+               _num_3_p = (const numeric *)&dynallocate<numeric>(-3);
+               _num_2_p = (const numeric *)&dynallocate<numeric>(-2);
+               _num_1_p = (const numeric *)&dynallocate<numeric>(-1);
+               _num_1_2_p = (const numeric *)&dynallocate<numeric>(-1,2);
+               _num_1_3_p = (const numeric *)&dynallocate<numeric>(-1,3);
+               _num_1_4_p = (const numeric *)&dynallocate<numeric>(-1,4);
+               _num0_p = (const numeric *)&dynallocate<numeric>(0);
                _num0_bp  = _num0_p;  // Cf. class ex default ctor.
-               (_num1_4_p = new numeric(1,4))->setflag(status_flags::dynallocated);
-               (_num1_3_p = new numeric(1,3))->setflag(status_flags::dynallocated);
-               (_num1_2_p = new numeric(1,2))->setflag(status_flags::dynallocated);
-               (_num1_p = new numeric(1))->setflag(status_flags::dynallocated);
-               (_num2_p = new numeric(2))->setflag(status_flags::dynallocated);
-               (_num3_p = new numeric(3))->setflag(status_flags::dynallocated);
-               (_num4_p = new numeric(4))->setflag(status_flags::dynallocated);
-               (_num5_p = new numeric(5))->setflag(status_flags::dynallocated);
-               (_num6_p = new numeric(6))->setflag(status_flags::dynallocated);
-               (_num7_p = new numeric(7))->setflag(status_flags::dynallocated);
-               (_num8_p = new numeric(8))->setflag(status_flags::dynallocated);
-               (_num9_p = new numeric(9))->setflag(status_flags::dynallocated);
-               (_num10_p = new numeric(10))->setflag(status_flags::dynallocated);
-               (_num11_p = new numeric(11))->setflag(status_flags::dynallocated);
-               (_num12_p = new numeric(12))->setflag(status_flags::dynallocated);
-               (_num15_p = new numeric(15))->setflag(status_flags::dynallocated);
-               (_num18_p = new numeric(18))->setflag(status_flags::dynallocated);
-               (_num20_p = new numeric(20))->setflag(status_flags::dynallocated);
-               (_num24_p = new numeric(24))->setflag(status_flags::dynallocated);
-               (_num25_p = new numeric(25))->setflag(status_flags::dynallocated);
-               (_num30_p = new numeric(30))->setflag(status_flags::dynallocated);
-               (_num48_p = new numeric(48))->setflag(status_flags::dynallocated);
-               (_num60_p = new numeric(60))->setflag(status_flags::dynallocated);
-               (_num120_p = new numeric(120))->setflag(status_flags::dynallocated);
+               _num1_4_p = (const numeric *)&dynallocate<numeric>(1,4);
+               _num1_3_p = (const numeric *)&dynallocate<numeric>(1,3);
+               _num1_2_p = (const numeric *)&dynallocate<numeric>(1,2);
+               _num1_p = (const numeric *)&dynallocate<numeric>(1);
+               _num2_p = (const numeric *)&dynallocate<numeric>(2);
+               _num3_p = (const numeric *)&dynallocate<numeric>(3);
+               _num4_p = (const numeric *)&dynallocate<numeric>(4);
+               _num5_p = (const numeric *)&dynallocate<numeric>(5);
+               _num6_p = (const numeric *)&dynallocate<numeric>(6);
+               _num7_p = (const numeric *)&dynallocate<numeric>(7);
+               _num8_p = (const numeric *)&dynallocate<numeric>(8);
+               _num9_p = (const numeric *)&dynallocate<numeric>(9);
+               _num10_p = (const numeric *)&dynallocate<numeric>(10);
+               _num11_p = (const numeric *)&dynallocate<numeric>(11);
+               _num12_p = (const numeric *)&dynallocate<numeric>(12);
+               _num15_p = (const numeric *)&dynallocate<numeric>(15);
+               _num18_p = (const numeric *)&dynallocate<numeric>(18);
+               _num20_p = (const numeric *)&dynallocate<numeric>(20);
+               _num24_p = (const numeric *)&dynallocate<numeric>(24);
+               _num25_p = (const numeric *)&dynallocate<numeric>(25);
+               _num30_p = (const numeric *)&dynallocate<numeric>(30);
+               _num48_p = (const numeric *)&dynallocate<numeric>(48);
+               _num60_p = (const numeric *)&dynallocate<numeric>(60);
+               _num120_p = (const numeric *)&dynallocate<numeric>(120);
 
                new((void*)&_ex_120) ex(*_num_120_p);
                new((void*)&_ex_60) ex(*_num_60_p);