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 bed95aa..754deea 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 7415dae..ed210e0 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 a32ae80..978757f 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 01d3697..96cfd14 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 b629f06..a8062c1 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 4b3c079..f500626 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 dcc106d..0f7723e 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 6482830..7bd8410 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 44031d4..84b756f 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 7030bca..00e4b2a 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 d75e132..e0a9073 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 675dd7c..ca4beff 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 cff14f4..850ed04 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 d7fa377..dd84418 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 016be2c..81e7ade 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 50f4631..7d054cf 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 c899ee1..48d6478 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 9ad55c5..c287a02 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 c362a43..ccf11e8 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 c86369f..2bb9265 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 85d13af..4cb57ec 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 b506ad8..aad3a71 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 c06b16e..9ff206e 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 5caea0e..6407caf 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 810b594..1daf576 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 1a452e3..2aedc9b 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 0d8eb49..1662ee0 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 12b57d6..08809fd 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 5e2b0e4..f2f7e61 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 c5b42d3..479522c 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 68b747e..84320f2 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 1467003..20aa913 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 0a57ae5..5f2c550 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 f0029d1..374e226 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);