* Supplement some (now deprecated) macros by inlined template functions:
authorRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Sat, 16 Jun 2001 18:35:50 +0000 (18:35 +0000)
committerRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Sat, 16 Jun 2001 18:35:50 +0000 (18:35 +0000)
  - ex_to_foobar(baz)  ->  ex_to<foobar>(baz).

47 files changed:
check/check_numeric.cpp
check/exam_numeric.cpp
check/exam_pseries.cpp
check/time_lw_M1.cpp
check/time_lw_M2.cpp
ginac/add.cpp
ginac/add.h
ginac/basic.h
ginac/clifford.cpp
ginac/clifford.h
ginac/color.cpp
ginac/color.h
ginac/constant.h
ginac/container.pl
ginac/expairseq.cpp
ginac/expairseq.h
ginac/function.pl
ginac/idx.cpp
ginac/idx.h
ginac/indexed.cpp
ginac/indexed.h
ginac/inifcns.cpp
ginac/inifcns_gamma.cpp
ginac/inifcns_trans.cpp
ginac/inifcns_zeta.cpp
ginac/matrix.cpp
ginac/matrix.h
ginac/mul.cpp
ginac/mul.h
ginac/ncmul.cpp
ginac/ncmul.h
ginac/normal.cpp
ginac/numeric.h
ginac/power.cpp
ginac/power.h
ginac/pseries.cpp
ginac/relational.cpp
ginac/relational.h
ginac/structure.pl
ginac/symbol.cpp
ginac/symbol.h
ginac/symmetry.cpp
ginac/symmetry.h
ginac/tensor.cpp
ginac/tensor.h
ginac/wildcard.h
ginsh/ginsh_parser.yy

index 17bfbae..3c56935 100644 (file)
@@ -81,7 +81,7 @@ static unsigned check_numeric2(void)
                                     << radical << endl;
                                errorflag = true;
                        }
-                       numeric ratio = ex_to_numeric(evalf(radical))/floating;
+                       numeric ratio = ex_to<numeric>(evalf(radical))/floating;
                        if (ratio>1.0001 && ratio<0.9999) {
                                clog << "(" << num << "/" << den << ")^(" << nm
                                     << ") erroneously evaluated to " << radical;
index fd1bf87..7a7c603 100644 (file)
@@ -79,7 +79,7 @@ static unsigned exam_numeric1(void)
        }
        
        e2 = test_int1 + a;
-       if (ex_to_numeric(e2).is_integer()) {
+       if (ex_to<numeric>(e2).is_integer()) {
                clog << "expression " << e2
                     << " erroneously recognized as integer" << endl;
                ++result;
index 4e4b397..9a1aaff 100644 (file)
@@ -27,7 +27,7 @@ static symbol x("x");
 static unsigned check_series(const ex &e, const ex &point, const ex &d, int order = 8)
 {
        ex es = e.series(x==point, order);
-       ex ep = ex_to_pseries(es).convert_to_poly();
+       ex ep = ex_to<pseries>(es).convert_to_poly();
        if (!(ep - d).is_zero()) {
                clog << "series expansion of " << e << " at " << point
                     << " erroneously returned " << ep << " (instead of " << d
index 961fe2a..122a579 100644 (file)
@@ -59,7 +59,7 @@ static unsigned test(void)
        for (unsigned r=0; r<26; ++r) {
                for (unsigned c=0; c<5; ++c) {
                        m.set(r,
-                             unsigned(ex_to_numeric(w[r][2*c+1]).to_int()-1),
+                             unsigned(ex_to<numeric>(w[r][2*c+1]).to_int()-1),
                              w[r][2*c+2]);
                }
        }
index fcd587f..8984250 100644 (file)
@@ -137,7 +137,7 @@ static unsigned test(void)
        for (unsigned r=0; r<101; ++r) {
                for (unsigned c=0; c<10; ++c) {
                        m.set(r,
-                             unsigned(ex_to_numeric(w[r][2*c+1]).to_int()-1),
+                             unsigned(ex_to<numeric>(w[r][2*c+1]).to_int()-1),
                              w[r][2*c+2]);
                }
        }
index 331f204..647de17 100644 (file)
@@ -135,15 +135,15 @@ void add::print(const print_context & c, unsigned level) const
                        } else if (it->coeff.compare(_num_1()) == 0) {
                                c.s << "-";
                                it->rest.bp->print(c, precedence());
-                       } else if (ex_to_numeric(it->coeff).numer().compare(_num1()) == 0) {
+                       } else if (ex_to<numeric>(it->coeff).numer().compare(_num1()) == 0) {
                                it->rest.bp->print(c, precedence());
                                c.s << "/";
-                               ex_to_numeric(it->coeff).denom().print(c, precedence());
-                       } else if (ex_to_numeric(it->coeff).numer().compare(_num_1()) == 0) {
+                               ex_to<numeric>(it->coeff).denom().print(c, precedence());
+                       } else if (ex_to<numeric>(it->coeff).numer().compare(_num_1()) == 0) {
                                c.s << "-";
                                it->rest.bp->print(c, precedence());
                                c.s << "/";
-                               ex_to_numeric(it->coeff).denom().print(c, precedence());
+                               ex_to<numeric>(it->coeff).denom().print(c, precedence());
                        } else {
                                it->coeff.bp->print(c, precedence());
                                c.s << "*";
@@ -189,7 +189,7 @@ void add::print(const print_context & c, unsigned level) const
                // Then proceed with the remaining factors
                epvector::const_iterator it = seq.begin(), itend = seq.end();
                while (it != itend) {
-                       coeff = ex_to_numeric(it->coeff);
+                       coeff = ex_to<numeric>(it->coeff);
                        if (!first) {
                                if (coeff.csgn() == -1) c.s << '-'; else c.s << '+';
                        } else {
@@ -354,10 +354,10 @@ ex add::evalm(void) const
                s->push_back(split_ex_to_pair(m));
                if (is_ex_of_type(m, matrix)) {
                        if (first_term) {
-                               sum = ex_to_matrix(m);
+                               sum = ex_to<matrix>(m);
                                first_term = false;
                        } else
-                               sum = sum.add(ex_to_matrix(m));
+                               sum = sum.add(ex_to<matrix>(m));
                } else
                        all_matrices = false;
                it++;
@@ -426,8 +426,8 @@ ex add::thisexpairseq(epvector * vp, const ex & oc) const
 expair add::split_ex_to_pair(const ex & e) const
 {
        if (is_ex_exactly_of_type(e,mul)) {
-               const mul &mulref = ex_to_mul(e);
-               ex numfactor(mulref.overall_coeff);
+               const mul &mulref(ex_to<mul>(e));
+               ex numfactor = mulref.overall_coeff;
                mul *mulcopyp = new mul(mulref);
                mulcopyp->overall_coeff = _ex1();
                mulcopyp->clearflag(status_flags::evaluated);
@@ -443,8 +443,8 @@ expair add::combine_ex_with_coeff_to_pair(const ex & e,
 {
        GINAC_ASSERT(is_ex_exactly_of_type(c, numeric));
        if (is_ex_exactly_of_type(e, mul)) {
-               const mul &mulref = ex_to_mul(e);
-               ex numfactor(mulref.overall_coeff);
+               const mul &mulref(ex_to<mul>(e));
+               ex numfactor = mulref.overall_coeff;
                mul *mulcopyp = new mul(mulref);
                mulcopyp->overall_coeff = _ex1();
                mulcopyp->clearflag(status_flags::evaluated);
@@ -455,11 +455,11 @@ expair add::combine_ex_with_coeff_to_pair(const ex & e,
                else if (are_ex_trivially_equal(numfactor, _ex1()))
                        return expair(*mulcopyp, c);
                else
-                       return expair(*mulcopyp, ex_to_numeric(numfactor).mul_dyn(ex_to_numeric(c)));
+                       return expair(*mulcopyp, ex_to<numeric>(numfactor).mul_dyn(ex_to<numeric>(c)));
        } else if (is_ex_exactly_of_type(e, numeric)) {
                if (are_ex_trivially_equal(c, _ex1()))
                        return expair(e, _ex1());
-               return expair(ex_to_numeric(e).mul_dyn(ex_to_numeric(c)), _ex1());
+               return expair(ex_to<numeric>(e).mul_dyn(ex_to<numeric>(c)), _ex1());
        }
        return expair(e, c);
 }
@@ -471,16 +471,16 @@ expair add::combine_pair_with_coeff_to_pair(const expair & p,
        GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
 
        if (is_ex_exactly_of_type(p.rest,numeric)) {
-               GINAC_ASSERT(ex_to_numeric(p.coeff).is_equal(_num1())); // should be normalized
-               return expair(ex_to_numeric(p.rest).mul_dyn(ex_to_numeric(c)),_ex1());
+               GINAC_ASSERT(ex_to<numeric>(p.coeff).is_equal(_num1())); // should be normalized
+               return expair(ex_to<numeric>(p.rest).mul_dyn(ex_to<numeric>(c)),_ex1());
        }
 
-       return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c)));
+       return expair(p.rest,ex_to<numeric>(p.coeff).mul_dyn(ex_to<numeric>(c)));
 }
        
 ex add::recombine_pair_to_ex(const expair & p) const
 {
-       if (ex_to_numeric(p.coeff).is_equal(_num1()))
+       if (ex_to<numeric>(p.coeff).is_equal(_num1()))
                return p.rest;
        else
                return p.rest*p.coeff;
index e04474f..c0dfca5 100644 (file)
@@ -79,7 +79,7 @@ protected:
 
 // utility functions
 
-/** Return the add object handled by an ex.
+/** Return the add object handled by an ex.  Deprecated: use ex_to<add>().
  *  This is unsafe: you need to check the type first. */
 inline const add &ex_to_add(const ex &e)
 {
index 78ceb54..f53a4e3 100644 (file)
@@ -196,24 +196,45 @@ extern int max_recursion_level;
 /** Check if obj is a T, including base classes. */
 template <class T>
 inline bool is_a(const basic & obj)
-{ return dynamic_cast<const T *>(&obj)!=0; }
+{
+       return dynamic_cast<const T *>(&obj)!=0;
+}
 
 /** Check if obj is a T, not including base classes.  This one is just an
  *  inefficient default.  It should in all time-critical cases be overridden
  *  by template specializations that don't create a temporary. */
 template <class T>
 inline bool is_exactly_a(const class basic & obj)
-{ const T foo; return foo.tinfo()==obj.tinfo(); }
+{
+       const T foo; return foo.tinfo()==obj.tinfo();
+}
 
 /** Check if ex is a handle to a T, including base classes. */
 template <class T>
 inline bool is_a(const ex & obj)
-{ return is_a<T>(*obj.bp); }
+{
+       return is_a<T>(*obj.bp);
+}
 
 /** Check if ex is a handle to a T, not including base classes. */
 template <class T>
 inline bool is_exactly_a(const ex & obj)
-{ return is_exactly_a<T>(*obj.bp); }
+{
+       return is_exactly_a<T>(*obj.bp);
+}
+
+/** Return a reference to the basic-derived class T object embedded in an
+ *  expression.  This is fast but unsafe: the result is undefined if the
+ *  expression does not contain a T object at its top level.
+ *
+ *  @param e expression
+ *  @return reference to pseries object
+ *  @see is_exactly_a<class T>() */
+template <class T>
+inline const T &ex_to(const ex &e)
+{
+       return static_cast<const T &>(*e.bp);
+}
 
 } // namespace GiNaC
 
index c985bd8..7446592 100644 (file)
@@ -153,11 +153,11 @@ bool diracgamma::contract_with(exvector::iterator self, exvector::iterator other
        GINAC_ASSERT(is_ex_of_type(*self, clifford));
        GINAC_ASSERT(is_ex_of_type(*other, indexed));
        GINAC_ASSERT(is_ex_of_type(self->op(0), diracgamma));
-       unsigned char rl = ex_to_clifford(*self).get_representation_label();
+       unsigned char rl = ex_to<clifford>(*self).get_representation_label();
 
        if (is_ex_of_type(*other, clifford)) {
 
-               ex dim = ex_to_idx(self->op(1)).get_dim();
+               ex dim = ex_to<idx>(self->op(1)).get_dim();
 
                // gamma~mu gamma.mu = dim ONE
                if (other - self == 1) {
@@ -386,7 +386,7 @@ ex dirac_trace(const ex & e, unsigned char rl, const ex & trONE)
 {
        if (is_ex_of_type(e, clifford)) {
 
-               if (ex_to_clifford(e).get_representation_label() == rl
+               if (ex_to<clifford>(e).get_representation_label() == rl
                 && is_ex_of_type(e.op(0), diracone))
                        return trONE;
                else
index 9d429dc..0233ba0 100644 (file)
@@ -102,7 +102,7 @@ public:
 
 // global functions
 
-/** Return the clifford object handled by an ex.
+/** Return the clifford object handled by an ex.  Deprecated: use ex_to<clifford>().
  *  This is unsafe: you need to check the type first. */
 inline const clifford &ex_to_clifford(const ex &e)
 {
index a3876f3..45521b7 100644 (file)
@@ -229,7 +229,7 @@ ex su3d::eval_indexed(const basic & i) const
                // Sort indices
                int v[3];
                for (unsigned j=0; j<3; j++)
-                       v[j] = ex_to_numeric(ex_to_idx(i.op(j + 1)).get_value()).to_int();
+                       v[j] = ex_to<numeric>(ex_to<idx>(i.op(j + 1)).get_value()).to_int();
                if (v[0] > v[1]) std::swap(v[0], v[1]);
                if (v[0] > v[2]) std::swap(v[0], v[2]);
                if (v[1] > v[2]) std::swap(v[1], v[2]);
@@ -270,7 +270,7 @@ ex su3f::eval_indexed(const basic & i) const
                // Sort indices, remember permutation sign
                int v[3];
                for (unsigned j=0; j<3; j++)
-                       v[j] = ex_to_numeric(ex_to_idx(i.op(j + 1)).get_value()).to_int();
+                       v[j] = ex_to<numeric>(ex_to<idx>(i.op(j + 1)).get_value()).to_int();
                int sign = 1;
                if (v[0] > v[1]) { std::swap(v[0], v[1]); sign = -sign; }
                if (v[0] > v[2]) { std::swap(v[0], v[2]); sign = -sign; }
@@ -302,7 +302,7 @@ bool su3t::contract_with(exvector::iterator self, exvector::iterator other, exve
        GINAC_ASSERT(is_ex_of_type(*other, indexed));
        GINAC_ASSERT(self->nops() == 2);
        GINAC_ASSERT(is_ex_of_type(self->op(0), su3t));
-       unsigned char rl = ex_to_color(*self).get_representation_label();
+       unsigned char rl = ex_to<color>(*self).get_representation_label();
 
        if (is_ex_exactly_of_type(other->op(0), su3t)) {
 
@@ -356,8 +356,8 @@ bool su3d::contract_with(exvector::iterator self, exvector::iterator other, exve
        if (is_ex_exactly_of_type(other->op(0), su3d)) {
 
                // Find the dummy indices of the contraction
-               exvector self_indices = ex_to_indexed(*self).get_indices();
-               exvector other_indices = ex_to_indexed(*other).get_indices();
+               exvector self_indices = ex_to<indexed>(*self).get_indices();
+               exvector other_indices = ex_to<indexed>(*other).get_indices();
                exvector all_indices = self_indices;
                all_indices.insert(all_indices.end(), other_indices.begin(), other_indices.end());
                exvector free_indices, dummy_indices;
@@ -386,16 +386,16 @@ bool su3d::contract_with(exvector::iterator self, exvector::iterator other, exve
                // d.abc T.b T.c = 5/6 T.a
                if (other+1 != v.end()
                 && is_ex_exactly_of_type(other[1].op(0), su3t)
-                && ex_to_indexed(*self).has_dummy_index_for(other[1].op(1))) {
+                && ex_to<indexed>(*self).has_dummy_index_for(other[1].op(1))) {
 
-                       exvector self_indices = ex_to_indexed(*self).get_indices();
+                       exvector self_indices = ex_to<indexed>(*self).get_indices();
                        exvector dummy_indices;
                        dummy_indices.push_back(other[0].op(1));
                        dummy_indices.push_back(other[1].op(1));
                        int sig;
                        ex a = permute_free_index_to_front(self_indices, dummy_indices, sig);
                        *self = numeric(5, 6);
-                       other[0] = color_T(a, ex_to_color(other[0]).get_representation_label());
+                       other[0] = color_T(a, ex_to<color>(other[0]).get_representation_label());
                        other[1] = _ex1();
                        return true;
                }
@@ -416,7 +416,7 @@ bool su3f::contract_with(exvector::iterator self, exvector::iterator other, exve
 
                // Find the dummy indices of the contraction
                exvector dummy_indices;
-               dummy_indices = ex_to_indexed(*self).get_dummy_indices(ex_to_indexed(*other));
+               dummy_indices = ex_to<indexed>(*self).get_dummy_indices(ex_to<indexed>(*other));
 
                // f.abc f.abc = 24
                if (dummy_indices.size() == 3) {
@@ -427,8 +427,8 @@ bool su3f::contract_with(exvector::iterator self, exvector::iterator other, exve
                // f.akl f.bkl = 3 delta.ab
                } else if (dummy_indices.size() == 2) {
                        int sign1, sign2;
-                       ex a = permute_free_index_to_front(ex_to_indexed(*self).get_indices(), dummy_indices, sign1);
-                       ex b = permute_free_index_to_front(ex_to_indexed(*other).get_indices(), dummy_indices, sign2);
+                       ex a = permute_free_index_to_front(ex_to<indexed>(*self).get_indices(), dummy_indices, sign1);
+                       ex b = permute_free_index_to_front(ex_to<indexed>(*other).get_indices(), dummy_indices, sign2);
                        *self = sign1 * sign2 * 3 * delta_tensor(a, b);
                        *other = _ex1();
                        return true;
@@ -439,16 +439,16 @@ bool su3f::contract_with(exvector::iterator self, exvector::iterator other, exve
                // f.abc T.b T.c = 3/2 I T.a
                if (other+1 != v.end()
                 && is_ex_exactly_of_type(other[1].op(0), su3t)
-                && ex_to_indexed(*self).has_dummy_index_for(other[1].op(1))) {
+                && ex_to<indexed>(*self).has_dummy_index_for(other[1].op(1))) {
 
-                       exvector self_indices = ex_to_indexed(*self).get_indices();
+                       exvector self_indices = ex_to<indexed>(*self).get_indices();
                        exvector dummy_indices;
                        dummy_indices.push_back(other[0].op(1));
                        dummy_indices.push_back(other[1].op(1));
                        int sig;
                        ex a = permute_free_index_to_front(self_indices, dummy_indices, sig);
                        *self = numeric(3, 2) * sig * I;
-                       other[0] = color_T(a, ex_to_color(other[0]).get_representation_label());
+                       other[0] = color_T(a, ex_to<color>(other[0]).get_representation_label());
                        other[1] = _ex1();
                        return true;
                }
@@ -470,7 +470,7 @@ ex color_T(const ex & a, unsigned char rl)
 {
        if (!is_ex_of_type(a, idx))
                throw(std::invalid_argument("indices of color_T must be of type idx"));
-       if (!ex_to_idx(a).get_dim().is_equal(8))
+       if (!ex_to<idx>(a).get_dim().is_equal(8))
                throw(std::invalid_argument("index dimension for color_T must be 8"));
 
        return color(su3t(), a, rl);
@@ -480,7 +480,7 @@ ex color_f(const ex & a, const ex & b, const ex & c)
 {
        if (!is_ex_of_type(a, idx) || !is_ex_of_type(b, idx) || !is_ex_of_type(c, idx))
                throw(std::invalid_argument("indices of color_f must be of type idx"));
-       if (!ex_to_idx(a).get_dim().is_equal(8) || !ex_to_idx(b).get_dim().is_equal(8) || !ex_to_idx(c).get_dim().is_equal(8))
+       if (!ex_to<idx>(a).get_dim().is_equal(8) || !ex_to<idx>(b).get_dim().is_equal(8) || !ex_to<idx>(c).get_dim().is_equal(8))
                throw(std::invalid_argument("index dimension for color_f must be 8"));
 
        return indexed(su3f(), sy_anti(), a, b, c);
@@ -490,7 +490,7 @@ ex color_d(const ex & a, const ex & b, const ex & c)
 {
        if (!is_ex_of_type(a, idx) || !is_ex_of_type(b, idx) || !is_ex_of_type(c, idx))
                throw(std::invalid_argument("indices of color_d must be of type idx"));
-       if (!ex_to_idx(a).get_dim().is_equal(8) || !ex_to_idx(b).get_dim().is_equal(8) || !ex_to_idx(c).get_dim().is_equal(8))
+       if (!ex_to<idx>(a).get_dim().is_equal(8) || !ex_to<idx>(b).get_dim().is_equal(8) || !ex_to<idx>(c).get_dim().is_equal(8))
                throw(std::invalid_argument("index dimension for color_d must be 8"));
 
        return indexed(su3d(), sy_symm(), a, b, c);
@@ -512,7 +512,7 @@ ex color_trace(const ex & e, unsigned char rl)
 {
        if (is_ex_of_type(e, color)) {
 
-               if (ex_to_color(e).get_representation_label() == rl
+               if (ex_to<color>(e).get_representation_label() == rl
                 && is_ex_of_type(e.op(0), su3one))
                        return _ex3();
                else
index 0916bdf..c0eb614 100644 (file)
@@ -116,7 +116,7 @@ public:
 
 // global functions
 
-/** Return the color object handled by an ex.
+/** Return the color object handled by an ex.  Deprecated: use ex_to<color>().
  *  This is unsafe: you need to check the type first. */
 inline const color &ex_to_color(const ex &e)
 {
index 4c92876..160b7ac 100644 (file)
@@ -81,7 +81,7 @@ extern const constant Euler;
 
 // utility functions
 
-/** Return the constant object handled by an ex.
+/** Return the constant object handled by an ex.  Deprecated: use ex_to<constant>().
  *  This is unsafe: you need to check the type first. */
 inline const constant &ex_to_constant(const ex &e)
 {
index 843421e..6db886c 100755 (executable)
@@ -247,7 +247,7 @@ protected:
 
 // utility functions
 
-/** Return the ${CONTAINER} object handled by an ex.
+/** Return the ${CONTAINER} object handled by an ex.  Deprecated: use ex_to<${CONTAINER}>().
  *  This is unsafe: you need to check the type first. */
 inline const ${CONTAINER} &ex_to_${CONTAINER}(const ex &e)
 {
index 6370fc2..108d1e1 100644 (file)
@@ -679,7 +679,7 @@ expair expairseq::combine_pair_with_coeff_to_pair(const expair &p,
        GINAC_ASSERT(is_ex_exactly_of_type(p.coeff,numeric));
        GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
        
-       return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c)));
+       return expair(p.rest,ex_to<numeric>(p.coeff).mul_dyn(ex_to<numeric>(c)));
 }
 
 
@@ -707,7 +707,7 @@ void expairseq::combine_overall_coeff(const ex &c)
 {
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
        GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
-       overall_coeff = ex_to_numeric(overall_coeff).add_dyn(ex_to_numeric(c));
+       overall_coeff = ex_to<numeric>(overall_coeff).add_dyn(ex_to<numeric>(c));
 }
 
 void expairseq::combine_overall_coeff(const ex &c1, const ex &c2)
@@ -715,8 +715,8 @@ void expairseq::combine_overall_coeff(const ex &c1, const ex &c2)
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
        GINAC_ASSERT(is_ex_exactly_of_type(c1,numeric));
        GINAC_ASSERT(is_ex_exactly_of_type(c2,numeric));
-       overall_coeff = ex_to_numeric(overall_coeff).
-                       add_dyn(ex_to_numeric(c1).mul(ex_to_numeric(c2)));
+       overall_coeff = ex_to<numeric>(overall_coeff).
+                       add_dyn(ex_to<numeric>(c1).mul(ex_to<numeric>(c2)));
 }
 
 bool expairseq::can_make_flat(const expair &p) const
@@ -747,26 +747,26 @@ void expairseq::construct_from_2_ex(const ex &lh, const ex &rh)
        if (lh.bp->tinfo()==tinfo()) {
                if (rh.bp->tinfo()==tinfo()) {
 #if EXPAIRSEQ_USE_HASHTAB
-                       unsigned totalsize = ex_to_expairseq(lh).seq.size() +
-                                            ex_to_expairseq(rh).seq.size();
+                       unsigned totalsize = ex_to<expairseq>(lh).seq.size() +
+                                            ex_to<expairseq>(rh).seq.size();
                        if (calc_hashtabsize(totalsize)!=0) {
                                construct_from_2_ex_via_exvector(lh,rh);
                        } else {
 #endif // EXPAIRSEQ_USE_HASHTAB
-                               construct_from_2_expairseq(ex_to_expairseq(lh),
-                                                          ex_to_expairseq(rh));
+                               construct_from_2_expairseq(ex_to<expairseq>(lh),
+                                                          ex_to<expairseq>(rh));
 #if EXPAIRSEQ_USE_HASHTAB
                        }
 #endif // EXPAIRSEQ_USE_HASHTAB
                        return;
                } else {
 #if EXPAIRSEQ_USE_HASHTAB
-                       unsigned totalsize = ex_to_expairseq(lh).seq.size()+1;
+                       unsigned totalsize = ex_to<expairseq>(lh).seq.size()+1;
                        if (calc_hashtabsize(totalsize)!=0) {
                                construct_from_2_ex_via_exvector(lh, rh);
                        } else {
 #endif // EXPAIRSEQ_USE_HASHTAB
-                               construct_from_expairseq_ex(ex_to_expairseq(lh), rh);
+                               construct_from_expairseq_ex(ex_to<expairseq>(lh), rh);
 #if EXPAIRSEQ_USE_HASHTAB
                        }
 #endif // EXPAIRSEQ_USE_HASHTAB
@@ -774,12 +774,12 @@ void expairseq::construct_from_2_ex(const ex &lh, const ex &rh)
                }
        } else if (rh.bp->tinfo()==tinfo()) {
 #if EXPAIRSEQ_USE_HASHTAB
-               unsigned totalsize=ex_to_expairseq(rh).seq.size()+1;
+               unsigned totalsize=ex_to<expairseq>(rh).seq.size()+1;
                if (calc_hashtabsize(totalsize)!=0) {
                        construct_from_2_ex_via_exvector(lh,rh);
                } else {
 #endif // EXPAIRSEQ_USE_HASHTAB
-                       construct_from_expairseq_ex(ex_to_expairseq(rh),lh);
+                       construct_from_expairseq_ex(ex_to<expairseq>(rh),lh);
 #if EXPAIRSEQ_USE_HASHTAB
                }
 #endif // EXPAIRSEQ_USE_HASHTAB
@@ -812,8 +812,8 @@ void expairseq::construct_from_2_ex(const ex &lh, const ex &rh)
                        
                        int cmpval = p1.rest.compare(p2.rest);
                        if (cmpval==0) {
-                               p1.coeff=ex_to_numeric(p1.coeff).add_dyn(ex_to_numeric(p2.coeff));
-                               if (!ex_to_numeric(p1.coeff).is_zero()) {
+                               p1.coeff=ex_to<numeric>(p1.coeff).add_dyn(ex_to<numeric>(p2.coeff));
+                               if (!ex_to<numeric>(p1.coeff).is_zero()) {
                                        // no further processing is necessary, since this
                                        // one element will usually be recombined in eval()
                                        seq.push_back(p1);
@@ -851,8 +851,8 @@ void expairseq::construct_from_2_expairseq(const expairseq &s1,
                int cmpval = (*first1).rest.compare((*first2).rest);
                if (cmpval==0) {
                        // combine terms
-                       const numeric &newcoeff = ex_to_numeric((*first1).coeff).
-                                                  add(ex_to_numeric((*first2).coeff));
+                       const numeric &newcoeff = ex_to<numeric>((*first1).coeff).
+                                                  add(ex_to<numeric>((*first2).coeff));
                        if (!newcoeff.is_zero()) {
                                seq.push_back(expair((*first1).rest,newcoeff));
                                if (expair_needs_further_processing(seq.end()-1)) {
@@ -910,8 +910,8 @@ void expairseq::construct_from_expairseq_ex(const expairseq &s,
                int cmpval=(*first).rest.compare(p.rest);
                if (cmpval==0) {
                        // combine terms
-                       const numeric &newcoeff = ex_to_numeric((*first).coeff).
-                                                  add(ex_to_numeric(p.coeff));
+                       const numeric &newcoeff = ex_to<numeric>((*first).coeff).
+                                                  add(ex_to<numeric>(p.coeff));
                        if (!newcoeff.is_zero()) {
                                seq.push_back(expair((*first).rest,newcoeff));
                                if (expair_needs_further_processing(seq.end()-1)) {
@@ -998,7 +998,7 @@ void expairseq::make_flat(const exvector &v)
        while (cit!=v.end()) {
                if (cit->bp->tinfo()==this->tinfo()) {
                        ++nexpairseqs;
-                       noperands += ex_to_expairseq(*cit).seq.size();
+                       noperands += ex_to<expairseq>(*cit).seq.size();
                }
                ++cit;
        }
@@ -1010,7 +1010,7 @@ void expairseq::make_flat(const exvector &v)
        cit = v.begin();
        while (cit!=v.end()) {
                if (cit->bp->tinfo()==this->tinfo()) {
-                       const expairseq &subseqref = ex_to_expairseq(*cit);
+                       const expairseq &subseqref = ex_to<expairseq>(*cit);
                        combine_overall_coeff(subseqref.overall_coeff);
                        epvector::const_iterator cit_s = subseqref.seq.begin();
                        while (cit_s!=subseqref.seq.end()) {
@@ -1044,7 +1044,7 @@ void expairseq::make_flat(const epvector &v)
        while (cit!=v.end()) {
                if (cit->rest.bp->tinfo()==this->tinfo()) {
                        ++nexpairseqs;
-                       noperands += ex_to_expairseq((*cit).rest).seq.size();
+                       noperands += ex_to<expairseq>((*cit).rest).seq.size();
                }
                ++cit;
        }
@@ -1057,13 +1057,13 @@ void expairseq::make_flat(const epvector &v)
        while (cit!=v.end()) {
                if (cit->rest.bp->tinfo()==this->tinfo() &&
                    this->can_make_flat(*cit)) {
-                       const expairseq &subseqref = ex_to_expairseq((*cit).rest);
-                       combine_overall_coeff(ex_to_numeric(subseqref.overall_coeff),
-                                                           ex_to_numeric((*cit).coeff));
+                       const expairseq &subseqref = ex_to<expairseq>((*cit).rest);
+                       combine_overall_coeff(ex_to<numeric>(subseqref.overall_coeff),
+                                                           ex_to<numeric>((*cit).coeff));
                        epvector::const_iterator cit_s = subseqref.seq.begin();
                        while (cit_s!=subseqref.seq.end()) {
                                seq.push_back(expair((*cit_s).rest,
-                                                    ex_to_numeric((*cit_s).coeff).mul_dyn(ex_to_numeric((*cit).coeff))));
+                                                    ex_to<numeric>((*cit_s).coeff).mul_dyn(ex_to<numeric>((*cit).coeff))));
                                //seq.push_back(combine_pair_with_coeff_to_pair(*cit_s,
                                //                                              (*cit).coeff));
                                ++cit_s;
@@ -1105,13 +1105,13 @@ void expairseq::combine_same_terms_sorted_seq(void)
                bool must_copy = false;
                while (itin2!=last) {
                        if ((*itin1).rest.compare((*itin2).rest)==0) {
-                               (*itin1).coeff = ex_to_numeric((*itin1).coeff).
-                                                add_dyn(ex_to_numeric((*itin2).coeff));
+                               (*itin1).coeff = ex_to<numeric>((*itin1).coeff).
+                                                add_dyn(ex_to<numeric>((*itin2).coeff));
                                if (expair_needs_further_processing(itin1))
                                        needs_further_processing = true;
                                must_copy = true;
                        } else {
-                               if (!ex_to_numeric((*itin1).coeff).is_zero()) {
+                               if (!ex_to<numeric>((*itin1).coeff).is_zero()) {
                                        if (must_copy)
                                                *itout = *itin1;
                                        ++itout;
@@ -1120,7 +1120,7 @@ void expairseq::combine_same_terms_sorted_seq(void)
                        }
                        ++itin2;
                }
-               if (!ex_to_numeric((*itin1).coeff).is_zero()) {
+               if (!ex_to<numeric>((*itin1).coeff).is_zero()) {
                        if (must_copy)
                                *itout = *itin1;
                        ++itout;
@@ -1297,8 +1297,8 @@ void expairseq::build_hashtab_and_combine(epvector::iterator &first_numeric,
                                ++current;
                        } else {
                                // epplit points to a matching expair, combine it with current
-                               (*(*epplit)).coeff = ex_to_numeric((*(*epplit)).coeff).
-                                                    add_dyn(ex_to_numeric((*current).coeff));
+                               (*(*epplit)).coeff = ex_to<numeric>((*(*epplit)).coeff).
+                                                    add_dyn(ex_to<numeric>((*current).coeff));
                                
                                // move obsolete current expair to end by swapping with last_non_zero element
                                // if this was a numeric, it is swapped with the expair before first_numeric 
@@ -1327,7 +1327,7 @@ void expairseq::drop_coeff_0_terms(epvector::iterator &first_numeric,
                if (!touched[i]) {
                        ++current;
                        ++i;
-               } else if (!ex_to_numeric((*current).coeff).is_zero()) {
+               } else if (!ex_to<numeric>((*current).coeff).is_zero()) {
                        ++current;
                        ++i;
                } else {
index 9865586..8851a27 100644 (file)
@@ -189,7 +189,7 @@ protected:
 
 // utility functions
 
-/** Return the expairseq object handled by an ex.
+/** Return the expairseq object handled by an ex.  Deprecated: use ex_to<expairseq>().
  *  This is unsafe: you need to check the type first. */
 inline const expairseq &ex_to_expairseq(const ex &e)
 {
index cfb9e81..6854638 100755 (executable)
@@ -745,7 +745,7 @@ ex function::eval(int level) const
        if (seq.size() > 1 && !(opt.symtree.is_zero())) {
                exvector v = seq;
                GINAC_ASSERT(is_ex_exactly_of_type(opt.symtree, symmetry));
-               int sig = canonicalize(v.begin(), ex_to_symmetry(opt.symtree));
+               int sig = canonicalize(v.begin(), ex_to<symmetry>(opt.symtree));
                if (sig != INT_MAX) {
                        // Something has changed while sorting arguments, more evaluations later
                        if (sig == 0)
@@ -840,7 +840,7 @@ ${series_switch_statement}
 bool function::match(const ex & pattern, lst & repl_lst) const
 {
        // Serial number must match
-       if (is_ex_of_type(pattern, function) && serial != ex_to_function(pattern).serial)
+       if (is_ex_of_type(pattern, function) && serial != ex_to<function>(pattern).serial)
                return false;
        return inherited::match(pattern, repl_lst);
 }
@@ -868,7 +868,7 @@ ex function::derivative(const symbol & s) const
                for (unsigned i=0; i!=fcn.nops(); i++) {
                        arg_diff = fcn.op(i).diff(s);
                        if (!arg_diff.is_zero()) {
-                               lst new_lst = ex_to_lst(seq[1]);
+                               lst new_lst = ex_to<lst>(seq[1]);
                                new_lst.append(i);
                                result += arg_diff * Derivative(fcn, new_lst);
                        }
index e2b76be..df79607 100644 (file)
@@ -320,7 +320,7 @@ bool idx::match(const ex & pattern, lst & repl_lst) const
 {
        if (!is_ex_of_type(pattern, idx))
                return false;
-       const idx &o = ex_to_idx(pattern);
+       const idx &o = ex_to<idx>(pattern);
        if (!dim.is_equal(o.dim))
                return false;
        return value.match(o.value, repl_lst);
@@ -330,7 +330,7 @@ bool varidx::match(const ex & pattern, lst & repl_lst) const
 {
        if (!is_ex_of_type(pattern, varidx))
                return false;
-       const varidx &o = ex_to_varidx(pattern);
+       const varidx &o = ex_to<varidx>(pattern);
        if (covariant != o.covariant)
                return false;
        return inherited::match(pattern, repl_lst);
@@ -340,7 +340,7 @@ bool spinidx::match(const ex & pattern, lst & repl_lst) const
 {
        if (!is_ex_of_type(pattern, spinidx))
                return false;
-       const spinidx &o = ex_to_spinidx(pattern);
+       const spinidx &o = ex_to<spinidx>(pattern);
        if (dotted != o.dotted)
                return false;
        return inherited::match(pattern, repl_lst);
@@ -469,7 +469,7 @@ bool is_dummy_pair(const ex & e1, const ex & e2)
        if (!is_ex_of_type(e1, idx) || !is_ex_of_type(e2, idx))
                return false;
 
-       return is_dummy_pair(ex_to_idx(e1), ex_to_idx(e2));
+       return is_dummy_pair(ex_to<idx>(e1), ex_to<idx>(e2));
 }
 
 void find_free_and_dummy(exvector::const_iterator it, exvector::const_iterator itend, exvector & out_free, exvector & out_dummy)
@@ -483,7 +483,7 @@ void find_free_and_dummy(exvector::const_iterator it, exvector::const_iterator i
 
        // Only one index? Then it is a free one if it's not numeric
        if (itend - it == 1) {
-               if (ex_to_idx(*it).is_symbolic())
+               if (ex_to<idx>(*it).is_symbolic())
                        out_free.push_back(*it);
                return;
        }
@@ -503,12 +503,12 @@ void find_free_and_dummy(exvector::const_iterator it, exvector::const_iterator i
                        if (it == itend)
                                return;
                } else {
-                       if (!it->is_equal(*last) && ex_to_idx(*last).is_symbolic())
+                       if (!it->is_equal(*last) && ex_to<idx>(*last).is_symbolic())
                                out_free.push_back(*last);
                }
                last = it++;
        }
-       if (ex_to_idx(*last).is_symbolic())
+       if (ex_to<idx>(*last).is_symbolic())
                out_free.push_back(*last);
 }
 
index 92c685c..79b9209 100644 (file)
@@ -175,21 +175,21 @@ protected:
 
 // utility functions
 
-/** Return the idx object handled by an ex.
+/** Return the idx object handled by an ex.  Deprecated: use ex_to<idx>().
  *  This is unsafe: you need to check the type first. */
 inline const idx &ex_to_idx(const ex & e)
 {
        return static_cast<const idx &>(*e.bp);
 }
 
-/** Return the varidx object handled by an ex.
+/** Return the varidx object handled by an ex.  Deprecated: use ex_to<varidx>().
  *  This is unsafe: you need to check the type first. */
 inline const varidx &ex_to_varidx(const ex & e)
 {
        return static_cast<const varidx &>(*e.bp);
 }
 
-/** Return the spinidx object handled by an ex.
+/** Return the spinidx object handled by an ex.  Deprecated: use ex_to<spinidx>().
  *  This is unsafe: you need to check the type first. */
 inline const spinidx &ex_to_spinidx(const ex & e)
 {
index fd96eeb..459caa9 100644 (file)
@@ -235,7 +235,7 @@ bool indexed::info(unsigned inf) const
 
 struct idx_is_not : public std::binary_function<ex, unsigned, bool> {
        bool operator() (const ex & e, unsigned inf) const {
-               return !(ex_to_idx(e).get_value().info(inf));
+               return !(ex_to<idx>(e).get_value().info(inf));
        }
 };
 
@@ -259,7 +259,7 @@ ex indexed::eval(int level) const
 {
        // First evaluate children, then we will end up here again
        if (level > 1)
-               return indexed(ex_to_symmetry(symtree), evalchildren(level));
+               return indexed(ex_to<symmetry>(symtree), evalchildren(level));
 
        const ex &base = seq[0];
 
@@ -270,7 +270,7 @@ ex indexed::eval(int level) const
        // If the base object is a product, pull out the numeric factor
        if (is_ex_exactly_of_type(base, mul) && is_ex_exactly_of_type(base.op(base.nops() - 1), numeric)) {
                exvector v(seq);
-               ex f = ex_to_numeric(base.op(base.nops() - 1));
+               ex f = ex_to<numeric>(base.op(base.nops() - 1));
                v[0] = seq[0] / f;
                return f * thisexprseq(v);
        }
@@ -279,7 +279,7 @@ ex indexed::eval(int level) const
        if (seq.size() > 2) {
                exvector v = seq;
                GINAC_ASSERT(is_ex_exactly_of_type(symtree, symmetry));
-               int sig = canonicalize(v.begin() + 1, ex_to_symmetry(symtree));
+               int sig = canonicalize(v.begin() + 1, ex_to<symmetry>(symtree));
                if (sig != INT_MAX) {
                        // Something has changed while sorting indices, more evaluations later
                        if (sig == 0)
@@ -312,12 +312,12 @@ ex indexed::coeff(const ex & s, int n) const
 
 ex indexed::thisexprseq(const exvector & v) const
 {
-       return indexed(ex_to_symmetry(symtree), v);
+       return indexed(ex_to<symmetry>(symtree), v);
 }
 
 ex indexed::thisexprseq(exvector * vp) const
 {
-       return indexed(ex_to_symmetry(symtree), vp);
+       return indexed(ex_to<symmetry>(symtree), vp);
 }
 
 ex indexed::expand(unsigned options) const
@@ -363,7 +363,7 @@ void indexed::printindices(const print_context & c, unsigned level) const
                        bool covariant = true;
 
                        while (it != itend) {
-                               bool cur_covariant = (is_ex_of_type(*it, varidx) ? ex_to_varidx(*it).is_covariant() : true);
+                               bool cur_covariant = (is_ex_of_type(*it, varidx) ? ex_to<varidx>(*it).is_covariant() : true);
                                if (first || cur_covariant != covariant) {
                                        if (!first)
                                                c.s << "}";
@@ -617,7 +617,7 @@ try_again:
                // Indexed factor found, get free indices and look for contraction
                // candidates
                exvector free1, dummy1;
-               find_free_and_dummy(ex_to_indexed(*it1).seq.begin() + 1, ex_to_indexed(*it1).seq.end(), free1, dummy1);
+               find_free_and_dummy(ex_to<indexed>(*it1).seq.begin() + 1, ex_to<indexed>(*it1).seq.end(), free1, dummy1);
 
                exvector::iterator it2;
                for (it2 = it1 + 1; it2 != itend; it2++) {
@@ -630,7 +630,7 @@ try_again:
                        // Find free indices of second factor and merge them with free
                        // indices of first factor
                        exvector un;
-                       find_free_and_dummy(ex_to_indexed(*it2).seq.begin() + 1, ex_to_indexed(*it2).seq.end(), un, dummy1);
+                       find_free_and_dummy(ex_to<indexed>(*it2).seq.begin() + 1, ex_to<indexed>(*it2).seq.end(), un, dummy1);
                        un.insert(un.end(), free1.begin(), free1.end());
 
                        // Check whether the two factors share dummy indices
@@ -651,8 +651,8 @@ try_again:
 
                        // Contraction of symmetric with antisymmetric object is zero
                        if (dummy.size() > 1
-                        && ex_to_symmetry(ex_to_indexed(*it1).symtree).has_symmetry()
-                        && ex_to_symmetry(ex_to_indexed(*it2).symtree).has_symmetry()) {
+                        && ex_to<symmetry>(ex_to<indexed>(*it1).symtree).has_symmetry()
+                        && ex_to<symmetry>(ex_to<indexed>(*it2).symtree).has_symmetry()) {
 
                                // Check all pairs of dummy indices
                                for (unsigned idx1=0; idx1<dummy.size()-1; idx1++) {
@@ -713,7 +713,7 @@ contraction_done:
                exvector free_indices_of_factor;
                if (is_ex_of_type(*it1, indexed)) {
                        exvector dummy_indices_of_factor;
-                       find_free_and_dummy(ex_to_indexed(*it1).seq.begin() + 1, ex_to_indexed(*it1).seq.end(), free_indices_of_factor, dummy_indices_of_factor);
+                       find_free_and_dummy(ex_to<indexed>(*it1).seq.begin() + 1, ex_to<indexed>(*it1).seq.end(), free_indices_of_factor, dummy_indices_of_factor);
                        individual_dummy_indices.insert(individual_dummy_indices.end(), dummy_indices_of_factor.begin(), dummy_indices_of_factor.end());
                } else
                        free_indices_of_factor = it1->get_free_indices();
@@ -736,7 +736,7 @@ contraction_done:
        // Product of indexed object with a scalar?
        if (is_ex_exactly_of_type(r, mul) && r.nops() == 2
         && is_ex_exactly_of_type(r.op(1), numeric) && is_ex_of_type(r.op(0), indexed))
-               return r.op(0).op(0).bp->scalar_mul_indexed(r.op(0), ex_to_numeric(r.op(1)));
+               return r.op(0).op(0).bp->scalar_mul_indexed(r.op(0), ex_to<numeric>(r.op(1)));
        else
                return r;
 }
@@ -750,7 +750,7 @@ ex simplify_indexed(const ex & e, exvector & free_indices, exvector & dummy_indi
        // Simplification of single indexed object: just find the free indices
        // and perform dummy index renaming
        if (is_ex_of_type(e_expanded, indexed)) {
-               const indexed &i = ex_to_indexed(e_expanded);
+               const indexed &i = ex_to<indexed>(e_expanded);
                exvector local_dummy_indices;
                find_free_and_dummy(i.seq.begin() + 1, i.seq.end(), free_indices, local_dummy_indices);
                return rename_dummy_indices(e_expanded, dummy_indices, local_dummy_indices);
index df05429..363bbe8 100644 (file)
@@ -234,7 +234,7 @@ private:
 
 // utility functions
 
-/** Return the indexed object handled by an ex.
+/** Return the indexed object handled by an ex.  Deprecated: use ex_to<indexed>().
  *  This is unsafe: you need to check the type first. */
 inline const indexed &ex_to_indexed(const ex &e)
 {
index e2714cf..e57c9df 100644 (file)
@@ -47,13 +47,13 @@ static ex abs_evalf(const ex & arg)
                TYPECHECK(arg,numeric)
        END_TYPECHECK(abs(arg))
        
-       return abs(ex_to_numeric(arg));
+       return abs(ex_to<numeric>(arg));
 }
 
 static ex abs_eval(const ex & arg)
 {
        if (is_ex_exactly_of_type(arg, numeric))
-               return abs(ex_to_numeric(arg));
+               return abs(ex_to<numeric>(arg));
        else
                return abs(arg).hold();
 }
@@ -72,17 +72,17 @@ static ex csgn_evalf(const ex & arg)
                TYPECHECK(arg,numeric)
        END_TYPECHECK(csgn(arg))
        
-       return csgn(ex_to_numeric(arg));
+       return csgn(ex_to<numeric>(arg));
 }
 
 static ex csgn_eval(const ex & arg)
 {
        if (is_ex_exactly_of_type(arg, numeric))
-               return csgn(ex_to_numeric(arg));
+               return csgn(ex_to<numeric>(arg));
        
        else if (is_ex_of_type(arg, mul) &&
                 is_ex_of_type(arg.op(arg.nops()-1),numeric)) {
-               numeric oc = ex_to_numeric(arg.op(arg.nops()-1));
+               numeric oc = ex_to<numeric>(arg.op(arg.nops()-1));
                if (oc.is_real()) {
                        if (oc > 0)
                                // csgn(42*x) -> csgn(x)
@@ -111,7 +111,7 @@ static ex csgn_series(const ex & arg,
 {
        const ex arg_pt = arg.subs(rel);
        if (arg_pt.info(info_flags::numeric)
-           && ex_to_numeric(arg_pt).real().is_zero()
+           && ex_to<numeric>(arg_pt).real().is_zero()
            && !(options & series_options::suppress_branchcut))
                throw (std::domain_error("csgn_series(): on imaginary axis"));
        
@@ -136,9 +136,9 @@ static ex eta_evalf(const ex & x, const ex & y)
                TYPECHECK(y,numeric)
        END_TYPECHECK(eta(x,y))
                
-       numeric xim = imag(ex_to_numeric(x));
-       numeric yim = imag(ex_to_numeric(y));
-       numeric xyim = imag(ex_to_numeric(x*y));
+       numeric xim = imag(ex_to<numeric>(x));
+       numeric yim = imag(ex_to<numeric>(y));
+       numeric xyim = imag(ex_to<numeric>(x*y));
        return evalf(I/4*Pi)*((csgn(-xim)+1)*(csgn(-yim)+1)*(csgn(xyim)+1)-(csgn(xim)+1)*(csgn(yim)+1)*(csgn(-xyim)+1));
 }
 
@@ -147,9 +147,9 @@ static ex eta_eval(const ex & x, const ex & y)
        if (is_ex_exactly_of_type(x, numeric) &&
                is_ex_exactly_of_type(y, numeric)) {
                // don't call eta_evalf here because it would call Pi.evalf()!
-               numeric xim = imag(ex_to_numeric(x));
-               numeric yim = imag(ex_to_numeric(y));
-               numeric xyim = imag(ex_to_numeric(x*y));
+               numeric xim = imag(ex_to<numeric>(x));
+               numeric yim = imag(ex_to<numeric>(y));
+               numeric xyim = imag(ex_to<numeric>(x*y));
                return (I/4)*Pi*((csgn(-xim)+1)*(csgn(-yim)+1)*(csgn(xyim)+1)-(csgn(xim)+1)*(csgn(yim)+1)*(csgn(-xyim)+1));
        }
        
@@ -164,9 +164,9 @@ static ex eta_series(const ex & arg1,
 {
        const ex arg1_pt = arg1.subs(rel);
        const ex arg2_pt = arg2.subs(rel);
-       if (ex_to_numeric(arg1_pt).imag().is_zero() ||
-               ex_to_numeric(arg2_pt).imag().is_zero() ||
-               ex_to_numeric(arg1_pt*arg2_pt).imag().is_zero()) {
+       if (ex_to<numeric>(arg1_pt).imag().is_zero() ||
+               ex_to<numeric>(arg2_pt).imag().is_zero() ||
+               ex_to<numeric>(arg1_pt*arg2_pt).imag().is_zero()) {
                throw (std::domain_error("eta_series(): on discontinuity"));
        }
        epvector seq;
@@ -190,7 +190,7 @@ static ex Li2_evalf(const ex & x)
                TYPECHECK(x,numeric)
        END_TYPECHECK(Li2(x))
        
-       return Li2(ex_to_numeric(x));  // -> numeric Li2(numeric)
+       return Li2(ex_to<numeric>(x));  // -> numeric Li2(numeric)
 }
 
 static ex Li2_eval(const ex & x)
@@ -289,7 +289,7 @@ static ex Li2_series(const ex &x, const relational &rel, int order, unsigned opt
                }
                // third special case: x real, >=1 (branch cut)
                if (!(options & series_options::suppress_branchcut) &&
-                       ex_to_numeric(x_pt).is_real() && ex_to_numeric(x_pt)>1) {
+                       ex_to<numeric>(x_pt).is_real() && ex_to<numeric>(x_pt)>1) {
                        // method:
                        // This is the branch cut: assemble the primitive series manually
                        // and then add the corresponding complex step function.
@@ -344,7 +344,7 @@ static ex factorial_evalf(const ex & x)
 static ex factorial_eval(const ex & x)
 {
        if (is_ex_exactly_of_type(x, numeric))
-               return factorial(ex_to_numeric(x));
+               return factorial(ex_to<numeric>(x));
        else
                return factorial(x).hold();
 }
@@ -364,7 +364,7 @@ static ex binomial_evalf(const ex & x, const ex & y)
 static ex binomial_eval(const ex & x, const ex &y)
 {
        if (is_ex_exactly_of_type(x, numeric) && is_ex_exactly_of_type(y, numeric))
-               return binomial(ex_to_numeric(x), ex_to_numeric(y));
+               return binomial(ex_to<numeric>(x), ex_to<numeric>(y));
        else
                return binomial(x, y).hold();
 }
@@ -471,7 +471,7 @@ ex lsolve(const ex &eqns, const ex &symbols)
                ex eq = eqns.op(r).op(0)-eqns.op(r).op(1); // lhs-rhs==0
                ex linpart = eq;
                for (unsigned c=0; c<symbols.nops(); c++) {
-                       ex co = eq.coeff(ex_to_symbol(symbols.op(c)),1);
+                       ex co = eq.coeff(ex_to<symbol>(symbols.op(c)),1);
                        linpart -= co*symbols.op(c);
                        sys(r,c) = co;
                }
index dfc5ee1..bb32f84 100644 (file)
@@ -46,7 +46,7 @@ static ex lgamma_evalf(const ex & x)
                TYPECHECK(x,numeric)
        END_TYPECHECK(lgamma(x))
        
-       return lgamma(ex_to_numeric(x));
+       return lgamma(ex_to<numeric>(x));
 }
 
 
@@ -99,7 +99,7 @@ static ex lgamma_series(const ex & arg,
        if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
                throw do_taylor();  // caught by function::series()
        // if we got here we have to care for a simple pole of tgamma(-m):
-       numeric m = -ex_to_numeric(arg_pt);
+       numeric m = -ex_to<numeric>(arg_pt);
        ex recur;
        for (numeric p; p<=m; ++p)
                recur += log(arg+p);
@@ -124,7 +124,7 @@ static ex tgamma_evalf(const ex & x)
                TYPECHECK(x,numeric)
        END_TYPECHECK(tgamma(x))
        
-       return tgamma(ex_to_numeric(x));
+       return tgamma(ex_to<numeric>(x));
 }
 
 
@@ -140,7 +140,7 @@ static ex tgamma_eval(const ex & x)
                if (x.info(info_flags::integer)) {
                        // tgamma(n) -> (n-1)! for postitive n
                        if (x.info(info_flags::posint)) {
-                               return factorial(ex_to_numeric(x).sub(_num1()));
+                               return factorial(ex_to<numeric>(x).sub(_num1()));
                        } else {
                                throw (pole_error("tgamma_eval(): simple pole",1));
                        }
@@ -150,14 +150,14 @@ static ex tgamma_eval(const ex & x)
                        // trap positive x==(n+1/2)
                        // tgamma(n+1/2) -> Pi^(1/2)*(1*3*..*(2*n-1))/(2^n)
                        if ((x*_ex2()).info(info_flags::posint)) {
-                               numeric n = ex_to_numeric(x).sub(_num1_2());
+                               numeric n = ex_to<numeric>(x).sub(_num1_2());
                                numeric coefficient = doublefactorial(n.mul(_num2()).sub(_num1()));
                                coefficient = coefficient.div(pow(_num2(),n));
                                return coefficient * pow(Pi,_ex1_2());
                        } else {
                                // trap negative x==(-n+1/2)
                                // tgamma(-n+1/2) -> Pi^(1/2)*(-2)^n/(1*3*..*(2*n-1))
-                               numeric n = abs(ex_to_numeric(x).sub(_num1_2()));
+                               numeric n = abs(ex_to<numeric>(x).sub(_num1_2()));
                                numeric coefficient = pow(_num_2(), n);
                                coefficient = coefficient.div(doublefactorial(n.mul(_num2()).sub(_num1())));;
                                return coefficient*power(Pi,_ex1_2());
@@ -196,7 +196,7 @@ static ex tgamma_series(const ex & arg,
        if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
                throw do_taylor();  // caught by function::series()
        // if we got here we have to care for a simple pole at -m:
-       numeric m = -ex_to_numeric(arg_pt);
+       numeric m = -ex_to<numeric>(arg_pt);
        ex ser_denom = _ex1();
        for (numeric p; p<=m; ++p)
                ser_denom *= arg+p;
@@ -222,7 +222,7 @@ static ex beta_evalf(const ex & x, const ex & y)
                TYPECHECK(y,numeric)
        END_TYPECHECK(beta(x,y))
        
-       return tgamma(ex_to_numeric(x))*tgamma(ex_to_numeric(y))/tgamma(ex_to_numeric(x+y));
+       return tgamma(ex_to<numeric>(x))*tgamma(ex_to<numeric>(y))/tgamma(ex_to<numeric>(x+y));
 }
 
 
@@ -232,8 +232,8 @@ static ex beta_eval(const ex & x, const ex & y)
                // treat all problematic x and y that may not be passed into tgamma,
                // because they would throw there although beta(x,y) is well-defined
                // using the formula beta(x,y) == (-1)^y * beta(1-x-y, y)
-               numeric nx(ex_to_numeric(x));
-               numeric ny(ex_to_numeric(y));
+               numeric nx(ex_to<numeric>(x));
+               numeric ny(ex_to<numeric>(y));
                if (nx.is_real() && nx.is_integer() &&
                        ny.is_real() && ny.is_integer()) {
                        if (nx.is_negative()) {
@@ -334,7 +334,7 @@ static ex psi1_evalf(const ex & x)
                TYPECHECK(x,numeric)
        END_TYPECHECK(psi(x))
        
-       return psi(ex_to_numeric(x));
+       return psi(ex_to<numeric>(x));
 }
 
 /** Evaluation of digamma-function psi(x).
@@ -342,7 +342,7 @@ static ex psi1_evalf(const ex & x)
 static ex psi1_eval(const ex & x)
 {
        if (x.info(info_flags::numeric)) {
-               numeric nx = ex_to_numeric(x);
+               numeric nx = ex_to<numeric>(x);
                if (nx.is_integer()) {
                        // integer case 
                        if (nx.is_positive()) {
@@ -407,7 +407,7 @@ static ex psi1_series(const ex & arg,
        if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
                throw do_taylor();  // caught by function::series()
        // if we got here we have to care for a simple pole at -m:
-       numeric m = -ex_to_numeric(arg_pt);
+       numeric m = -ex_to<numeric>(arg_pt);
        ex recur;
        for (numeric p; p<=m; ++p)
                recur += power(arg+p,_ex_1());
@@ -434,7 +434,7 @@ static ex psi2_evalf(const ex & n, const ex & x)
                TYPECHECK(x,numeric)
        END_TYPECHECK(psi(n,x))
        
-       return psi(ex_to_numeric(n), ex_to_numeric(x));
+       return psi(ex_to<numeric>(n), ex_to<numeric>(x));
 }
 
 /** Evaluation of polygamma-function psi(n,x). 
@@ -449,8 +449,8 @@ static ex psi2_eval(const ex & n, const ex & x)
                return log(tgamma(x));
        if (n.info(info_flags::numeric) && n.info(info_flags::posint) &&
                x.info(info_flags::numeric)) {
-               numeric nn = ex_to_numeric(n);
-               numeric nx = ex_to_numeric(x);
+               numeric nn = ex_to<numeric>(n);
+               numeric nx = ex_to<numeric>(x);
                if (nx.is_integer()) {
                        // integer case 
                        if (nx.is_equal(_num1()))
@@ -533,7 +533,7 @@ static ex psi2_series(const ex & n,
        if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
                throw do_taylor();  // caught by function::series()
        // if we got here we have to care for a pole of order n+1 at -m:
-       numeric m = -ex_to_numeric(arg_pt);
+       numeric m = -ex_to<numeric>(arg_pt);
        ex recur;
        for (numeric p; p<=m; ++p)
                recur += power(arg+p,-n+_ex_1());
index 3bda254..a37f716 100644 (file)
@@ -46,7 +46,7 @@ static ex exp_evalf(const ex & x)
                TYPECHECK(x,numeric)
        END_TYPECHECK(exp(x))
        
-       return exp(ex_to_numeric(x)); // -> numeric exp(numeric)
+       return exp(ex_to<numeric>(x)); // -> numeric exp(numeric)
 }
 
 static ex exp_eval(const ex & x)
@@ -58,7 +58,7 @@ static ex exp_eval(const ex & x)
        // exp(n*Pi*I/2) -> {+1|+I|-1|-I}
        ex TwoExOverPiI=(_ex2()*x)/(Pi*I);
        if (TwoExOverPiI.info(info_flags::integer)) {
-               numeric z=mod(ex_to_numeric(TwoExOverPiI),_num4());
+               numeric z=mod(ex_to<numeric>(TwoExOverPiI),_num4());
                if (z.is_equal(_num0()))
                        return _ex1();
                if (z.is_equal(_num1()))
@@ -102,7 +102,7 @@ static ex log_evalf(const ex & x)
                TYPECHECK(x,numeric)
        END_TYPECHECK(log(x))
        
-       return log(ex_to_numeric(x)); // -> numeric log(numeric)
+       return log(ex_to<numeric>(x)); // -> numeric log(numeric)
 }
 
 static ex log_eval(const ex & x)
@@ -126,7 +126,7 @@ static ex log_eval(const ex & x)
        if (is_ex_the_function(x, exp)) {
                ex t = x.op(0);
                if (t.info(info_flags::numeric)) {
-                       numeric nt = ex_to_numeric(t);
+                       numeric nt = ex_to<numeric>(t);
                        if (nt.is_real())
                                return t;
                }
@@ -170,7 +170,7 @@ static ex log_series(const ex &arg,
                // Return a plain n*log(x) for the x^n part and series expand the
                // other part.  Add them together and reexpand again in order to have
                // one unnested pseries object.  All this also works for negative n.
-               const pseries argser = ex_to_pseries(arg.series(rel, order, options));
+               const pseries argser = ex_to<pseries>(arg.series(rel, order, options));
                const symbol *s = static_cast<symbol *>(rel.lhs().bp);
                const ex point = rel.rhs();
                const int n = argser.ldegree(*s);
@@ -186,8 +186,8 @@ static ex log_series(const ex &arg,
                if (!argser.is_terminating() || argser.nops()!=1) {
                        // in this case n more terms are needed
                        // (sadly, to generate them, we have to start from the beginning)
-                       ex newarg = ex_to_pseries((arg/coeff).series(rel, order+n, options)).shift_exponents(-n).convert_to_poly(true);
-                       return pseries(rel, seq).add_series(ex_to_pseries(log(newarg).series(rel, order, options)));
+                       ex newarg = ex_to<pseries>((arg/coeff).series(rel, order+n, options)).shift_exponents(-n).convert_to_poly(true);
+                       return pseries(rel, seq).add_series(ex_to<pseries>(log(newarg).series(rel, order, options)));
                } else  // it was a monomial
                        return pseries(rel, seq);
        }
@@ -224,7 +224,7 @@ static ex sin_evalf(const ex & x)
           TYPECHECK(x,numeric)
        END_TYPECHECK(sin(x))
        
-       return sin(ex_to_numeric(x)); // -> numeric sin(numeric)
+       return sin(ex_to<numeric>(x)); // -> numeric sin(numeric)
 }
 
 static ex sin_eval(const ex & x)
@@ -233,7 +233,7 @@ static ex sin_eval(const ex & x)
        ex SixtyExOverPi = _ex60()*x/Pi;
        ex sign = _ex1();
        if (SixtyExOverPi.info(info_flags::integer)) {
-               numeric z = mod(ex_to_numeric(SixtyExOverPi),_num120());
+               numeric z = mod(ex_to<numeric>(SixtyExOverPi),_num120());
                if (z>=_num60()) {
                        // wrap to interval [0, Pi)
                        z -= _num60();
@@ -306,7 +306,7 @@ static ex cos_evalf(const ex & x)
                TYPECHECK(x,numeric)
        END_TYPECHECK(cos(x))
        
-       return cos(ex_to_numeric(x)); // -> numeric cos(numeric)
+       return cos(ex_to<numeric>(x)); // -> numeric cos(numeric)
 }
 
 static ex cos_eval(const ex & x)
@@ -315,7 +315,7 @@ static ex cos_eval(const ex & x)
        ex SixtyExOverPi = _ex60()*x/Pi;
        ex sign = _ex1();
        if (SixtyExOverPi.info(info_flags::integer)) {
-               numeric z = mod(ex_to_numeric(SixtyExOverPi),_num120());
+               numeric z = mod(ex_to<numeric>(SixtyExOverPi),_num120());
                if (z>=_num60()) {
                        // wrap to interval [0, Pi)
                        z = _num120()-z;
@@ -388,7 +388,7 @@ static ex tan_evalf(const ex & x)
           TYPECHECK(x,numeric)
        END_TYPECHECK(tan(x)) // -> numeric tan(numeric)
        
-       return tan(ex_to_numeric(x));
+       return tan(ex_to<numeric>(x));
 }
 
 static ex tan_eval(const ex & x)
@@ -397,7 +397,7 @@ static ex tan_eval(const ex & x)
        ex SixtyExOverPi = _ex60()*x/Pi;
        ex sign = _ex1();
        if (SixtyExOverPi.info(info_flags::integer)) {
-               numeric z = mod(ex_to_numeric(SixtyExOverPi),_num60());
+               numeric z = mod(ex_to<numeric>(SixtyExOverPi),_num60());
                if (z>=_num60()) {
                        // wrap to interval [0, Pi)
                        z -= _num60();
@@ -484,7 +484,7 @@ static ex asin_evalf(const ex & x)
           TYPECHECK(x,numeric)
        END_TYPECHECK(asin(x))
        
-       return asin(ex_to_numeric(x)); // -> numeric asin(numeric)
+       return asin(ex_to<numeric>(x)); // -> numeric asin(numeric)
 }
 
 static ex asin_eval(const ex & x)
@@ -536,7 +536,7 @@ static ex acos_evalf(const ex & x)
           TYPECHECK(x,numeric)
        END_TYPECHECK(acos(x))
        
-       return acos(ex_to_numeric(x)); // -> numeric acos(numeric)
+       return acos(ex_to<numeric>(x)); // -> numeric acos(numeric)
 }
 
 static ex acos_eval(const ex & x)
@@ -588,7 +588,7 @@ static ex atan_evalf(const ex & x)
                TYPECHECK(x,numeric)
        END_TYPECHECK(atan(x))
        
-       return atan(ex_to_numeric(x)); // -> numeric atan(numeric)
+       return atan(ex_to<numeric>(x)); // -> numeric atan(numeric)
 }
 
 static ex atan_eval(const ex & x)
@@ -681,7 +681,7 @@ static ex atan2_evalf(const ex & y, const ex & x)
                TYPECHECK(x,numeric)
        END_TYPECHECK(atan2(y,x))
        
-       return atan(ex_to_numeric(y),ex_to_numeric(x)); // -> numeric atan(numeric)
+       return atan(ex_to<numeric>(y),ex_to<numeric>(x)); // -> numeric atan(numeric)
 }
 
 static ex atan2_eval(const ex & y, const ex & x)
@@ -720,7 +720,7 @@ static ex sinh_evalf(const ex & x)
           TYPECHECK(x,numeric)
        END_TYPECHECK(sinh(x))
        
-       return sinh(ex_to_numeric(x)); // -> numeric sinh(numeric)
+       return sinh(ex_to<numeric>(x)); // -> numeric sinh(numeric)
 }
 
 static ex sinh_eval(const ex & x)
@@ -733,7 +733,7 @@ static ex sinh_eval(const ex & x)
        }
        
        if ((x/Pi).info(info_flags::numeric) &&
-               ex_to_numeric(x/Pi).real().is_zero())  // sinh(I*x) -> I*sin(x)
+               ex_to<numeric>(x/Pi).real().is_zero())  // sinh(I*x) -> I*sin(x)
                return I*sin(x/I);
        
        if (is_ex_exactly_of_type(x, function)) {
@@ -775,7 +775,7 @@ static ex cosh_evalf(const ex & x)
           TYPECHECK(x,numeric)
        END_TYPECHECK(cosh(x))
        
-       return cosh(ex_to_numeric(x)); // -> numeric cosh(numeric)
+       return cosh(ex_to<numeric>(x)); // -> numeric cosh(numeric)
 }
 
 static ex cosh_eval(const ex & x)
@@ -788,7 +788,7 @@ static ex cosh_eval(const ex & x)
        }
        
        if ((x/Pi).info(info_flags::numeric) &&
-               ex_to_numeric(x/Pi).real().is_zero())  // cosh(I*x) -> cos(x)
+               ex_to<numeric>(x/Pi).real().is_zero())  // cosh(I*x) -> cos(x)
                return cos(x/I);
        
        if (is_ex_exactly_of_type(x, function)) {
@@ -830,7 +830,7 @@ static ex tanh_evalf(const ex & x)
           TYPECHECK(x,numeric)
        END_TYPECHECK(tanh(x))
        
-       return tanh(ex_to_numeric(x)); // -> numeric tanh(numeric)
+       return tanh(ex_to<numeric>(x)); // -> numeric tanh(numeric)
 }
 
 static ex tanh_eval(const ex & x)
@@ -843,7 +843,7 @@ static ex tanh_eval(const ex & x)
        }
        
        if ((x/Pi).info(info_flags::numeric) &&
-               ex_to_numeric(x/Pi).real().is_zero())  // tanh(I*x) -> I*tan(x);
+               ex_to<numeric>(x/Pi).real().is_zero())  // tanh(I*x) -> I*tan(x);
                return I*tan(x/I);
        
        if (is_ex_exactly_of_type(x, function)) {
@@ -902,7 +902,7 @@ static ex asinh_evalf(const ex & x)
           TYPECHECK(x,numeric)
        END_TYPECHECK(asinh(x))
        
-       return asinh(ex_to_numeric(x)); // -> numeric asinh(numeric)
+       return asinh(ex_to<numeric>(x)); // -> numeric asinh(numeric)
 }
 
 static ex asinh_eval(const ex & x)
@@ -941,7 +941,7 @@ static ex acosh_evalf(const ex & x)
           TYPECHECK(x,numeric)
        END_TYPECHECK(acosh(x))
        
-       return acosh(ex_to_numeric(x)); // -> numeric acosh(numeric)
+       return acosh(ex_to<numeric>(x)); // -> numeric acosh(numeric)
 }
 
 static ex acosh_eval(const ex & x)
@@ -986,7 +986,7 @@ static ex atanh_evalf(const ex & x)
           TYPECHECK(x,numeric)
        END_TYPECHECK(atanh(x))
        
-       return atanh(ex_to_numeric(x)); // -> numeric atanh(numeric)
+       return atanh(ex_to<numeric>(x)); // -> numeric atanh(numeric)
 }
 
 static ex atanh_eval(const ex & x)
index 14015b7..9cd0961 100644 (file)
@@ -42,13 +42,13 @@ static ex zeta1_evalf(const ex & x)
                TYPECHECK(x,numeric)
        END_TYPECHECK(zeta(x))
                
-       return zeta(ex_to_numeric(x));
+       return zeta(ex_to<numeric>(x));
 }
 
 static ex zeta1_eval(const ex & x)
 {
        if (x.info(info_flags::numeric)) {
-               numeric y = ex_to_numeric(x);
+               numeric y = ex_to<numeric>(x);
                // trap integer arguments:
                if (y.is_integer()) {
                        if (y.is_zero())
index 1f2e0ea..965e1da 100644 (file)
@@ -308,7 +308,7 @@ ex matrix::eval_indexed(const basic & i) const
                if (row != 1 && col != 1)
                        throw (std::runtime_error("matrix::eval_indexed(): vector must have exactly 1 index"));
 
-               const idx & i1 = ex_to_idx(i.op(1));
+               const idx & i1 = ex_to<idx>(i.op(1));
 
                if (col == 1) {
 
@@ -318,7 +318,7 @@ ex matrix::eval_indexed(const basic & i) const
 
                        // Index numeric -> return vector element
                        if (all_indices_unsigned) {
-                               unsigned n1 = ex_to_numeric(i1.get_value()).to_int();
+                               unsigned n1 = ex_to<numeric>(i1.get_value()).to_int();
                                if (n1 >= row)
                                        throw (std::runtime_error("matrix::eval_indexed(): value of index exceeds number of vector elements"));
                                return (*this)(n1, 0);
@@ -332,7 +332,7 @@ ex matrix::eval_indexed(const basic & i) const
 
                        // Index numeric -> return vector element
                        if (all_indices_unsigned) {
-                               unsigned n1 = ex_to_numeric(i1.get_value()).to_int();
+                               unsigned n1 = ex_to<numeric>(i1.get_value()).to_int();
                                if (n1 >= col)
                                        throw (std::runtime_error("matrix::eval_indexed(): value of index exceeds number of vector elements"));
                                return (*this)(0, n1);
@@ -342,8 +342,8 @@ ex matrix::eval_indexed(const basic & i) const
        } else if (i.nops() == 3) {
 
                // Two indices
-               const idx & i1 = ex_to_idx(i.op(1));
-               const idx & i2 = ex_to_idx(i.op(2));
+               const idx & i1 = ex_to<idx>(i.op(1));
+               const idx & i2 = ex_to<idx>(i.op(2));
 
                if (!i1.get_dim().is_equal(row))
                        throw (std::runtime_error("matrix::eval_indexed(): dimension of first index must match number of rows"));
@@ -356,7 +356,7 @@ ex matrix::eval_indexed(const basic & i) const
 
                // Both indices numeric -> return matrix element
                if (all_indices_unsigned) {
-                       unsigned n1 = ex_to_numeric(i1.get_value()).to_int(), n2 = ex_to_numeric(i2.get_value()).to_int();
+                       unsigned n1 = ex_to<numeric>(i1.get_value()).to_int(), n2 = ex_to<numeric>(i2.get_value()).to_int();
                        if (n1 >= row)
                                throw (std::runtime_error("matrix::eval_indexed(): value of first index exceeds number of rows"));
                        if (n2 >= col)
@@ -382,8 +382,8 @@ ex matrix::add_indexed(const ex & self, const ex & other) const
        if (is_ex_of_type(other.op(0), matrix)) {
                GINAC_ASSERT(other.nops() == 2 || other.nops() == 3);
 
-               const matrix &self_matrix = ex_to_matrix(self.op(0));
-               const matrix &other_matrix = ex_to_matrix(other.op(0));
+               const matrix &self_matrix = ex_to<matrix>(self.op(0));
+               const matrix &other_matrix = ex_to<matrix>(other.op(0));
 
                if (self.nops() == 2 && other.nops() == 2) { // vector + vector
 
@@ -413,7 +413,7 @@ ex matrix::scalar_mul_indexed(const ex & self, const numeric & other) const
        GINAC_ASSERT(is_ex_of_type(self.op(0), matrix));
        GINAC_ASSERT(self.nops() == 2 || self.nops() == 3);
 
-       const matrix &self_matrix = ex_to_matrix(self.op(0));
+       const matrix &self_matrix = ex_to<matrix>(self.op(0));
 
        if (self.nops() == 2)
                return indexed(self_matrix.mul(other), self.op(1));
@@ -435,8 +435,8 @@ bool matrix::contract_with(exvector::iterator self, exvector::iterator other, ex
 
        GINAC_ASSERT(other->nops() == 2 || other->nops() == 3);
 
-       const matrix &self_matrix = ex_to_matrix(self->op(0));
-       const matrix &other_matrix = ex_to_matrix(other->op(0));
+       const matrix &self_matrix = ex_to<matrix>(self->op(0));
+       const matrix &other_matrix = ex_to<matrix>(other->op(0));
 
        if (self->nops() == 2) {
                unsigned self_dim = (self_matrix.col == 1) ? self_matrix.row : self_matrix.col;
@@ -628,10 +628,10 @@ matrix matrix::pow(const ex & expn) const
                        numeric k;
                        matrix prod(row,col);
                        if (expn.info(info_flags::negative)) {
-                               k = -ex_to_numeric(expn);
+                               k = -ex_to<numeric>(expn);
                                prod = this->inverse();
                        } else {
-                               k = ex_to_numeric(expn);
+                               k = ex_to<numeric>(expn);
                                prod = *this;
                        }
                        matrix result(row,col);
@@ -1425,10 +1425,10 @@ int matrix::pivot(unsigned ro, unsigned co, bool symbolic)
                // search largest element in column co beginning at row ro
                GINAC_ASSERT(is_ex_of_type(this->m[k*col+co],numeric));
                unsigned kmax = k+1;
-               numeric mmax = abs(ex_to_numeric(m[kmax*col+co]));
+               numeric mmax = abs(ex_to<numeric>(m[kmax*col+co]));
                while (kmax<row) {
                        GINAC_ASSERT(is_ex_of_type(this->m[kmax*col+co],numeric));
-                       numeric tmp = ex_to_numeric(this->m[kmax*col+co]);
+                       numeric tmp = ex_to<numeric>(this->m[kmax*col+co]);
                        if (abs(tmp) > mmax) {
                                mmax = tmp;
                                k = kmax;
index fac033a..b7f3f1c 100644 (file)
@@ -134,7 +134,7 @@ inline matrix inverse(const matrix & m)
 
 // utility functions
 
-/** Return the matrix object handled by an ex.
+/** Return the matrix object handled by an ex.  Deprecated: use ex_to<matrix>().
  *  This is unsafe: you need to check the type first. */
 inline const matrix &ex_to_matrix(const ex &e)
 {
index 10f25ec..04941b3 100644 (file)
@@ -150,7 +150,7 @@ void mul::print(const print_context & c, unsigned level) const
                while (it != itend) {
 
                        // If the first argument is a negative integer power, it gets printed as "1.0/<expr>"
-                       if (it == seq.begin() && ex_to_numeric(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0) {
+                       if (it == seq.begin() && ex_to<numeric>(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0) {
                                if (is_a<print_csrc_cl_N>(c))
                                        c.s << "recip(";
                                else
@@ -162,13 +162,13 @@ void mul::print(const print_context & c, unsigned level) const
                                it->rest.print(c, precedence());
                        else {
                                // Outer parens around ex needed for broken gcc-2.95 parser:
-                               (ex(power(it->rest, abs(ex_to_numeric(it->coeff))))).print(c, level);
+                               (ex(power(it->rest, abs(ex_to<numeric>(it->coeff))))).print(c, level);
                        }
 
                        // Separator is "/" for negative integer powers, "*" otherwise
                        ++it;
                        if (it != itend) {
-                               if (ex_to_numeric(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0)
+                               if (ex_to<numeric>(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0)
                                        c.s << "/";
                                else
                                        c.s << "*";
@@ -190,7 +190,7 @@ void mul::print(const print_context & c, unsigned level) const
                bool first = true;
 
                // First print the overall numeric coefficient
-               numeric coeff = ex_to_numeric(overall_coeff);
+               numeric coeff = ex_to<numeric>(overall_coeff);
                if (coeff.csgn() == -1)
                        c.s << '-';
                if (!coeff.is_equal(_num1()) &&
@@ -266,8 +266,8 @@ int mul::degree(const ex & s) const
 {
        int deg_sum = 0;
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               if (ex_to_numeric(cit->coeff).is_integer())
-                       deg_sum+=cit->rest.degree(s) * ex_to_numeric(cit->coeff).to_int();
+               if (ex_to<numeric>(cit->coeff).is_integer())
+                       deg_sum+=cit->rest.degree(s) * ex_to<numeric>(cit->coeff).to_int();
        }
        return deg_sum;
 }
@@ -276,8 +276,8 @@ int mul::ldegree(const ex & s) const
 {
        int deg_sum = 0;
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               if (ex_to_numeric(cit->coeff).is_integer())
-                       deg_sum+=cit->rest.ldegree(s) * ex_to_numeric(cit->coeff).to_int();
+               if (ex_to<numeric>(cit->coeff).is_integer())
+                       deg_sum+=cit->rest.ldegree(s) * ex_to<numeric>(cit->coeff).to_int();
        }
        return deg_sum;
 }
@@ -339,7 +339,7 @@ ex mul::eval(int level) const
 #ifdef DO_GINAC_ASSERT
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
                GINAC_ASSERT((!is_ex_exactly_of_type((*cit).rest,mul)) ||
-                            (!(ex_to_numeric((*cit).coeff).is_integer())));
+                            (!(ex_to<numeric>((*cit).coeff).is_integer())));
                GINAC_ASSERT(!(cit->is_canonical_numeric()));
                if (is_ex_exactly_of_type(recombine_pair_to_ex(*cit),numeric))
                    print(print_tree(std::cerr));
@@ -370,17 +370,17 @@ ex mul::eval(int level) const
                return recombine_pair_to_ex(*(seq.begin()));
        } else if ((seq_size==1) &&
                   is_ex_exactly_of_type((*seq.begin()).rest,add) &&
-                  ex_to_numeric((*seq.begin()).coeff).is_equal(_num1())) {
+                  ex_to<numeric>((*seq.begin()).coeff).is_equal(_num1())) {
                // *(+(x,y,...);c) -> +(*(x,c),*(y,c),...) (c numeric(), no powers of +())
-               const add & addref = ex_to_add((*seq.begin()).rest);
+               const add & addref = ex_to<add>((*seq.begin()).rest);
                epvector distrseq;
                distrseq.reserve(addref.seq.size());
                for (epvector::const_iterator cit=addref.seq.begin(); cit!=addref.seq.end(); ++cit) {
                        distrseq.push_back(addref.combine_pair_with_coeff_to_pair(*cit, overall_coeff));
                }
                return (new add(distrseq,
-                               ex_to_numeric(addref.overall_coeff).
-                               mul_dyn(ex_to_numeric(overall_coeff))))
+                               ex_to<numeric>(addref.overall_coeff).
+                               mul_dyn(ex_to<numeric>(overall_coeff))))
                      ->setflag(status_flags::dynallocated | status_flags::evaluated);
        }
        return this->hold();
@@ -410,7 +410,7 @@ ex mul::evalm(void) const
        // numeric*matrix
        if (seq.size() == 1 && seq[0].coeff.is_equal(_ex1())
         && is_ex_of_type(seq[0].rest, matrix))
-               return ex_to_matrix(seq[0].rest).mul(ex_to_numeric(overall_coeff));
+               return ex_to<matrix>(seq[0].rest).mul(ex_to<numeric>(overall_coeff));
 
        // Evaluate children first, look whether there are any matrices at all
        // (there can be either no matrices or one matrix; if there were more
@@ -436,7 +436,7 @@ ex mul::evalm(void) const
 
                // The product contained a matrix. We will multiply all other factors
                // into that matrix.
-               matrix m = ex_to_matrix(the_matrix->rest);
+               matrix m = ex_to<matrix>(the_matrix->rest);
                s->erase(the_matrix);
                ex scalar = (new mul(s, overall_coeff))->setflag(status_flags::dynallocated);
                return m.mul_scalar(scalar);
@@ -546,7 +546,7 @@ ex mul::thisexpairseq(epvector * vp, const ex & oc) const
 expair mul::split_ex_to_pair(const ex & e) const
 {
        if (is_ex_exactly_of_type(e,power)) {
-               const power & powerref = ex_to_power(e);
+               const power & powerref = ex_to<power>(e);
                if (is_ex_exactly_of_type(powerref.exponent,numeric))
                        return expair(powerref.basis,powerref.exponent);
        }
@@ -581,7 +581,7 @@ expair mul::combine_pair_with_coeff_to_pair(const expair & p,
        
 ex mul::recombine_pair_to_ex(const expair & p) const
 {
-       if (ex_to_numeric(p.coeff).is_equal(_num1())) 
+       if (ex_to<numeric>(p.coeff).is_equal(_num1())) 
                return p.rest;
        else
                return power(p.rest,p.coeff);
@@ -590,7 +590,7 @@ ex mul::recombine_pair_to_ex(const expair & p) const
 bool mul::expair_needs_further_processing(epp it)
 {
        if (is_ex_exactly_of_type((*it).rest,mul) &&
-               ex_to_numeric((*it).coeff).is_integer()) {
+               ex_to<numeric>((*it).coeff).is_integer()) {
                // combined pair is product with integer power -> expand it
                *it = split_ex_to_pair(recombine_pair_to_ex(*it));
                return true;
@@ -602,7 +602,7 @@ bool mul::expair_needs_further_processing(epp it)
                        *it = ep;
                        return true;
                }
-               if (ex_to_numeric((*it).coeff).is_equal(_num1())) {
+               if (ex_to<numeric>((*it).coeff).is_equal(_num1())) {
                        // combined pair has coeff 1 and must be moved to the end
                        return true;
                }
@@ -619,7 +619,7 @@ void mul::combine_overall_coeff(const ex & c)
 {
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
        GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
-       overall_coeff = ex_to_numeric(overall_coeff).mul_dyn(ex_to_numeric(c));
+       overall_coeff = ex_to<numeric>(overall_coeff).mul_dyn(ex_to<numeric>(c));
 }
 
 void mul::combine_overall_coeff(const ex & c1, const ex & c2)
@@ -627,7 +627,7 @@ void mul::combine_overall_coeff(const ex & c1, const ex & c2)
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
        GINAC_ASSERT(is_ex_exactly_of_type(c1,numeric));
        GINAC_ASSERT(is_ex_exactly_of_type(c2,numeric));
-       overall_coeff = ex_to_numeric(overall_coeff).mul_dyn(ex_to_numeric(c1).power(ex_to_numeric(c2)));
+       overall_coeff = ex_to<numeric>(overall_coeff).mul_dyn(ex_to<numeric>(c1).power(ex_to<numeric>(c2)));
 }
 
 bool mul::can_make_flat(const expair & p) const
@@ -636,7 +636,7 @@ bool mul::can_make_flat(const expair & p) const
        // this assertion will probably fail somewhere
        // it would require a more careful make_flat, obeying the power laws
        // probably should return true only if p.coeff is integer
-       return ex_to_numeric(p.coeff).is_equal(_num1());
+       return ex_to<numeric>(p.coeff).is_equal(_num1());
 }
 
 ex mul::expand(unsigned options) const
@@ -655,15 +655,15 @@ ex mul::expand(unsigned options) const
        non_adds.reserve(expanded_seq.size());
        epvector::const_iterator cit = expanded_seq.begin();
        epvector::const_iterator last = expanded_seq.end();
-       ex last_expanded(_ex1());
+       ex last_expanded = _ex1();
        while (cit!=last) {
                if (is_ex_exactly_of_type((*cit).rest,add) &&
                        ((*cit).coeff.is_equal(_ex1()))) {
                        ++number_of_adds;
                        if (is_ex_exactly_of_type(last_expanded,add)) {
                                // expand adds
-                               const add & add1 = ex_to_add(last_expanded);
-                               const add & add2 = ex_to_add((*cit).rest);
+                               const add & add1 = ex_to<add>(last_expanded);
+                               const add & add2 = ex_to<add>((*cit).rest);
                                int n1 = add1.nops();
                                int n2 = add2.nops();
                                exvector distrseq;
@@ -687,7 +687,7 @@ ex mul::expand(unsigned options) const
                delete expanded_seqp;
 
        if (is_ex_exactly_of_type(last_expanded,add)) {
-               add const & finaladd = ex_to_add(last_expanded);
+               add const & finaladd = ex_to<add>(last_expanded);
                exvector distrseq;
                int n = finaladd.nops();
                distrseq.reserve(n);
index 39138c2..d24d37e 100644 (file)
@@ -91,7 +91,7 @@ protected:
 
 // utility functions
 
-/** Return the mul object handled by an ex.
+/** Return the mul object handled by an ex.  Deprecated: use ex_to<mul>().
  *  This is unsafe: you need to check the type first. */
 inline const mul &ex_to_mul(const ex &e)
 {
index 43ded21..e4a9186 100644 (file)
@@ -164,7 +164,7 @@ ex ncmul::expand(unsigned options) const
        for (exvector::const_iterator cit=expanded_seq.begin(); cit!=last; ++cit) {
                if (is_ex_exactly_of_type((*cit),add)) {
                        positions_of_adds[number_of_adds]=current_position;
-                       const add & expanded_addref=ex_to_add(*cit);
+                       const add & expanded_addref=ex_to<add>(*cit);
                        number_of_add_operands[number_of_adds]=expanded_addref.seq.size();
                        number_of_expanded_terms *= expanded_addref.seq.size();
                        number_of_adds++;
@@ -193,7 +193,7 @@ ex ncmul::expand(unsigned options) const
                term=expanded_seq;
                for (l=0; l<number_of_adds; l++) {
                        GINAC_ASSERT(is_ex_exactly_of_type(expanded_seq[positions_of_adds[l]],add));
-                       const add & addref=ex_to_add(expanded_seq[positions_of_adds[l]]);
+                       const add & addref=ex_to<add>(expanded_seq[positions_of_adds[l]]);
                        term[positions_of_adds[l]]=addref.recombine_pair_to_ex(addref.seq[k[l]]);
                }
                distrseq.push_back((new ncmul(term,1))->setflag(status_flags::dynallocated |
@@ -447,12 +447,12 @@ ex ncmul::evalm(void) const
        // If there are only matrices, simply multiply them
        it = s->begin(); itend = s->end();
        if (is_ex_of_type(*it, matrix)) {
-               matrix prod(ex_to_matrix(*it));
+               matrix prod(ex_to<matrix>(*it));
                it++;
                while (it != itend) {
                        if (!is_ex_of_type(*it, matrix))
                                goto no_matrix;
-                       prod = prod.mul(ex_to_matrix(*it));
+                       prod = prod.mul(ex_to<matrix>(*it));
                        it++;
                }
                delete s;
index 361deff..b0fbbee 100644 (file)
@@ -89,7 +89,7 @@ ex simplified_ncmul(const exvector & v);
 
 // utility functions
 
-/** Return the ncmul object handled by an ex.
+/** Return the ncmul object handled by an ex.  Deprecated: use ex_to<ncmul>().
  *  This is unsafe: you need to check the type first. */
 inline const ncmul &ex_to_ncmul(const ex &e)
 {
index f985573..18e24e9 100644 (file)
@@ -228,7 +228,7 @@ static void get_symbol_stats(const ex &a, const ex &b, sym_desc_vec &v)
 static numeric lcmcoeff(const ex &e, const numeric &l)
 {
        if (e.info(info_flags::rational))
-               return lcm(ex_to_numeric(e).denom(), l);
+               return lcm(ex_to<numeric>(e).denom(), l);
        else if (is_ex_exactly_of_type(e, add)) {
                numeric c = _num1();
                for (unsigned i=0; i<e.nops(); i++)
@@ -243,7 +243,7 @@ static numeric lcmcoeff(const ex &e, const numeric &l)
                if (is_ex_exactly_of_type(e.op(0), symbol))
                        return l;
                else
-                       return pow(lcmcoeff(e.op(0), l), ex_to_numeric(e.op(1)));
+                       return pow(lcmcoeff(e.op(0), l), ex_to<numeric>(e.op(1)));
        }
        return l;
 }
@@ -286,7 +286,7 @@ static ex multiply_lcm(const ex &e, const numeric &lcm)
                if (is_ex_exactly_of_type(e.op(0), symbol))
                        return e * lcm;
                else
-                       return pow(multiply_lcm(e.op(0), lcm.power(ex_to_numeric(e.op(1)).inverse())), e.op(1));
+                       return pow(multiply_lcm(e.op(0), lcm.power(ex_to<numeric>(e.op(1)).inverse())), e.op(1));
        } else
                return e * lcm;
 }
@@ -321,11 +321,11 @@ numeric add::integer_content(void) const
        while (it != itend) {
                GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
                GINAC_ASSERT(is_ex_exactly_of_type(it->coeff,numeric));
-               c = gcd(ex_to_numeric(it->coeff), c);
+               c = gcd(ex_to<numeric>(it->coeff), c);
                it++;
        }
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
-       c = gcd(ex_to_numeric(overall_coeff),c);
+       c = gcd(ex_to<numeric>(overall_coeff),c);
        return c;
 }
 
@@ -340,7 +340,7 @@ numeric mul::integer_content(void) const
        }
 #endif // def DO_GINAC_ASSERT
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
-       return abs(ex_to_numeric(overall_coeff));
+       return abs(ex_to<numeric>(overall_coeff));
 }
 
 
@@ -1204,11 +1204,11 @@ numeric add::max_coefficient(void) const
        epvector::const_iterator it = seq.begin();
        epvector::const_iterator itend = seq.end();
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
-       numeric cur_max = abs(ex_to_numeric(overall_coeff));
+       numeric cur_max = abs(ex_to<numeric>(overall_coeff));
        while (it != itend) {
                numeric a;
                GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
-               a = abs(ex_to_numeric(it->coeff));
+               a = abs(ex_to<numeric>(it->coeff));
                if (a > cur_max)
                        cur_max = a;
                it++;
@@ -1227,7 +1227,7 @@ numeric mul::max_coefficient(void) const
        }
 #endif // def DO_GINAC_ASSERT
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
-       return abs(ex_to_numeric(overall_coeff));
+       return abs(ex_to<numeric>(overall_coeff));
 }
 
 
@@ -1262,13 +1262,13 @@ ex add::smod(const numeric &xi) const
        epvector::const_iterator itend = seq.end();
        while (it != itend) {
                GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
-               numeric coeff = GiNaC::smod(ex_to_numeric(it->coeff), xi);
+               numeric coeff = GiNaC::smod(ex_to<numeric>(it->coeff), xi);
                if (!coeff.is_zero())
                        newseq.push_back(expair(it->rest, coeff));
                it++;
        }
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
-       numeric coeff = GiNaC::smod(ex_to_numeric(overall_coeff), xi);
+       numeric coeff = GiNaC::smod(ex_to<numeric>(overall_coeff), xi);
        return (new add(newseq,coeff))->setflag(status_flags::dynallocated);
 }
 
@@ -1284,7 +1284,7 @@ ex mul::smod(const numeric &xi) const
 #endif // def DO_GINAC_ASSERT
        mul * mulcopyp = new mul(*this);
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
-       mulcopyp->overall_coeff = GiNaC::smod(ex_to_numeric(overall_coeff),xi);
+       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);
@@ -1336,11 +1336,11 @@ static ex heur_gcd(const ex &a, const ex &b, ex *ca, ex *cb, sym_desc_vec::const
 
        // GCD of two numeric values -> CLN
        if (is_ex_exactly_of_type(a, numeric) && is_ex_exactly_of_type(b, numeric)) {
-               numeric g = gcd(ex_to_numeric(a), ex_to_numeric(b));
+               numeric g = gcd(ex_to<numeric>(a), ex_to<numeric>(b));
                if (ca)
-                       *ca = ex_to_numeric(a) / g;
+                       *ca = ex_to<numeric>(a) / g;
                if (cb)
-                       *cb = ex_to_numeric(b) / g;
+                       *cb = ex_to<numeric>(b) / g;
                return g;
        }
 
@@ -1386,7 +1386,7 @@ static ex heur_gcd(const ex &a, const ex &b, ex *ca, ex *cb, sym_desc_vec::const
                        if (divide_in_z(p, g, ca ? *ca : dummy, var) && divide_in_z(q, g, cb ? *cb : dummy, var)) {
                                g *= gc;
                                ex lc = g.lcoeff(x);
-                               if (is_ex_exactly_of_type(lc, numeric) && ex_to_numeric(lc).is_negative())
+                               if (is_ex_exactly_of_type(lc, numeric) && ex_to<numeric>(lc).is_negative())
                                        return -g;
                                else
                                        return g;
@@ -1399,7 +1399,7 @@ static ex heur_gcd(const ex &a, const ex &b, ex *ca, ex *cb, sym_desc_vec::const
                                        if (ca)
                                                *ca = cp;
                                        ex lc = g.lcoeff(x);
-                                       if (is_ex_exactly_of_type(lc, numeric) && ex_to_numeric(lc).is_negative())
+                                       if (is_ex_exactly_of_type(lc, numeric) && ex_to<numeric>(lc).is_negative())
                                                return -g;
                                        else
                                                return g;
@@ -1412,7 +1412,7 @@ static ex heur_gcd(const ex &a, const ex &b, ex *ca, ex *cb, sym_desc_vec::const
                                        if (cb)
                                                *cb = cq;
                                        ex lc = g.lcoeff(x);
-                                       if (is_ex_exactly_of_type(lc, numeric) && ex_to_numeric(lc).is_negative())
+                                       if (is_ex_exactly_of_type(lc, numeric) && ex_to<numeric>(lc).is_negative())
                                                return -g;
                                        else
                                                return g;
@@ -1445,7 +1445,7 @@ ex gcd(const ex &a, const ex &b, ex *ca, ex *cb, bool check_args)
 
        // GCD of numerics -> CLN
        if (is_ex_exactly_of_type(a, numeric) && is_ex_exactly_of_type(b, numeric)) {
-               numeric g = gcd(ex_to_numeric(a), ex_to_numeric(b));
+               numeric g = gcd(ex_to<numeric>(a), ex_to<numeric>(b));
                if (ca || cb) {
                        if (g.is_zero()) {
                                if (ca)
@@ -1454,9 +1454,9 @@ ex gcd(const ex &a, const ex &b, ex *ca, ex *cb, bool check_args)
                                        *cb = _ex0();
                        } else {
                                if (ca)
-                                       *ca = ex_to_numeric(a) / g;
+                                       *ca = ex_to<numeric>(a) / g;
                                if (cb)
-                                       *cb = ex_to_numeric(b) / g;
+                                       *cb = ex_to<numeric>(b) / g;
                        }
                }
                return g;
@@ -1676,7 +1676,7 @@ factored_b:
 ex lcm(const ex &a, const ex &b, bool check_args)
 {
        if (is_ex_exactly_of_type(a, numeric) && is_ex_exactly_of_type(b, numeric))
-               return lcm(ex_to_numeric(a), ex_to_numeric(b));
+               return lcm(ex_to<numeric>(a), ex_to<numeric>(b));
        if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
                throw(std::invalid_argument("lcm: arguments must be polynomials over the rationals"));
        
@@ -1742,7 +1742,7 @@ ex sqrfree(const ex &a, const lst &l)
        // Find the symbol to factor in at this stage
        if (!is_ex_of_type(args.op(0), symbol))
                throw (std::runtime_error("sqrfree(): invalid factorization variable"));
-       const symbol x = ex_to_symbol(args.op(0));
+       const symbol x = ex_to<symbol>(args.op(0));
        // convert the argument from something in Q[X] to something in Z[X]
        numeric lcm = lcm_of_coefficients_denominators(a);
        ex tmp = multiply_lcm(a,lcm);
@@ -1908,7 +1908,7 @@ static ex frac_cancel(const ex &n, const ex &d)
        const symbol *x;
        if (get_first_symbol(den, x)) {
                GINAC_ASSERT(is_ex_exactly_of_type(den.unit(*x),numeric));
-               if (ex_to_numeric(den.unit(*x)).is_negative()) {
+               if (ex_to<numeric>(den.unit(*x)).is_negative()) {
                        num *= _ex_1();
                        den *= _ex_1();
                }
index d727fe3..71781f4 100644 (file)
@@ -286,7 +286,7 @@ ex CatalanEvalf(void);
 
 // utility functions
 
-/** Return the numeric object handled by an ex.
+/** Return the numeric object handled by an ex.  Deprecated: use ex_to<numeric>().
  *  This is unsafe: you need to check the type first. */
 inline const numeric &ex_to_numeric(const ex &e)
 {
index 05b6d1c..97b0f6f 100644 (file)
@@ -142,7 +142,7 @@ void power::print(const print_context & c, unsigned level) const
                // Integer powers of symbols are printed in a special, optimized way
                if (exponent.info(info_flags::integer)
                 && (is_exactly_a<symbol>(basis) || is_exactly_a<constant>(basis))) {
-                       int exp = ex_to_numeric(exponent).to_int();
+                       int exp = ex_to<numeric>(exponent).to_int();
                        if (exp > 0)
                                c.s << '(';
                        else {
@@ -152,7 +152,7 @@ void power::print(const print_context & c, unsigned level) const
                                else
                                        c.s << "1.0/(";
                        }
-                       print_sym_pow(c, ex_to_symbol(basis), exp);
+                       print_sym_pow(c, ex_to<symbol>(basis), exp);
                        c.s << ')';
 
                // <expr>^-1 is printed as "1.0/<expr>" or with the recip() function of CLN
@@ -252,12 +252,12 @@ int power::degree(const ex & s) const
 {
        if (is_exactly_of_type(*exponent.bp,numeric)) {
                if (basis.is_equal(s)) {
-                       if (ex_to_numeric(exponent).is_integer())
-                               return ex_to_numeric(exponent).to_int();
+                       if (ex_to<numeric>(exponent).is_integer())
+                               return ex_to<numeric>(exponent).to_int();
                        else
                                return 0;
                } else
-                       return basis.degree(s) * ex_to_numeric(exponent).to_int();
+                       return basis.degree(s) * ex_to<numeric>(exponent).to_int();
        }
        return 0;
 }
@@ -266,12 +266,12 @@ int power::ldegree(const ex & s) const
 {
        if (is_exactly_of_type(*exponent.bp,numeric)) {
                if (basis.is_equal(s)) {
-                       if (ex_to_numeric(exponent).is_integer())
-                               return ex_to_numeric(exponent).to_int();
+                       if (ex_to<numeric>(exponent).is_integer())
+                               return ex_to<numeric>(exponent).to_int();
                        else
                                return 0;
                } else
-                       return basis.ldegree(s) * ex_to_numeric(exponent).to_int();
+                       return basis.ldegree(s) * ex_to<numeric>(exponent).to_int();
        }
        return 0;
 }
@@ -286,9 +286,9 @@ ex power::coeff(const ex & s, int n) const
                        return _ex0();
        } else {
                // basis equal to s
-               if (is_exactly_of_type(*exponent.bp, numeric) && ex_to_numeric(exponent).is_integer()) {
+               if (is_exactly_of_type(*exponent.bp, numeric) && ex_to<numeric>(exponent).is_integer()) {
                        // integer exponent
-                       int int_exp = ex_to_numeric(exponent).to_int();
+                       int int_exp = ex_to<numeric>(exponent).to_int();
                        if (n == int_exp)
                                return _ex1();
                        else
@@ -406,11 +406,11 @@ ex power::eval(int level) const
                // (c1, c2 numeric(), c2 integer or -1 < c1 <= 1,
                // case c1==1 should not happen, see below!)
                if (is_ex_exactly_of_type(ebasis,power)) {
-                       const power & sub_power = ex_to_power(ebasis);
+                       const power & sub_power = ex_to<power>(ebasis);
                        const ex & sub_basis = sub_power.basis;
                        const ex & sub_exponent = sub_power.exponent;
                        if (is_ex_exactly_of_type(sub_exponent,numeric)) {
-                               const numeric & num_sub_exponent = ex_to_numeric(sub_exponent);
+                               const numeric & num_sub_exponent = ex_to<numeric>(sub_exponent);
                                GINAC_ASSERT(num_sub_exponent!=numeric(1));
                                if (num_exponent->is_integer() || (abs(num_sub_exponent) - _num1()).is_negative())
                                        return power(sub_basis,num_sub_exponent.mul(*num_exponent));
@@ -419,16 +419,16 @@ ex power::eval(int level) const
        
                // ^(*(x,y,z),c1) -> *(x^c1,y^c1,z^c1) (c1 integer)
                if (num_exponent->is_integer() && is_ex_exactly_of_type(ebasis,mul)) {
-                       return expand_mul(ex_to_mul(ebasis), *num_exponent);
+                       return expand_mul(ex_to<mul>(ebasis), *num_exponent);
                }
        
                // ^(*(...,x;c1),c2) -> ^(*(...,x;1),c2)*c1^c2 (c1, c2 numeric(), c1>0)
                // ^(*(...,x,c1),c2) -> ^(*(...,x;-1),c2)*(-c1)^c2 (c1, c2 numeric(), c1<0)
                if (is_ex_exactly_of_type(ebasis,mul)) {
                        GINAC_ASSERT(!num_exponent->is_integer()); // should have been handled above
-                       const mul & mulref = ex_to_mul(ebasis);
+                       const mul & mulref = ex_to<mul>(ebasis);
                        if (!mulref.overall_coeff.is_equal(_ex1())) {
-                               const numeric & num_coeff = ex_to_numeric(mulref.overall_coeff);
+                               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);
@@ -497,7 +497,7 @@ ex power::evalm(void) const
        ex eexponent = exponent.evalm();
        if (is_ex_of_type(ebasis,matrix)) {
                if (is_ex_of_type(eexponent,numeric)) {
-                       return (new matrix(ex_to_matrix(ebasis).pow(eexponent)))->setflag(status_flags::dynallocated);
+                       return (new matrix(ex_to<matrix>(ebasis).pow(eexponent)))->setflag(status_flags::dynallocated);
                }
        }
        return (new power(ebasis, eexponent))->setflag(status_flags::dynallocated);
@@ -574,7 +574,7 @@ ex power::expand(unsigned options) const
        
        // x^(a+b) -> x^a * x^b
        if (is_ex_exactly_of_type(expanded_exponent, add)) {
-               const add &a = ex_to_add(expanded_exponent);
+               const add &a = ex_to<add>(expanded_exponent);
                exvector distrseq;
                distrseq.reserve(a.seq.size() + 1);
                epvector::const_iterator last = a.seq.end();
@@ -585,11 +585,11 @@ ex power::expand(unsigned options) const
                }
                
                // Make sure that e.g. (x+y)^(2+a) expands the (x+y)^2 factor
-               if (ex_to_numeric(a.overall_coeff).is_integer()) {
-                       const numeric &num_exponent = ex_to_numeric(a.overall_coeff);
+               if (ex_to<numeric>(a.overall_coeff).is_integer()) {
+                       const numeric &num_exponent = ex_to<numeric>(a.overall_coeff);
                        int int_exponent = num_exponent.to_int();
                        if (int_exponent > 0 && is_ex_exactly_of_type(expanded_basis, add))
-                               distrseq.push_back(expand_add(ex_to_add(expanded_basis), int_exponent));
+                               distrseq.push_back(expand_add(ex_to<add>(expanded_basis), int_exponent));
                        else
                                distrseq.push_back(power(expanded_basis, a.overall_coeff));
                } else
@@ -601,7 +601,7 @@ ex power::expand(unsigned options) const
        }
        
        if (!is_ex_exactly_of_type(expanded_exponent, numeric) ||
-               !ex_to_numeric(expanded_exponent).is_integer()) {
+               !ex_to<numeric>(expanded_exponent).is_integer()) {
                if (are_ex_trivially_equal(basis,expanded_basis) && are_ex_trivially_equal(exponent,expanded_exponent)) {
                        return this->hold();
                } else {
@@ -610,16 +610,16 @@ ex power::expand(unsigned options) const
        }
        
        // integer numeric exponent
-       const numeric & num_exponent = ex_to_numeric(expanded_exponent);
+       const numeric & num_exponent = ex_to<numeric>(expanded_exponent);
        int int_exponent = num_exponent.to_int();
        
        // (x+y)^n, n>0
        if (int_exponent > 0 && is_ex_exactly_of_type(expanded_basis,add))
-               return expand_add(ex_to_add(expanded_basis), int_exponent);
+               return expand_add(ex_to<add>(expanded_basis), int_exponent);
        
        // (x*y)^n -> x^n * y^n
        if (is_ex_exactly_of_type(expanded_basis,mul))
-               return expand_mul(ex_to_mul(expanded_basis), num_exponent);
+               return expand_mul(ex_to<mul>(expanded_basis), num_exponent);
        
        // cannot expand further
        if (are_ex_trivially_equal(basis,expanded_basis) && are_ex_trivially_equal(exponent,expanded_exponent))
@@ -666,13 +666,13 @@ ex power::expand_add(const add & a, int n) const
                        const ex & b = a.op(l);
                        GINAC_ASSERT(!is_ex_exactly_of_type(b,add));
                        GINAC_ASSERT(!is_ex_exactly_of_type(b,power) ||
-                                    !is_ex_exactly_of_type(ex_to_power(b).exponent,numeric) ||
-                                    !ex_to_numeric(ex_to_power(b).exponent).is_pos_integer() ||
-                                    !is_ex_exactly_of_type(ex_to_power(b).basis,add) ||
-                                    !is_ex_exactly_of_type(ex_to_power(b).basis,mul) ||
-                                    !is_ex_exactly_of_type(ex_to_power(b).basis,power));
+                                    !is_ex_exactly_of_type(ex_to<power>(b).exponent,numeric) ||
+                                    !ex_to<numeric>(ex_to<power>(b).exponent).is_pos_integer() ||
+                                    !is_ex_exactly_of_type(ex_to<power>(b).basis,add) ||
+                                    !is_ex_exactly_of_type(ex_to<power>(b).basis,mul) ||
+                                    !is_ex_exactly_of_type(ex_to<power>(b).basis,power));
                        if (is_ex_exactly_of_type(b,mul))
-                               term.push_back(expand_mul(ex_to_mul(b),numeric(k[l])));
+                               term.push_back(expand_mul(ex_to<mul>(b),numeric(k[l])));
                        else
                                term.push_back(power(b,k[l]));
                }
@@ -680,13 +680,13 @@ ex power::expand_add(const add & a, int n) const
                const ex & b = a.op(l);
                GINAC_ASSERT(!is_ex_exactly_of_type(b,add));
                GINAC_ASSERT(!is_ex_exactly_of_type(b,power) ||
-                            !is_ex_exactly_of_type(ex_to_power(b).exponent,numeric) ||
-                            !ex_to_numeric(ex_to_power(b).exponent).is_pos_integer() ||
-                            !is_ex_exactly_of_type(ex_to_power(b).basis,add) ||
-                            !is_ex_exactly_of_type(ex_to_power(b).basis,mul) ||
-                            !is_ex_exactly_of_type(ex_to_power(b).basis,power));
+                            !is_ex_exactly_of_type(ex_to<power>(b).exponent,numeric) ||
+                            !ex_to<numeric>(ex_to<power>(b).exponent).is_pos_integer() ||
+                            !is_ex_exactly_of_type(ex_to<power>(b).basis,add) ||
+                            !is_ex_exactly_of_type(ex_to<power>(b).basis,mul) ||
+                            !is_ex_exactly_of_type(ex_to<power>(b).basis,power));
                if (is_ex_exactly_of_type(b,mul))
-                       term.push_back(expand_mul(ex_to_mul(b),numeric(n-k_cum[m-2])));
+                       term.push_back(expand_mul(ex_to<mul>(b),numeric(n-k_cum[m-2])));
                else
                        term.push_back(power(b,n-k_cum[m-2]));
                
@@ -752,15 +752,15 @@ ex power::expand_add_2(const add & a) const
                
                GINAC_ASSERT(!is_ex_exactly_of_type(r,add));
                GINAC_ASSERT(!is_ex_exactly_of_type(r,power) ||
-                            !is_ex_exactly_of_type(ex_to_power(r).exponent,numeric) ||
-                            !ex_to_numeric(ex_to_power(r).exponent).is_pos_integer() ||
-                            !is_ex_exactly_of_type(ex_to_power(r).basis,add) ||
-                            !is_ex_exactly_of_type(ex_to_power(r).basis,mul) ||
-                            !is_ex_exactly_of_type(ex_to_power(r).basis,power));
+                            !is_ex_exactly_of_type(ex_to<power>(r).exponent,numeric) ||
+                            !ex_to<numeric>(ex_to<power>(r).exponent).is_pos_integer() ||
+                            !is_ex_exactly_of_type(ex_to<power>(r).basis,add) ||
+                            !is_ex_exactly_of_type(ex_to<power>(r).basis,mul) ||
+                            !is_ex_exactly_of_type(ex_to<power>(r).basis,power));
                
                if (are_ex_trivially_equal(c,_ex1())) {
                        if (is_ex_exactly_of_type(r,mul)) {
-                               sum.push_back(expair(expand_mul(ex_to_mul(r),_num2()),
+                               sum.push_back(expair(expand_mul(ex_to<mul>(r),_num2()),
                                                     _ex1()));
                        } else {
                                sum.push_back(expair((new power(r,_ex2()))->setflag(status_flags::dynallocated),
@@ -768,11 +768,11 @@ ex power::expand_add_2(const add & a) const
                        }
                } else {
                        if (is_ex_exactly_of_type(r,mul)) {
-                               sum.push_back(expair(expand_mul(ex_to_mul(r),_num2()),
-                                                    ex_to_numeric(c).power_dyn(_num2())));
+                               sum.push_back(expair(expand_mul(ex_to<mul>(r),_num2()),
+                                                    ex_to<numeric>(c).power_dyn(_num2())));
                        } else {
                                sum.push_back(expair((new power(r,_ex2()))->setflag(status_flags::dynallocated),
-                                                    ex_to_numeric(c).power_dyn(_num2())));
+                                                    ex_to<numeric>(c).power_dyn(_num2())));
                        }
                }
                        
@@ -780,7 +780,7 @@ ex power::expand_add_2(const add & a) const
                        const ex & r1 = (*cit1).rest;
                        const ex & c1 = (*cit1).coeff;
                        sum.push_back(a.combine_ex_with_coeff_to_pair((new mul(r,r1))->setflag(status_flags::dynallocated),
-                                                                     _num2().mul(ex_to_numeric(c)).mul_dyn(ex_to_numeric(c1))));
+                                                                     _num2().mul(ex_to<numeric>(c)).mul_dyn(ex_to<numeric>(c1))));
                }
        }
        
@@ -789,9 +789,9 @@ ex power::expand_add_2(const add & a) const
        // second part: add terms coming from overall_factor (if != 0)
        if (!a.overall_coeff.is_zero()) {
                for (epvector::const_iterator cit=a.seq.begin(); cit!=a.seq.end(); ++cit) {
-                       sum.push_back(a.combine_pair_with_coeff_to_pair(*cit,ex_to_numeric(a.overall_coeff).mul_dyn(_num2())));
+                       sum.push_back(a.combine_pair_with_coeff_to_pair(*cit,ex_to<numeric>(a.overall_coeff).mul_dyn(_num2())));
                }
-               sum.push_back(expair(ex_to_numeric(a.overall_coeff).power_dyn(_num2()),_ex1()));
+               sum.push_back(expair(ex_to<numeric>(a.overall_coeff).power_dyn(_num2()),_ex1()));
        }
        
        GINAC_ASSERT(sum.size()==(a_nops*(a_nops+1))/2);
@@ -816,11 +816,11 @@ ex power::expand_mul(const mul & m, const numeric & n) const
                } else {
                        // it is safe not to call mul::combine_pair_with_coeff_to_pair()
                        // since n is an integer
-                       distrseq.push_back(expair((*cit).rest, ex_to_numeric((*cit).coeff).mul(n)));
+                       distrseq.push_back(expair((*cit).rest, ex_to<numeric>((*cit).coeff).mul(n)));
                }
                ++cit;
        }
-       return (new mul(distrseq,ex_to_numeric(m.overall_coeff).power_dyn(n)))->setflag(status_flags::dynallocated);
+       return (new mul(distrseq,ex_to<numeric>(m.overall_coeff).power_dyn(n)))->setflag(status_flags::dynallocated);
 }
 
 /*
index 23a7a4e..049d55d 100644 (file)
@@ -93,7 +93,7 @@ protected:
 
 // utility functions
 
-/** Return the power object handled by an ex.
+/** Return the power object handled by an ex.  Deprecated: use ex_to<power>().
  *  This is unsafe: you need to check the type first. */
 inline const power &ex_to_power(const ex &e)
 {
index d7f7847..37f2958 100644 (file)
@@ -263,7 +263,7 @@ int pseries::degree(const ex &s) const
        if (var.is_equal(s)) {
                // Return last exponent
                if (seq.size())
-                       return ex_to_numeric((*(seq.end() - 1)).coeff).to_int();
+                       return ex_to<numeric>((*(seq.end() - 1)).coeff).to_int();
                else
                        return 0;
        } else {
@@ -291,7 +291,7 @@ int pseries::ldegree(const ex &s) const
        if (var.is_equal(s)) {
                // Return first exponent
                if (seq.size())
-                       return ex_to_numeric((*(seq.begin())).coeff).to_int();
+                       return ex_to<numeric>((*(seq.begin())).coeff).to_int();
                else
                        return 0;
        } else {
@@ -328,7 +328,7 @@ ex pseries::coeff(const ex &s, int n) const
                while (lo <= hi) {
                        int mid = (lo + hi) / 2;
                        GINAC_ASSERT(is_ex_exactly_of_type(seq[mid].coeff, numeric));
-                       int cmp = ex_to_numeric(seq[mid].coeff).compare(looking_for);
+                       int cmp = ex_to<numeric>(seq[mid].coeff).compare(looking_for);
                        switch (cmp) {
                                case -1:
                                        lo = mid + 1;
@@ -566,7 +566,7 @@ ex pseries::add_series(const pseries &other) const
                        }
                        break;
                } else
-                       pow_a = ex_to_numeric((*a).coeff).to_int();
+                       pow_a = ex_to<numeric>((*a).coeff).to_int();
                
                // If b is empty, fill up with elements from a and stop
                if (b == b_end) {
@@ -576,7 +576,7 @@ ex pseries::add_series(const pseries &other) const
                        }
                        break;
                } else
-                       pow_b = ex_to_numeric((*b).coeff).to_int();
+                       pow_b = ex_to<numeric>((*b).coeff).to_int();
                
                // a and b are non-empty, compare powers
                if (pow_a < pow_b) {
@@ -629,10 +629,10 @@ ex add::series(const relational & r, int order, unsigned options) const
                else
                        op = it->rest.series(r, order, options);
                if (!it->coeff.is_equal(_ex1()))
-                       op = ex_to_pseries(op).mul_const(ex_to_numeric(it->coeff));
+                       op = ex_to<pseries>(op).mul_const(ex_to<numeric>(it->coeff));
                
                // Series addition
-               acc = ex_to_pseries(acc).add_series(ex_to_pseries(op));
+               acc = ex_to<pseries>(acc).add_series(ex_to<pseries>(op));
        }
        return acc;
 }
@@ -731,15 +731,15 @@ ex mul::series(const relational & r, int order, unsigned options) const
                if (op.info(info_flags::numeric)) {
                        // series * const (special case, faster)
                        ex f = power(op, it->coeff);
-                       acc = ex_to_pseries(acc).mul_const(ex_to_numeric(f));
+                       acc = ex_to<pseries>(acc).mul_const(ex_to<numeric>(f));
                        continue;
                } else if (!is_ex_exactly_of_type(op, pseries))
                        op = op.series(r, order, options);
                if (!it->coeff.is_equal(_ex1()))
-                       op = ex_to_pseries(op).power_const(ex_to_numeric(it->coeff), order);
+                       op = ex_to<pseries>(op).power_const(ex_to<numeric>(it->coeff), order);
 
                // Series multiplication
-               acc = ex_to_pseries(acc).mul_series(ex_to_pseries(op));
+               acc = ex_to<pseries>(acc).mul_series(ex_to<pseries>(op));
        }
        return acc;
 }
@@ -862,7 +862,7 @@ ex power::series(const relational & r, int order, unsigned options) const
        }
        
        // Power e
-       return ex_to_pseries(e).power_const(ex_to_numeric(exponent), order);
+       return ex_to<pseries>(e).power_const(ex_to<numeric>(exponent), order);
 }
 
 
@@ -880,7 +880,7 @@ ex pseries::series(const relational & r, int order, unsigned options) const
                        epvector new_seq;
                        epvector::const_iterator it = seq.begin(), itend = seq.end();
                        while (it != itend) {
-                               int o = ex_to_numeric(it->coeff).to_int();
+                               int o = ex_to<numeric>(it->coeff).to_int();
                                if (o >= order) {
                                        new_seq.push_back(expair(Order(_ex1()), o));
                                        break;
@@ -911,7 +911,7 @@ ex ex::series(const ex & r, int order, unsigned options) const
        relational rel_;
        
        if (is_ex_exactly_of_type(r,relational))
-               rel_ = ex_to_relational(r);
+               rel_ = ex_to<relational>(r);
        else if (is_ex_exactly_of_type(r,symbol))
                rel_ = relational(r,_ex0());
        else
index d539b70..82b4bb9 100644 (file)
@@ -263,7 +263,7 @@ relational::operator bool() const
                // cannot decide on non-numerical results
                return o==not_equal ? true : false;
        
-       int cmpval = ex_to_numeric(df).compare(_num0());
+       int cmpval = ex_to<numeric>(df).compare(_num0());
        switch (o) {
        case equal:
                return cmpval==0;
index 79f3cf3..a5188b5 100644 (file)
@@ -83,7 +83,7 @@ protected:
 
 // utility functions
 
-/** Return the relational object handled by an ex.
+/** Return the relational object handled by an ex.  Deprecated: use ex_to<relational>().
  *  This is unsafe: you need to check the type first. */
 inline const relational &ex_to_relational(const ex &e)
 {
index 901c572..8b64454 100755 (executable)
@@ -209,10 +209,6 @@ extern const ${STRUCTURE} some_${STRUCTURE};
 extern const type_info & typeid_${STRUCTURE};
 extern const unsigned tinfo_${STRUCTURE};
 
-// macros
-
-#define ex_to_${STRUCTURE}(X) (static_cast<${STRUCTURE} const &>(*(X).bp))
-
 } // namespace GiNaC
 
 #endif // ndef _${STRUCTURE_UC}_H_
index 73e0761..ea453a9 100644 (file)
@@ -121,7 +121,7 @@ ex symbol::unarchive(const archive_node &n, const lst &sym_lst)
        
        // If symbol is in sym_lst, return the existing symbol
        for (unsigned i=0; i<sym_lst.nops(); i++) {
-               if (is_ex_of_type(sym_lst.op(i), symbol) && (ex_to_symbol(sym_lst.op(i)).name == ex_to_symbol(s).name))
+               if (is_ex_of_type(sym_lst.op(i), symbol) && (ex_to<symbol>(sym_lst.op(i)).name == ex_to<symbol>(s).name))
                        return sym_lst.op(i);
        }
        return s;
index df6a9fd..69d9b9e 100644 (file)
@@ -116,7 +116,7 @@ private:
 
 // utility functions
 
-/** Return the symbol object handled by an ex.
+/** Return the symbol object handled by an ex.  Deprecated: use ex_to<symbol>().
  *  This is unsafe: you need to check the type first. */
 inline const symbol &ex_to_symbol(const ex &e)
 {
index db05580..ab31838 100644 (file)
@@ -95,7 +95,7 @@ symmetry::symmetry(const archive_node &n, const lst &sym_lst) : inherited(n, sym
        while (true) {
                ex e;
                if (n.find_ex("child", e, sym_lst, i))
-                       add(ex_to_symmetry(e));
+                       add(ex_to<symmetry>(e));
                else
                        break;
                i++;
@@ -185,7 +185,7 @@ symmetry &symmetry::add(const symmetry &c)
        // All children must have the same number of indices
        if (type != none && !children.empty()) {
                GINAC_ASSERT(is_ex_exactly_of_type(children[0], symmetry));
-               if (ex_to_symmetry(children[0]).indices.size() != c.indices.size())
+               if (ex_to<symmetry>(children[0]).indices.size() != c.indices.size())
                        throw (std::logic_error("symmetry:add(): children must have same number of indices"));
        }
 
@@ -227,8 +227,8 @@ public:
        {
                GINAC_ASSERT(is_ex_exactly_of_type(lh, symmetry));
                GINAC_ASSERT(is_ex_exactly_of_type(rh, symmetry));
-               GINAC_ASSERT(ex_to_symmetry(lh).indices.size() == ex_to_symmetry(rh).indices.size());
-               std::set<unsigned>::const_iterator ait = ex_to_symmetry(lh).indices.begin(), aitend = ex_to_symmetry(lh).indices.end(), bit = ex_to_symmetry(rh).indices.begin();
+               GINAC_ASSERT(ex_to<symmetry>(lh).indices.size() == ex_to<symmetry>(rh).indices.size());
+               std::set<unsigned>::const_iterator ait = ex_to<symmetry>(lh).indices.begin(), aitend = ex_to<symmetry>(lh).indices.end(), bit = ex_to<symmetry>(rh).indices.begin();
                while (ait != aitend) {
                        int cmpval = v[*ait].compare(v[*bit]);
                        if (cmpval < 0)
@@ -253,8 +253,8 @@ public:
        {
                GINAC_ASSERT(is_ex_exactly_of_type(lh, symmetry));
                GINAC_ASSERT(is_ex_exactly_of_type(rh, symmetry));
-               GINAC_ASSERT(ex_to_symmetry(lh).indices.size() == ex_to_symmetry(rh).indices.size());
-               std::set<unsigned>::const_iterator ait = ex_to_symmetry(lh).indices.begin(), aitend = ex_to_symmetry(lh).indices.end(), bit = ex_to_symmetry(rh).indices.begin();
+               GINAC_ASSERT(ex_to<symmetry>(lh).indices.size() == ex_to<symmetry>(rh).indices.size());
+               std::set<unsigned>::const_iterator ait = ex_to<symmetry>(lh).indices.begin(), aitend = ex_to<symmetry>(lh).indices.end(), bit = ex_to<symmetry>(rh).indices.begin();
                while (ait != aitend) {
                        v[*ait].swap(v[*bit]);
                        ++ait; ++bit;
@@ -275,7 +275,7 @@ int canonicalize(exvector::iterator v, const symmetry &symm)
        exvector::const_iterator first = symm.children.begin(), last = symm.children.end();
        while (first != last) {
                GINAC_ASSERT(is_ex_exactly_of_type(*first, symmetry));
-               int child_sign = canonicalize(v, ex_to_symmetry(*first));
+               int child_sign = canonicalize(v, ex_to<symmetry>(*first));
                if (child_sign == 0)
                        return 0;
                if (child_sign != INT_MAX) {
index 405ba31..21ab09f 100644 (file)
@@ -99,11 +99,6 @@ private:
 
 
 // global functions
-inline const symmetry &ex_to_symmetry(const ex &e)
-{
-       return static_cast<const symmetry &>(*e.bp);
-}
-
 inline symmetry &ex_to_nonconst_symmetry(const ex &e)
 {
        return static_cast<symmetry &>(*e.bp);
index 4a10f54..0991f58 100644 (file)
@@ -187,8 +187,8 @@ ex tensdelta::eval_indexed(const basic & i) const
        GINAC_ASSERT(i.nops() == 3);
        GINAC_ASSERT(is_ex_of_type(i.op(0), tensdelta));
 
-       const idx & i1 = ex_to_idx(i.op(1));
-       const idx & i2 = ex_to_idx(i.op(2));
+       const idx & i1 = ex_to<idx>(i.op(1));
+       const idx & i2 = ex_to<idx>(i.op(2));
 
        // Trace of delta tensor is the dimension of the space
        if (is_dummy_pair(i1, i2))
@@ -196,7 +196,7 @@ ex tensdelta::eval_indexed(const basic & i) const
 
        // Numeric evaluation
        if (static_cast<const indexed &>(i).all_index_values_are(info_flags::integer)) {
-               int n1 = ex_to_numeric(i1.get_value()).to_int(), n2 = ex_to_numeric(i2.get_value()).to_int();
+               int n1 = ex_to<numeric>(i1.get_value()).to_int(), n2 = ex_to<numeric>(i2.get_value()).to_int();
                if (n1 == n2)
                        return _ex1();
                else
@@ -216,8 +216,8 @@ ex tensmetric::eval_indexed(const basic & i) const
        GINAC_ASSERT(is_ex_of_type(i.op(1), varidx));
        GINAC_ASSERT(is_ex_of_type(i.op(2), varidx));
 
-       const varidx & i1 = ex_to_varidx(i.op(1));
-       const varidx & i2 = ex_to_varidx(i.op(2));
+       const varidx & i1 = ex_to<varidx>(i.op(1));
+       const varidx & i2 = ex_to<varidx>(i.op(2));
 
        // A metric tensor with one covariant and one contravariant index gets
        // replaced by a delta tensor
@@ -237,12 +237,12 @@ ex minkmetric::eval_indexed(const basic & i) const
        GINAC_ASSERT(is_ex_of_type(i.op(1), varidx));
        GINAC_ASSERT(is_ex_of_type(i.op(2), varidx));
 
-       const varidx & i1 = ex_to_varidx(i.op(1));
-       const varidx & i2 = ex_to_varidx(i.op(2));
+       const varidx & i1 = ex_to<varidx>(i.op(1));
+       const varidx & i2 = ex_to<varidx>(i.op(2));
 
        // Numeric evaluation
        if (static_cast<const indexed &>(i).all_index_values_are(info_flags::nonnegint)) {
-               int n1 = ex_to_numeric(i1.get_value()).to_int(), n2 = ex_to_numeric(i2.get_value()).to_int();
+               int n1 = ex_to<numeric>(i1.get_value()).to_int(), n2 = ex_to<numeric>(i2.get_value()).to_int();
                if (n1 != n2)
                        return _ex0();
                else if (n1 == 0)
@@ -264,8 +264,8 @@ ex spinmetric::eval_indexed(const basic & i) const
        GINAC_ASSERT(is_ex_of_type(i.op(1), spinidx));
        GINAC_ASSERT(is_ex_of_type(i.op(2), spinidx));
 
-       const spinidx & i1 = ex_to_spinidx(i.op(1));
-       const spinidx & i2 = ex_to_spinidx(i.op(2));
+       const spinidx & i1 = ex_to<spinidx>(i.op(1));
+       const spinidx & i2 = ex_to<spinidx>(i.op(2));
 
        // Convolutions are zero
        if (static_cast<const indexed &>(i).get_dummy_indices().size() != 0)
@@ -273,7 +273,7 @@ ex spinmetric::eval_indexed(const basic & i) const
 
        // Numeric evaluation
        if (static_cast<const indexed &>(i).all_index_values_are(info_flags::nonnegint)) {
-               int n1 = ex_to_numeric(i1.get_value()).to_int(), n2 = ex_to_numeric(i2.get_value()).to_int();
+               int n1 = ex_to<numeric>(i1.get_value()).to_int(), n2 = ex_to<numeric>(i2.get_value()).to_int();
                if (n1 == n2)
                        return _ex0();
                else if (n1 < n2)
@@ -305,7 +305,7 @@ ex tensepsilon::eval_indexed(const basic & i) const
                std::vector<int> v;
                v.reserve(i.nops() - 1);
                for (unsigned j=1; j<i.nops(); j++)
-                       v.push_back(ex_to_numeric(ex_to_idx(i.op(j)).get_value()).to_int());
+                       v.push_back(ex_to<numeric>(ex_to<idx>(i.op(j)).get_value()).to_int());
                int sign = permutation_sign(v.begin(), v.end());
 
                // In a Minkowski space, check for covariant indices
@@ -314,8 +314,8 @@ ex tensepsilon::eval_indexed(const basic & i) const
                                const ex & x = i.op(j);
                                if (!is_ex_of_type(x, varidx))
                                        throw(std::runtime_error("indices of epsilon tensor in Minkowski space must be of type varidx"));
-                               if (ex_to_varidx(x).is_covariant())
-                                       if (ex_to_idx(x).get_value().is_zero())
+                               if (ex_to<varidx>(x).is_covariant())
+                                       if (ex_to<idx>(x).get_value().is_zero())
                                                sign = (pos_sig ? -sign : sign);
                                        else
                                                sign = (pos_sig ? sign : -sign);
@@ -338,14 +338,14 @@ bool tensdelta::contract_with(exvector::iterator self, exvector::iterator other,
        GINAC_ASSERT(is_ex_of_type(self->op(0), tensdelta));
 
        // Try to contract first index
-       const idx *self_idx = &ex_to_idx(self->op(1));
-       const idx *free_idx = &ex_to_idx(self->op(2));
+       const idx *self_idx = &ex_to<idx>(self->op(1));
+       const idx *free_idx = &ex_to<idx>(self->op(2));
        bool first_index_tried = false;
 
 again:
        if (self_idx->is_symbolic()) {
                for (int i=1; i<other->nops(); i++) {
-                       const idx &other_idx = ex_to_idx(other->op(i));
+                       const idx &other_idx = ex_to<idx>(other->op(i));
                        if (is_dummy_pair(*self_idx, other_idx)) {
 
                                // Contraction found, remove delta tensor and substitute
@@ -360,8 +360,8 @@ again:
        if (!first_index_tried) {
 
                // No contraction with first index found, try second index
-               self_idx = &ex_to_idx(self->op(2));
-               free_idx = &ex_to_idx(self->op(1));
+               self_idx = &ex_to<idx>(self->op(2));
+               free_idx = &ex_to<idx>(self->op(1));
                first_index_tried = true;
                goto again;
        }
@@ -383,14 +383,14 @@ bool tensmetric::contract_with(exvector::iterator self, exvector::iterator other
                return false;
 
        // Try to contract first index
-       const idx *self_idx = &ex_to_idx(self->op(1));
-       const idx *free_idx = &ex_to_idx(self->op(2));
+       const idx *self_idx = &ex_to<idx>(self->op(1));
+       const idx *free_idx = &ex_to<idx>(self->op(2));
        bool first_index_tried = false;
 
 again:
        if (self_idx->is_symbolic()) {
                for (int i=1; i<other->nops(); i++) {
-                       const idx &other_idx = ex_to_idx(other->op(i));
+                       const idx &other_idx = ex_to<idx>(other->op(i));
                        if (is_dummy_pair(*self_idx, other_idx)) {
 
                                // Contraction found, remove metric tensor and substitute
@@ -405,8 +405,8 @@ again:
        if (!first_index_tried) {
 
                // No contraction with first index found, try second index
-               self_idx = &ex_to_idx(self->op(2));
-               free_idx = &ex_to_idx(self->op(1));
+               self_idx = &ex_to<idx>(self->op(2));
+               free_idx = &ex_to<idx>(self->op(1));
                first_index_tried = true;
                goto again;
        }
@@ -424,10 +424,10 @@ bool spinmetric::contract_with(exvector::iterator self, exvector::iterator other
 
        // Contractions between spinor metrics
        if (is_ex_of_type(other->op(0), spinmetric)) {
-               const idx &self_i1 = ex_to_idx(self->op(1));
-               const idx &self_i2 = ex_to_idx(self->op(2));
-               const idx &other_i1 = ex_to_idx(other->op(1));
-               const idx &other_i2 = ex_to_idx(other->op(2));
+               const idx &self_i1 = ex_to<idx>(self->op(1));
+               const idx &self_i2 = ex_to<idx>(self->op(2));
+               const idx &other_i1 = ex_to<idx>(other->op(1));
+               const idx &other_i2 = ex_to<idx>(other->op(2));
 
                if (is_dummy_pair(self_i1, other_i1)) {
                        if (is_dummy_pair(self_i2, other_i2))
@@ -460,15 +460,15 @@ bool spinmetric::contract_with(exvector::iterator self, exvector::iterator other
                return false;
 
        // Try to contract first index
-       const idx *self_idx = &ex_to_idx(self->op(1));
-       const idx *free_idx = &ex_to_idx(self->op(2));
+       const idx *self_idx = &ex_to<idx>(self->op(1));
+       const idx *free_idx = &ex_to<idx>(self->op(2));
        bool first_index_tried = false;
        int sign = 1;
 
 again:
        if (self_idx->is_symbolic()) {
                for (int i=1; i<other->nops(); i++) {
-                       const idx &other_idx = ex_to_idx(other->op(i));
+                       const idx &other_idx = ex_to<idx>(other->op(i));
                        if (is_dummy_pair(*self_idx, other_idx)) {
 
                                // Contraction found, remove metric tensor and substitute
@@ -483,8 +483,8 @@ again:
        if (!first_index_tried) {
 
                // No contraction with first index found, try second index
-               self_idx = &ex_to_idx(self->op(2));
-               free_idx = &ex_to_idx(self->op(1));
+               self_idx = &ex_to<idx>(self->op(2));
+               free_idx = &ex_to<idx>(self->op(1));
                first_index_tried = true;
                sign = -sign;
                goto again;
@@ -525,7 +525,7 @@ ex spinor_metric(const ex & i1, const ex & i2)
 {
        if (!is_ex_of_type(i1, spinidx) || !is_ex_of_type(i2, spinidx))
                throw(std::invalid_argument("indices of spinor metric must be of type spinidx"));
-       if (!ex_to_idx(i1).get_dim().is_equal(2) || !ex_to_idx(i2).get_dim().is_equal(2))
+       if (!ex_to<idx>(i1).get_dim().is_equal(2) || !ex_to<idx>(i2).get_dim().is_equal(2))
                throw(std::runtime_error("index dimension for spinor metric must be 2"));
 
        return indexed(spinmetric(), sy_anti(), i1, i2);
@@ -536,10 +536,10 @@ ex epsilon_tensor(const ex & i1, const ex & i2)
        if (!is_ex_of_type(i1, idx) || !is_ex_of_type(i2, idx))
                throw(std::invalid_argument("indices of epsilon tensor must be of type idx"));
 
-       ex dim = ex_to_idx(i1).get_dim();
-       if (!dim.is_equal(ex_to_idx(i2).get_dim()))
+       ex dim = ex_to<idx>(i1).get_dim();
+       if (!dim.is_equal(ex_to<idx>(i2).get_dim()))
                throw(std::invalid_argument("all indices of epsilon tensor must have the same dimension"));
-       if (!ex_to_idx(i1).get_dim().is_equal(_ex2()))
+       if (!ex_to<idx>(i1).get_dim().is_equal(_ex2()))
                throw(std::runtime_error("index dimension of epsilon tensor must match number of indices"));
 
        return indexed(tensepsilon(), sy_anti(), i1, i2);
@@ -550,10 +550,10 @@ ex epsilon_tensor(const ex & i1, const ex & i2, const ex & i3)
        if (!is_ex_of_type(i1, idx) || !is_ex_of_type(i2, idx) || !is_ex_of_type(i3, idx))
                throw(std::invalid_argument("indices of epsilon tensor must be of type idx"));
 
-       ex dim = ex_to_idx(i1).get_dim();
-       if (!dim.is_equal(ex_to_idx(i2).get_dim()) || !dim.is_equal(ex_to_idx(i3).get_dim()))
+       ex dim = ex_to<idx>(i1).get_dim();
+       if (!dim.is_equal(ex_to<idx>(i2).get_dim()) || !dim.is_equal(ex_to<idx>(i3).get_dim()))
                throw(std::invalid_argument("all indices of epsilon tensor must have the same dimension"));
-       if (!ex_to_idx(i1).get_dim().is_equal(_ex3()))
+       if (!ex_to<idx>(i1).get_dim().is_equal(_ex3()))
                throw(std::runtime_error("index dimension of epsilon tensor must match number of indices"));
 
        return indexed(tensepsilon(), sy_anti(), i1, i2, i3);
@@ -564,10 +564,10 @@ ex lorentz_eps(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool
        if (!is_ex_of_type(i1, varidx) || !is_ex_of_type(i2, varidx) || !is_ex_of_type(i3, varidx) || !is_ex_of_type(i4, varidx))
                throw(std::invalid_argument("indices of Lorentz epsilon tensor must be of type varidx"));
 
-       ex dim = ex_to_idx(i1).get_dim();
-       if (!dim.is_equal(ex_to_idx(i2).get_dim()) || !dim.is_equal(ex_to_idx(i3).get_dim()) || !dim.is_equal(ex_to_idx(i4).get_dim()))
+       ex dim = ex_to<idx>(i1).get_dim();
+       if (!dim.is_equal(ex_to<idx>(i2).get_dim()) || !dim.is_equal(ex_to<idx>(i3).get_dim()) || !dim.is_equal(ex_to<idx>(i4).get_dim()))
                throw(std::invalid_argument("all indices of epsilon tensor must have the same dimension"));
-       if (!ex_to_idx(i1).get_dim().is_equal(_ex4()))
+       if (!ex_to<idx>(i1).get_dim().is_equal(_ex4()))
                throw(std::runtime_error("index dimension of epsilon tensor must match number of indices"));
 
        return indexed(tensepsilon(true, pos_sig), sy_anti(), i1, i2, i3, i4);
@@ -578,7 +578,7 @@ ex eps0123(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool pos_
        if (!is_ex_of_type(i1, varidx) || !is_ex_of_type(i2, varidx) || !is_ex_of_type(i3, varidx) || !is_ex_of_type(i4, varidx))
                throw(std::invalid_argument("indices of epsilon tensor must be of type varidx"));
 
-       ex dim = ex_to_idx(i1).get_dim();
+       ex dim = ex_to<idx>(i1).get_dim();
        if (dim.is_equal(4))
                return lorentz_eps(i1, i2, i3, i4, pos_sig);
        else
index 5698b9b..147ab44 100644 (file)
@@ -137,6 +137,9 @@ private:
 
 
 // utility functions
+
+/** Return the tensor object handled by an ex.  Deprecated: use ex_to<tensor>().
+ *  This is unsafe: you need to check the type first. */
 inline const tensor &ex_to_tensor(const ex &e)
 {
        return static_cast<const tensor &>(*e.bp);
index 6e1bf1c..6bddc5e 100644 (file)
@@ -57,7 +57,7 @@ private:
 
 // utility functions
 
-/** Return the wildcard object handled by an ex.
+/** Return the wildcard object handled by an ex.  Deprecated: use ex_to<wildcard>().
  *  This is unsafe: you need to check the type first. */
 inline const wildcard &ex_to_wildcard(const ex &e)
 {
index a7872fb..be3f686 100644 (file)
@@ -146,7 +146,7 @@ line        : ';'
                        ex e = $3;
                        if (!e.info(info_flags::integer))
                                throw (std::invalid_argument("argument to iprint() must be an integer"));
-                       long i = ex_to_numeric(e).to_long();
+                       long i = ex_to<numeric>(e).to_long();
                        cout << i << endl;
                        cout << "#o" << oct << i << endl;
                        cout << "#x" << hex << i << dec << endl;
@@ -155,7 +155,7 @@ line        : ';'
                        YYERROR;
                }
        }
-       | '?' T_SYMBOL          {print_help(ex_to_symbol($2).get_name());}
+       | '?' T_SYMBOL          {print_help(ex_to<symbol>($2).get_name());}
        | '?' T_TIME            {print_help("time");}
        | '?' '?'               {print_help_topics();}
        | T_QUIT                {YYACCEPT;}
@@ -207,8 +207,8 @@ exp : T_NUMBER              {$$ = $1;}
                        $$ = (i->second.p)(static_cast<const exprseq &>(*($3.bp)));
                }
        }
-       | T_DIGITS '=' T_NUMBER {$$ = $3; Digits = ex_to_numeric($3).to_int();}
-       | T_SYMBOL '=' exp      {$$ = $3; const_cast<symbol *>(&ex_to_symbol($1))->assign($3);}
+       | T_DIGITS '=' T_NUMBER {$$ = $3; Digits = ex_to<numeric>($3).to_int();}
+       | T_SYMBOL '=' exp      {$$ = $3; const_cast<symbol *>(&ex_to<symbol>($1))->assign($3);}
        | exp T_EQUAL exp       {$$ = $1 == $3;}
        | exp T_NOTEQ exp       {$$ = $1 != $3;}
        | exp '<' exp           {$$ = $1 < $3;}
@@ -225,7 +225,7 @@ exp : T_NUMBER              {$$ = $1;}
        | exp '!'               {$$ = factorial($1);}
        | '(' exp ')'           {$$ = $2;}
        | '{' list_or_empty '}' {$$ = $2;}
-       | '[' matrix ']'        {$$ = lst_to_matrix(ex_to_lst($2));}
+       | '[' matrix ']'        {$$ = lst_to_matrix(ex_to<lst>($2));}
        ;
 
 exprseq        : exp                   {$$ = exprseq($1);}
@@ -304,25 +304,25 @@ static ex f_charpoly(const exprseq &e)
 {
        CHECK_ARG(0, matrix, charpoly);
        CHECK_ARG(1, symbol, charpoly);
-       return ex_to_matrix(e[0]).charpoly(ex_to_symbol(e[1]));
+       return ex_to<matrix>(e[0]).charpoly(ex_to<symbol>(e[1]));
 }
 
 static ex f_coeff(const exprseq &e)
 {
        CHECK_ARG(2, numeric, coeff);
-       return e[0].coeff(e[1], ex_to_numeric(e[2]).to_int());
+       return e[0].coeff(e[1], ex_to<numeric>(e[2]).to_int());
 }
 
 static ex f_content(const exprseq &e)
 {
        CHECK_ARG(1, symbol, content);
-       return e[0].content(ex_to_symbol(e[1]));
+       return e[0].content(ex_to<symbol>(e[1]));
 }
 
 static ex f_determinant(const exprseq &e)
 {
        CHECK_ARG(0, matrix, determinant);
-       return ex_to_matrix(e[0]).determinant();
+       return ex_to<matrix>(e[0]).determinant();
 }
 
 static ex f_diag(const exprseq &e)
@@ -337,14 +337,14 @@ static ex f_diag(const exprseq &e)
 static ex f_diff2(const exprseq &e)
 {
        CHECK_ARG(1, symbol, diff);
-       return e[0].diff(ex_to_symbol(e[1]));
+       return e[0].diff(ex_to<symbol>(e[1]));
 }
 
 static ex f_diff3(const exprseq &e)
 {
        CHECK_ARG(1, symbol, diff);
        CHECK_ARG(2, numeric, diff);
-       return e[0].diff(ex_to_symbol(e[1]), ex_to_numeric(e[2]).to_int());
+       return e[0].diff(ex_to<symbol>(e[1]), ex_to<numeric>(e[2]).to_int());
 }
 
 static ex f_divide(const exprseq &e)
@@ -359,25 +359,25 @@ static ex f_divide(const exprseq &e)
 static ex f_eval2(const exprseq &e)
 {
        CHECK_ARG(1, numeric, eval);
-       return e[0].eval(ex_to_numeric(e[1]).to_int());
+       return e[0].eval(ex_to<numeric>(e[1]).to_int());
 }
 
 static ex f_evalf2(const exprseq &e)
 {
        CHECK_ARG(1, numeric, evalf);
-       return e[0].evalf(ex_to_numeric(e[1]).to_int());
+       return e[0].evalf(ex_to<numeric>(e[1]).to_int());
 }
 
 static ex f_inverse(const exprseq &e)
 {
        CHECK_ARG(0, matrix, inverse);
-       return ex_to_matrix(e[0]).inverse();
+       return ex_to<matrix>(e[0]).inverse();
 }
 
 static ex f_is(const exprseq &e)
 {
        CHECK_ARG(0, relational, is);
-       return (bool)ex_to_relational(e[0]) ? ex(1) : ex(0);
+       return (bool)ex_to<relational>(e[0]) ? ex(1) : ex(0);
 }
 
 static ex f_match(const exprseq &e)
@@ -392,13 +392,13 @@ static ex f_match(const exprseq &e)
 static ex f_normal2(const exprseq &e)
 {
        CHECK_ARG(1, numeric, normal);
-       return e[0].normal(ex_to_numeric(e[1]).to_int());
+       return e[0].normal(ex_to<numeric>(e[1]).to_int());
 }
 
 static ex f_op(const exprseq &e)
 {
        CHECK_ARG(1, numeric, op);
-       int n = ex_to_numeric(e[1]).to_int();
+       int n = ex_to<numeric>(e[1]).to_int();
        if (n < 0 || n >= (int)e[0].nops())
                throw(std::out_of_range("second argument to op() is out of range"));
        return e[0].op(n);
@@ -407,69 +407,69 @@ static ex f_op(const exprseq &e)
 static ex f_prem(const exprseq &e)
 {
        CHECK_ARG(2, symbol, prem);
-       return prem(e[0], e[1], ex_to_symbol(e[2]));
+       return prem(e[0], e[1], ex_to<symbol>(e[2]));
 }
 
 static ex f_primpart(const exprseq &e)
 {
        CHECK_ARG(1, symbol, primpart);
-       return e[0].primpart(ex_to_symbol(e[1]));
+       return e[0].primpart(ex_to<symbol>(e[1]));
 }
 
 static ex f_quo(const exprseq &e)
 {
        CHECK_ARG(2, symbol, quo);
-       return quo(e[0], e[1], ex_to_symbol(e[2]));
+       return quo(e[0], e[1], ex_to<symbol>(e[2]));
 }
 
 static ex f_rem(const exprseq &e)
 {
        CHECK_ARG(2, symbol, rem);
-       return rem(e[0], e[1], ex_to_symbol(e[2]));
+       return rem(e[0], e[1], ex_to<symbol>(e[2]));
 }
 
 static ex f_series(const exprseq &e)
 {
        CHECK_ARG(2, numeric, series);
-       return e[0].series(e[1], ex_to_numeric(e[2]).to_int());
+       return e[0].series(e[1], ex_to<numeric>(e[2]).to_int());
 }
 
 static ex f_sqrfree2(const exprseq &e)
 {
        CHECK_ARG(1, lst, sqrfree);
-       return sqrfree(e[0], ex_to_lst(e[1]));
+       return sqrfree(e[0], ex_to<lst>(e[1]));
 }
 
 static ex f_subs3(const exprseq &e)
 {
        CHECK_ARG(1, lst, subs);
        CHECK_ARG(2, lst, subs);
-       return e[0].subs(ex_to_lst(e[1]), ex_to_lst(e[2]));
+       return e[0].subs(ex_to<lst>(e[1]), ex_to<lst>(e[2]));
 }
 
 static ex f_trace(const exprseq &e)
 {
        CHECK_ARG(0, matrix, trace);
-       return ex_to_matrix(e[0]).trace();
+       return ex_to<matrix>(e[0]).trace();
 }
 
 static ex f_transpose(const exprseq &e)
 {
        CHECK_ARG(0, matrix, transpose);
-       return ex_to_matrix(e[0]).transpose();
+       return ex_to<matrix>(e[0]).transpose();
 }
 
 static ex f_unassign(const exprseq &e)
 {
        CHECK_ARG(0, symbol, unassign);
-       (const_cast<symbol *>(&ex_to_symbol(e[0])))->unassign();
+       (const_cast<symbol *>(&ex_to<symbol>(e[0])))->unassign();
        return e[0];
 }
 
 static ex f_unit(const exprseq &e)
 {
        CHECK_ARG(1, symbol, unit);
-       return e[0].unit(ex_to_symbol(e[1]));
+       return e[0].unit(ex_to<symbol>(e[1]));
 }
 
 static ex f_dummy(const exprseq &e)
@@ -575,7 +575,7 @@ void GiNaC::ginsh_get_ginac_functions(void)
 
 static fcn_tab::const_iterator find_function(const ex &sym, int req_params)
 {
-       const string &name = ex_to_symbol(sym).get_name();
+       const string &name = ex_to<symbol>(sym).get_name();
        typedef fcn_tab::const_iterator I;
        pair<I, I> b = fcns.equal_range(name);
        if (b.first == b.second)