return seq.begin()->rest.return_type();
}
-tinfo_t add::return_type_tinfo() const
+return_type_t add::return_type_tinfo() const
{
if (seq.empty())
- return this;
+ return make_return_type_t<add>();
else
return seq.begin()->rest.return_type_tinfo();
}
protected:
ex derivative(const symbol & s) const;
unsigned return_type() const;
- tinfo_t return_type_tinfo() const;
+ return_type_t return_type_tinfo() const;
ex thisexpairseq(const epvector & v, const ex & oc, bool do_index_renaming = false) const;
ex thisexpairseq(std::auto_ptr<epvector> vp, const ex & oc, bool do_index_renaming = false) const;
expair split_ex_to_pair(const ex & e) const;
return return_types::commutative;
}
-tinfo_t basic::return_type_tinfo() const
+return_type_t basic::return_type_tinfo() const
{
- return tinfo_key;
+ return_type_t rt;
+ rt.tinfo = &typeid(*this);
+ rt.rl = 0;
+ return rt;
}
/** Compute the hash value of an object and if it makes sense to store it in
// noncommutativity
virtual unsigned return_type() const;
- virtual tinfo_t return_type_tinfo() const;
+ virtual return_type_t return_type_tinfo() const;
// functions for complex expressions
virtual ex conjugate() const;
print_func<print_dflt>(&clifford::do_print_dflt).
print_func<print_latex>(&clifford::do_print_latex))
-const tinfo_static_t clifford::return_type_tinfo_static[256] = {{}};
-
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(diracone, tensor,
print_func<print_dflt>(&diracone::do_print).
print_func<print_latex>(&diracone::do_print_latex))
tinfo_key = &clifford::tinfo_static;
}
+return_type_t clifford::return_type_tinfo() const
+{
+ return make_return_type_t<clifford>(representation_label);
+}
+
//////////
// archiving
//////////
return clifford(e, varidx(0, dim), indexed((new minkmetric)->setflag(status_flags::dynallocated), symmetric2(), xi, chi), rl);
}
-/** Check whether a given tinfo key (as returned by return_type_tinfo()
- * is that of a clifford object (with an arbitrary representation label). */
-bool is_clifford_tinfo(tinfo_t ti)
-{
- p_int start_loc=(p_int)&clifford::return_type_tinfo_static;
- return (p_int)ti>=start_loc && (p_int)ti<start_loc+256;
-}
-
/** Extract representation label from tinfo key (as returned by
* return_type_tinfo()). */
-static unsigned char get_representation_label(tinfo_t ti)
+static unsigned char get_representation_label(const return_type_t& ti)
{
- return (unsigned char)((p_int)ti-(p_int)&clifford::return_type_tinfo_static);
+ return (unsigned char)ti.rl;
}
/** Take trace of a string of an even number of Dirac gammas given a vector
class clifford : public indexed
{
GINAC_DECLARE_REGISTERED_CLASS(clifford, indexed)
-public:
- static const tinfo_static_t return_type_tinfo_static[256];
-
// other constructors
public:
clifford(const ex & b, unsigned char rl = 0);
ex thiscontainer(const exvector & v) const;
ex thiscontainer(std::auto_ptr<exvector> vp) const;
unsigned return_type() const { return return_types::noncommutative; }
- tinfo_t return_type_tinfo() const { return clifford::return_type_tinfo_static+representation_label; }
-
+ return_type_t return_type_tinfo() const;
// non-virtual functions in this class
public:
unsigned char get_representation_label() const { return representation_label; }
// global functions
-/** Check whether a given tinfo key (as returned by return_type_tinfo()
+/** Check whether a given return_type_t object (as returned by return_type_tinfo()
* is that of a clifford object (with an arbitrary representation label).
*
* @param ti tinfo key */
-bool is_clifford_tinfo(tinfo_t ti);
+inline bool is_clifford_tinfo(const return_type_t& ti)
+{
+ return *(ti.tinfo) == typeid(clifford);
+}
/** Create a Clifford unity object.
*
GINAC_IMPLEMENT_REGISTERED_CLASS(color, indexed)
-const tinfo_static_t color::return_type_tinfo_static[256] = {{}};
-
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(su3one, tensor,
print_func<print_dflt>(&su3one::do_print).
print_func<print_latex>(&su3one::do_print_latex))
tinfo_key = &color::tinfo_static;
}
+return_type_t color::return_type_tinfo() const
+{
+ return make_return_type_t<color>(representation_label);
+}
+
//////////
// archiving
//////////
/** Check whether a given tinfo key (as returned by return_type_tinfo()
* is that of a color object (with an arbitrary representation label). */
-static bool is_color_tinfo(tinfo_t ti)
+static bool is_color_tinfo(const return_type_t& ti)
{
- p_int start_loc=(p_int)&color::return_type_tinfo_static;
- return (p_int)ti>=start_loc && (p_int)ti<start_loc+256;
+ return *(ti.tinfo) == typeid(color);
}
/** Extract representation label from tinfo key (as returned by
* return_type_tinfo()). */
-static unsigned char get_representation_label(tinfo_t ti)
+static unsigned char get_representation_label(const return_type_t& ti)
{
- return (unsigned char)((p_int)ti-(p_int)&color::return_type_tinfo_static);
+ return (unsigned char)ti.rl;
}
ex color_trace(const ex & e, const std::set<unsigned char> & rls)
class color : public indexed
{
GINAC_DECLARE_REGISTERED_CLASS(color, indexed)
-public:
- static const tinfo_static_t return_type_tinfo_static[256];
-
// other constructors
public:
color(const ex & b, unsigned char rl = 0);
ex thiscontainer(const exvector & v) const;
ex thiscontainer(std::auto_ptr<exvector> vp) const;
unsigned return_type() const { return return_types::noncommutative; }
- tinfo_t return_type_tinfo() const { return color::return_type_tinfo_static+representation_label; }
+ return_type_t return_type_tinfo() const;
// non-virtual functions in this class
public:
// noncommutativity
unsigned return_type() const { return bp->return_type(); }
- tinfo_t return_type_tinfo() const { return bp->return_type_tinfo(); }
+ return_type_t return_type_tinfo() const { return bp->return_type_tinfo(); }
unsigned gethash() const { return bp->gethash(); }
return *this;
}
- function_options & set_return_type(unsigned rt, tinfo_t rtt=NULL);
+ function_options & set_return_type(unsigned rt, const return_type_t* rtt = 0);
function_options & do_not_evalf_params();
function_options & remember(unsigned size, unsigned assoc_size=0,
unsigned strategy=remember_strategies::delete_never);
bool use_return_type;
unsigned return_type;
- tinfo_t return_type_tinfo;
+ return_type_t return_type_tinfo;
bool use_remember;
unsigned remember_size;
bool is_equal_same_type(const basic & other) const;
bool match_same_type(const basic & other) const;
unsigned return_type() const;
- tinfo_t return_type_tinfo() const;
+ return_type_t return_type_tinfo() const;
// new virtual functions which can be overridden by derived classes
// none
return *this;
}
-function_options & function_options::set_return_type(unsigned rt, tinfo_t rtt)
+function_options & function_options::set_return_type(unsigned rt, const return_type_t* rtt)
{
use_return_type = true;
return_type = rt;
- return_type_tinfo = rtt;
+ if (rtt != 0)
+ return_type_tinfo = *rtt;
+ else
+ return_type_tinfo = make_return_type_t<function>();
return *this;
}
}
}
-tinfo_t function::return_type_tinfo() const
+return_type_t function::return_type_tinfo() const
{
GINAC_ASSERT(serial<registered_functions().size());
const function_options &opt = registered_functions()[serial];
// Default behavior is to use the return type of the first
// argument. Thus, exp() of a matrix behaves like a matrix, etc.
if (seq.empty())
- return this;
+ return make_return_type_t<function>();
else
return seq.begin()->return_type_tinfo();
}
ex thiscontainer(const exvector & v) const;
ex thiscontainer(std::auto_ptr<exvector> vp) const;
unsigned return_type() const;
- tinfo_t return_type_tinfo() const { return op(0).return_type_tinfo(); }
+ return_type_t return_type_tinfo() const { return op(0).return_type_tinfo(); }
ex expand(unsigned options = 0) const;
// new virtual functions which can be overridden by derived classes
return f.return_type();
}
-tinfo_t integral::return_type_tinfo() const
+return_type_t integral::return_type_tinfo() const
{
return f.return_type_tinfo();
}
ex expand(unsigned options = 0) const;
exvector get_free_indices() const;
unsigned return_type() const;
- tinfo_t return_type_tinfo() const;
+ return_type_t return_type_tinfo() const;
ex conjugate() const;
ex eval_integ() const;
protected:
return all_commutative ? return_types::commutative : return_types::noncommutative;
}
-tinfo_t mul::return_type_tinfo() const
+return_type_t mul::return_type_tinfo() const
{
if (seq.empty())
- return this; // mul without factors: should not happen
+ return make_return_type_t<mul>(); // mul without factors: should not happen
// return type_info of first noncommutative element
epvector::const_iterator i = seq.begin(), end = seq.end();
++i;
}
// no noncommutative element found, should not happen
- return this;
+ return make_return_type_t<mul>();
}
ex mul::thisexpairseq(const epvector & v, const ex & oc, bool do_index_renaming) const
ex derivative(const symbol & s) const;
ex eval_ncmul(const exvector & v) const;
unsigned return_type() const;
- tinfo_t return_type_tinfo() const;
+ return_type_t return_type_tinfo() const;
ex thisexpairseq(const epvector & v, const ex & oc, bool do_index_renaming = false) const;
ex thisexpairseq(std::auto_ptr<epvector> vp, const ex & oc, bool do_index_renaming = false) const;
expair split_ex_to_pair(const ex & e) const;
size_t assoc_num = assocseq.size();
exvectorvector evv;
- std::vector<tinfo_t> rttinfos;
+ std::vector<return_type_t> rttinfos;
evv.reserve(assoc_num);
rttinfos.reserve(assoc_num);
cit = assocseq.begin(), citend = assocseq.end();
while (cit != citend) {
- tinfo_t ti = cit->return_type_tinfo();
+ return_type_t ti = cit->return_type_tinfo();
size_t rtt_num = rttinfos.size();
// search type in vector of known types
for (i=0; i<rtt_num; ++i) {
return all_commutative ? return_types::commutative : return_types::noncommutative;
}
-tinfo_t ncmul::return_type_tinfo() const
+return_type_t ncmul::return_type_tinfo() const
{
if (seq.empty())
- return this;
+ return make_return_type_t<ncmul>();
// return type_info of first noncommutative element
exvector::const_iterator i = seq.begin(), end = seq.end();
}
// no noncommutative element found, should not happen
- return this;
+ return make_return_type_t<ncmul>();
}
//////////
protected:
ex derivative(const symbol & s) const;
unsigned return_type() const;
- tinfo_t return_type_tinfo() const;
+ return_type_t return_type_tinfo() const;
// new virtual functions which can be overridden by derived classes
// none
return basis.return_type();
}
-tinfo_t power::return_type_tinfo() const
+return_type_t power::return_type_tinfo() const
{
return basis.return_type_tinfo();
}
ex derivative(const symbol & s) const;
ex eval_ncmul(const exvector & v) const;
unsigned return_type() const;
- tinfo_t return_type_tinfo() const;
+ return_type_t return_type_tinfo() const;
ex expand(unsigned options = 0) const;
// new virtual functions which can be overridden by derived classes
template <template <class T, class = std::allocator<T> > class> class container;
typedef container<std::list> lst;
+/** To distinguish between different kinds of non-commutative objects */
+struct return_type_t
+{
+ /// to distinguish between non-commutative objects of different type.
+ std::type_info const* tinfo;
+ /// to distinguish between non-commutative objects of the same type.
+ /// Think of gamma matrices with different represenation labels.
+ unsigned rl;
+
+ /// Strict weak ordering (so one can put return_type_t's into
+ /// a STL container).
+ inline bool operator<(const return_type_t& other) const
+ {
+ if (tinfo->before(*other.tinfo))
+ return true;
+ return rl < other.rl;
+ }
+ inline bool operator==(const return_type_t& other) const
+ {
+ if (*tinfo != *(other.tinfo))
+ return false;
+ return rl == other.rl;
+ }
+ inline bool operator!=(const return_type_t& other) const
+ {
+ return ! (operator==(other));
+ }
+};
+
+template<typename T> inline return_type_t make_return_type_t(const unsigned rl = 0)
+{
+ return_type_t ret;
+ ret.rl = rl;
+ ret.tinfo = &typeid(T);
+ return ret;
+}
+
/** Definitions for the tinfo mechanism. */
typedef const void * tinfo_t;
struct tinfo_static_t {};
return lh.return_type();
}
-tinfo_t relational::return_type_tinfo() const
+return_type_t relational::return_type_tinfo() const
{
GINAC_ASSERT(lh.return_type_tinfo()==rh.return_type_tinfo());
return lh.return_type_tinfo();
ex eval_ncmul(const exvector & v) const;
bool match_same_type(const basic & other) const;
unsigned return_type() const;
- tinfo_t return_type_tinfo() const;
+ return_type_t return_type_tinfo() const;
unsigned calchash() const;
// new virtual functions which can be overridden by derived classes
// noncommutativity
unsigned return_type() const { return return_types::commutative; }
- tinfo_t return_type_tinfo() const { return this; }
+ return_type_t return_type_tinfo() const
+ {
+ return_type_t r;
+ r.rl = 0;
+ r.tinfo = &typeid(*this);
+ return r;
+ }
protected:
bool is_equal_same_type(const basic & other) const
// symbol
symbol::symbol()
- : inherited(&symbol::tinfo_static), serial(next_serial++), name(autoname_prefix() + ToString(serial)), TeX_name(name), domain(domain::complex), ret_type(return_types::commutative), ret_type_tinfo(&symbol::tinfo_static)
+ : inherited(&symbol::tinfo_static), serial(next_serial++), name(autoname_prefix() + ToString(serial)), TeX_name(name), domain(domain::complex), ret_type(return_types::commutative), ret_type_tinfo(make_return_type_t<symbol>())
{
setflag(status_flags::evaluated | status_flags::expanded);
}
// symbol
symbol::symbol(const std::string & initname, unsigned domain)
- : inherited(&symbol::tinfo_static), serial(next_serial++), name(initname), TeX_name(default_TeX_name()), domain(domain), ret_type(return_types::commutative), ret_type_tinfo(&symbol::tinfo_static)
+ : inherited(&symbol::tinfo_static), serial(next_serial++), name(initname), TeX_name(default_TeX_name()), domain(domain), ret_type(return_types::commutative), ret_type_tinfo(make_return_type_t<symbol>())
{
setflag(status_flags::evaluated | status_flags::expanded);
}
-symbol::symbol(const std::string & initname, unsigned rt, tinfo_t rtt, unsigned domain)
+symbol::symbol(const std::string & initname, unsigned rt, const return_type_t& rtt, unsigned domain)
: inherited(&symbol::tinfo_static), serial(next_serial++), name(initname), TeX_name(default_TeX_name()), domain(domain), ret_type(rt), ret_type_tinfo(rtt)
{
setflag(status_flags::evaluated | status_flags::expanded);
}
symbol::symbol(const std::string & initname, const std::string & texname, unsigned domain)
- : inherited(&symbol::tinfo_static), serial(next_serial++), name(initname), TeX_name(texname), domain(domain), ret_type(return_types::commutative), ret_type_tinfo(&symbol::tinfo_static)
+ : inherited(&symbol::tinfo_static), serial(next_serial++), name(initname), TeX_name(texname), domain(domain), ret_type(return_types::commutative), ret_type_tinfo(make_return_type_t<symbol>())
{
setflag(status_flags::evaluated | status_flags::expanded);
}
-symbol::symbol(const std::string & initname, const std::string & texname, unsigned rt, tinfo_t rtt, unsigned domain)
+symbol::symbol(const std::string & initname, const std::string & texname, unsigned rt, const return_type_t& rtt, unsigned domain)
: inherited(&symbol::tinfo_static), serial(next_serial++), name(initname), TeX_name(texname), domain(domain), ret_type(rt), ret_type_tinfo(rtt)
{
setflag(status_flags::evaluated | status_flags::expanded);
realsymbol::realsymbol(const std::string & initname, const std::string & texname, unsigned domain)
: symbol(initname, texname, domain) { }
-realsymbol::realsymbol(const std::string & initname, unsigned rt, tinfo_t rtt, unsigned domain)
+realsymbol::realsymbol(const std::string & initname, unsigned rt, const return_type_t& rtt, unsigned domain)
: symbol(initname, rt, rtt, domain) { }
-realsymbol::realsymbol(const std::string & initname, const std::string & texname, unsigned rt, tinfo_t rtt, unsigned domain)
+realsymbol::realsymbol(const std::string & initname, const std::string & texname, unsigned rt, const return_type_t& rtt, unsigned domain)
: symbol(initname, texname, rt, rtt, domain) { }
// possymbol
possymbol::possymbol(const std::string & initname, const std::string & texname, unsigned domain)
: symbol(initname, texname, domain) { }
-possymbol::possymbol(const std::string & initname, unsigned rt, tinfo_t rtt, unsigned domain)
+possymbol::possymbol(const std::string & initname, unsigned rt, const return_type_t& rtt, unsigned domain)
: symbol(initname, rt, rtt, domain) { }
-possymbol::possymbol(const std::string & initname, const std::string & texname, unsigned rt, tinfo_t rtt, unsigned domain)
+possymbol::possymbol(const std::string & initname, const std::string & texname, unsigned rt, const return_type_t& rtt, unsigned domain)
: symbol(initname, texname, rt, rtt, domain) { }
//////////
explicit symbol(const std::string & initname, unsigned domain = domain::complex);
symbol(const std::string & initname, const std::string & texname, unsigned domain = domain::complex);
symbol(const std::string & initname, const std::string & texname, unsigned rt, unsigned domain);
- symbol(const std::string & initname, unsigned rt, tinfo_t rtt, unsigned domain = domain::complex);
- symbol(const std::string & initname, const std::string & texname, unsigned rt, tinfo_t rtt, unsigned domain = domain::complex);
+ symbol(const std::string & initname, unsigned rt, const return_type_t& rtt, unsigned domain = domain::complex);
+ symbol(const std::string & initname, const std::string & texname, unsigned rt, const return_type_t& rtt, unsigned domain = domain::complex);
// functions overriding virtual functions from base classes
public:
ex to_rational(exmap & repl) const;
ex to_polynomial(exmap & repl) const;
unsigned return_type() const { return ret_type; }
- tinfo_t return_type_tinfo() const { return ret_type_tinfo; }
+ return_type_t return_type_tinfo() const { return ret_type_tinfo; }
ex conjugate() const;
ex real_part() const;
ex imag_part() const;
std::string TeX_name; ///< LaTeX name of this symbol
unsigned domain; ///< domain of symbol, complex (default) or real
unsigned ret_type; ///< value returned by return_type()
- tinfo_t ret_type_tinfo; ///< value returned by return_type_tinfo()
+ return_type_t ret_type_tinfo; ///< value returned by return_type_tinfo()
private:
static unsigned next_serial;
};
realsymbol();
explicit realsymbol(const std::string & initname, unsigned domain = domain::real);
realsymbol(const std::string & initname, const std::string & texname, unsigned domain = domain::real);
- realsymbol(const std::string & initname, unsigned rt, tinfo_t rtt, unsigned domain = domain::real);
- realsymbol(const std::string & initname, const std::string & texname, unsigned rt, tinfo_t rtt, unsigned domain = domain::real);
+ realsymbol(const std::string & initname, unsigned rt, const return_type_t& rtt, unsigned domain = domain::real);
+ realsymbol(const std::string & initname, const std::string & texname, unsigned rt, const return_type_t& rtt, unsigned domain = domain::real);
};
possymbol();
explicit possymbol(const std::string & initname, unsigned domain = domain::positive);
possymbol(const std::string & initname, const std::string & texname, unsigned domain = domain::positive);
- possymbol(const std::string & initname, unsigned rt, tinfo_t rtt, unsigned domain = domain::positive);
- possymbol(const std::string & initname, const std::string & texname, unsigned rt, tinfo_t rtt, unsigned domain = domain::positive);
+ possymbol(const std::string & initname, unsigned rt, const return_type_t& rtt, unsigned domain = domain::positive);
+ possymbol(const std::string & initname, const std::string & texname, unsigned rt, const return_type_t& rtt, unsigned domain = domain::positive);
};