Commits

Volker Braun committed 8b1b2da

working on reviewer patches

Comments (0)

Files changed (2)

 num_symbol.patch
 stable_op.patch
 trac_9880_ginac_infinities_rewrite.patch
+trac_9880_reviewer-vb.patch

trac_9880_reviewer-vb.patch

+# HG changeset patch
+# Parent 3c4b290ed6ec3f3c3fc8a679f4368bf6a21f9d60
+
+diff --git a/ginac/add.cpp b/ginac/add.cpp
+--- a/ginac/add.cpp
++++ b/ginac/add.cpp
+@@ -128,9 +128,9 @@
+ 	numeric coeff;
+ 	bool first = true;
+ 
+-	epvector* sorted_seq = get_sorted_seq();
++	const epvector & sorted_seq = get_sorted_seq();
+ 	// Then proceed with the remaining factors
+-	epvector::const_iterator it = sorted_seq->begin(), itend = sorted_seq->end();
++	epvector::const_iterator it = sorted_seq.begin(), itend = sorted_seq.end();
+ 	while (it != itend) {
+ 		std::stringstream tstream;
+ 		print_context *tcontext_p;
+@@ -697,15 +697,15 @@
+ 	return (new add(vp, overall_coeff))->setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
+ }
+ 
+-epvector* add::get_sorted_seq() const
++const epvector & add::get_sorted_seq() const
+ {
+-	if (!this->seq_sorted) {
+-		seq_sorted = new epvector(seq.size());
++	if (seq_sorted.empty() and not seq.empty()) {
++		seq_sorted = epvector(seq.size());
+ 		partial_sort_copy(seq.begin(), seq.end(),
+-				seq_sorted->begin(), seq_sorted->end(),
+-				print_order_pair());
++				  seq_sorted.begin(), seq_sorted.end(),
++				  print_order_pair());
+ 	}
+-	return seq_sorted;
++	return expairseq::get_sorted_seq();
+ }
+ 
+ } // namespace GiNaC
+diff --git a/ginac/add.h b/ginac/add.h
+--- a/ginac/add.h
++++ b/ginac/add.h
+@@ -63,7 +63,7 @@
+ 	ex imag_part() const;
+ 	exvector get_free_indices() const;
+ 	ex eval_ncmul(const exvector & v) const;
+-	epvector* get_sorted_seq() const;
++	const epvector & get_sorted_seq() const;
+ protected:
+ 	ex derivative(const symbol & s) const;
+ 	unsigned return_type() const;
+diff --git a/ginac/basic.cpp b/ginac/basic.cpp
+--- a/ginac/basic.cpp
++++ b/ginac/basic.cpp
+@@ -830,43 +830,43 @@
+ int basic::compare(const basic & other) const
+ {
+ #ifdef GINAC_COMPARE_STATISTICS
+-        compare_statistics.total_basic_compares++;
++	compare_statistics.total_basic_compares++;
+ #endif
+-        const unsigned hash_this = gethash();
+-        const unsigned hash_other = other.gethash();
+-        if (hash_this<hash_other) return -1;
+-        if (hash_this>hash_other) return 1;
++	const unsigned hash_this = gethash();
++	const unsigned hash_other = other.gethash();
++	if (hash_this<hash_other) return -1;
++	if (hash_this>hash_other) return 1;
+ #ifdef GINAC_COMPARE_STATISTICS
+-        compare_statistics.compare_same_hashvalue++;
++	compare_statistics.compare_same_hashvalue++;
+ #endif
+ 
+-        const tinfo_t& typeid_this = tinfo();//typeid(*this);
+-        const tinfo_t& typeid_other = other.tinfo();//typeid(other);
+-        if (typeid_this == typeid_other) {
+-//              int cmpval = compare_same_type(other);
+-//              if (cmpval!=0) {
+-//                      std::cout << "hash collision, same type: " 
+-//                                << *this << " and " << other << std::endl;
+-//                      this->print(print_tree(std::cout));
+-//                      std::cout << " and ";
+-//                      other.print(print_tree(std::cout));
+-//                      std::cout << std::endl;
+-//              }
+-//              return cmpval;
++	const tinfo_t& typeid_this = tinfo();//typeid(*this);
++	const tinfo_t& typeid_other = other.tinfo();//typeid(other);
++	if (typeid_this == typeid_other) {
++//		int cmpval = compare_same_type(other);
++//		if (cmpval!=0) {
++//			std::cout << "hash collision, same type: " 
++//			          << *this << " and " << other << std::endl;
++//			this->print(print_tree(std::cout));
++//			std::cout << " and ";
++//			other.print(print_tree(std::cout));
++//			std::cout << std::endl;
++//		}
++//		return cmpval;
+ #ifdef GINAC_COMPARE_STATISTICS
+-                compare_statistics.compare_same_type++;
++		compare_statistics.compare_same_type++;
+ #endif
+-                return compare_same_type(other);
+-        } else {
+-//              std::cout << "hash collision, different types: " 
+-//                        << *this << " and " << other << std::endl;
+-//              this->print(print_tree(std::cout));
+-//              std::cout << " and ";
+-//              other.print(print_tree(std::cout));
+-//              std::cout << std::endl;
+-                //return (typeid_this.before(typeid_other) ? -1 : 1);
++		return compare_same_type(other);
++	} else {
++//		std::cout << "hash collision, different types: " 
++//		          << *this << " and " << other << std::endl;
++//		this->print(print_tree(std::cout));
++//		std::cout << " and ";
++//	 	other.print(print_tree(std::cout));
++//	 	std::cout << std::endl;
++		//return (typeid_this.before(typeid_other) ? -1 : 1);
+ 		return (typeid_this<typeid_other ? -1 : 1);
+-        }
++	}
+ }
+ 
+ /** Test for syntactic equality.
+diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp
+--- a/ginac/expairseq.cpp
++++ b/ginac/expairseq.cpp
+@@ -71,7 +71,7 @@
+ 
+ // public
+ 
+-expairseq::expairseq() : inherited(&expairseq::tinfo_static), seq_sorted(NULL)
++expairseq::expairseq() : inherited(&expairseq::tinfo_static)
+ #if EXPAIRSEQ_USE_HASHTAB
+                                                    , hashtabsize(0)
+ #endif // EXPAIRSEQ_USE_HASHTAB
+@@ -110,20 +110,20 @@
+ // other constructors
+ //////////
+ 
+-expairseq::expairseq(const ex &lh, const ex &rh) : inherited(&expairseq::tinfo_static), seq_sorted(NULL)
++expairseq::expairseq(const ex &lh, const ex &rh) : inherited(&expairseq::tinfo_static)
+ {
+ 	construct_from_2_ex(lh,rh);
+ 	GINAC_ASSERT(is_canonical());
+ }
+ 
+-expairseq::expairseq(const exvector &v) : inherited(&expairseq::tinfo_static), seq_sorted(NULL)
++expairseq::expairseq(const exvector &v) : inherited(&expairseq::tinfo_static)
+ {
+ 	construct_from_exvector(v);
+ 	GINAC_ASSERT(is_canonical());
+ }
+ 
+ expairseq::expairseq(const epvector &v, const ex &oc, bool do_index_renaming)
+-  : inherited(&expairseq::tinfo_static), overall_coeff(oc), seq_sorted(NULL)
++  : inherited(&expairseq::tinfo_static), overall_coeff(oc)
+ {
+ 	GINAC_ASSERT(is_a<numeric>(oc));
+ 	construct_from_epvector(v, do_index_renaming);
+@@ -131,7 +131,7 @@
+ }
+ 
+ expairseq::expairseq(std::auto_ptr<epvector> vp, const ex &oc, bool do_index_renaming)
+-  : inherited(&expairseq::tinfo_static), overall_coeff(oc), seq_sorted(NULL)
++  : inherited(&expairseq::tinfo_static), overall_coeff(oc)
+ {
+ 	GINAC_ASSERT(vp.get()!=0);
+ 	GINAC_ASSERT(is_a<numeric>(oc));
+@@ -143,7 +143,7 @@
+ // archiving
+ //////////
+ 
+-expairseq::expairseq(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst), seq_sorted(NULL)
++expairseq::expairseq(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+ #if EXPAIRSEQ_USE_HASHTAB
+ 	, hashtabsize(0)
+ #endif
+@@ -312,8 +312,7 @@
+ ex expairseq::stable_op(size_t i) const
+ {
+ 	if (i < seq.size()) {
+-		const epvector* sorted_seq = get_sorted_seq();
+-		return recombine_pair_to_ex((*sorted_seq)[i]);
++		return recombine_pair_to_ex(get_sorted_seq()[i]);
+ 	}
+ 	GINAC_ASSERT(!overall_coeff.is_equal(default_overall_coeff()));
+ 	return overall_coeff;
+@@ -1765,6 +1764,15 @@
+ 	return std::auto_ptr<epvector>(0);
+ }
+ 
++
++const epvector & expairseq::get_sorted_seq() const
++{
++	if (seq_sorted.empty())
++		return seq;
++	else
++		return seq_sorted;
++}
++
+ //////////
+ // static member variables
+ //////////
+diff --git a/ginac/expairseq.h b/ginac/expairseq.h
+--- a/ginac/expairseq.h
++++ b/ginac/expairseq.h
+@@ -75,7 +75,6 @@
+ 	expairseq(const exvector & v);
+ 	expairseq(const epvector & v, const ex & oc, bool do_index_renaming = false);
+ 	expairseq(std::auto_ptr<epvector>, const ex & oc, bool do_index_renaming = false);
+-	~expairseq() { if (!seq_sorted) delete seq_sorted; }
+ 	
+ 	// functions overriding virtual functions from base classes
+ public:
+@@ -92,7 +91,7 @@
+ 	ex subs(const exmap & m, unsigned options = 0) const;
+ 	ex conjugate() const;
+ 	numeric calc_total_degree() const;
+-	virtual const epvector* get_sorted_seq() const { return &seq; }
++	virtual const epvector & get_sorted_seq() const;
+ protected:
+ 	bool is_equal_same_type(const basic & other) const;
+ 	unsigned return_type() const;
+@@ -166,7 +165,7 @@
+ 	
+ protected:
+ 	epvector seq;
+-	mutable epvector *seq_sorted;
++	mutable epvector seq_sorted;
+ 	ex overall_coeff;
+ #if EXPAIRSEQ_USE_HASHTAB
+ 	epplistvector hashtab;
+diff --git a/ginac/mul.cpp b/ginac/mul.cpp
+--- a/ginac/mul.cpp
++++ b/ginac/mul.cpp
+@@ -259,9 +259,8 @@
+ 
+ 	// Separate factors into those with negative numeric exponent
+ 	// and all others
+-	epvector* sorted_seq = get_sorted_seq();
+-	epvector::const_iterator it = sorted_seq->begin(), itend = sorted_seq->end();
+-	//epvector::const_iterator it = seq.begin(), itend = seq.end();
++	const epvector & sorted_seq = get_sorted_seq();
++	epvector::const_iterator it = sorted_seq.begin(), itend = sorted_seq.end();
+ 	exvector neg_powers, others;
+ 	while (it != itend) {
+ 		GINAC_ASSERT(is_exactly_a<numeric>(it->coeff));
+@@ -787,10 +786,10 @@
+ 	infinity result = ex_to<infinity>(recombine_pair_to_ex(*infinity_iter));
+ 	result *= overall_coeff;
+ 
+-        for (epvector::const_iterator i = seq.begin(); i != seq.end(); i++) {
+-                if (i == infinity_iter) continue;
++	for (epvector::const_iterator i = seq.begin(); i != seq.end(); i++) {
++		if (i == infinity_iter) continue;
+ 		result *= recombine_pair_to_ex(*i);
+-        }
++	}
+ 	return result;
+ }
+ 
+@@ -1507,15 +1506,15 @@
+ 	}
+ }
+ 
+-epvector* mul::get_sorted_seq() const
++const epvector & mul::get_sorted_seq() const
+ {
+-	if (!this->seq_sorted) {
+-		seq_sorted = new epvector(seq.size());
++	if (seq_sorted.empty() and not seq.empty()) {
++		seq_sorted = epvector(seq.size());
+ 		partial_sort_copy(seq.begin(), seq.end(),
+-				seq_sorted->begin(), seq_sorted->end(),
+-				print_order_pair_mul());
++				  seq_sorted.begin(), seq_sorted.end(),
++				  print_order_pair_mul());
+ 	}
+-	return seq_sorted;
++	return expairseq::get_sorted_seq();
+ }
+ 
+   
+diff --git a/ginac/mul.h b/ginac/mul.h
+--- a/ginac/mul.h
++++ b/ginac/mul.h
+@@ -97,7 +97,7 @@
+ public:
+ 	ex algebraic_subs_mul(const exmap & m, unsigned options) const;
+ 	double total_degree() const;
+-	epvector* get_sorted_seq() const;
++	const epvector & get_sorted_seq() const;
+ 	//int compare_symbol(const symbol &other) const;
+ 	//int compare_pow(const power &other) const;
+ protected:
+diff --git a/ginac/order.cpp b/ginac/order.cpp
+--- a/ginac/order.cpp
++++ b/ginac/order.cpp
+@@ -36,9 +36,63 @@
+ 		return exp.to_double();
+ 	else 
+ 		return std::sqrt(std::pow(exp.real().to_double(), 2) + 
+-				std::pow(exp.imag().to_double(), 2));
++				 std::pow(exp.imag().to_double(), 2));
+ }
+ 
++
++// Methods to get type id's. These cannot be const static because the
++// id's are set by another static initializer.
++  
++const tinfo_t & print_order::function_id() const
++{
++	static tinfo_t id = find_tinfo_key("function");
++	return id;
++}
++
++const tinfo_t & print_order::fderivative_id() const
++{
++	static tinfo_t id = find_tinfo_key("fderivative");
++	return id;
++}
++
++const tinfo_t & print_order::power_id() const
++{
++	static tinfo_t id = find_tinfo_key("power");
++	return id;
++}
++
++const tinfo_t & print_order::symbol_id() const
++{
++	static tinfo_t id = find_tinfo_key("symbol");
++	return id;
++}
++
++const tinfo_t & print_order::mul_id() const
++{
++	static tinfo_t id = find_tinfo_key("mul");
++	return id;
++}
++
++const tinfo_t & print_order::add_id() const
++{
++	static tinfo_t id = find_tinfo_key("add");
++	return id;
++}
++
++const tinfo_t & print_order::numeric_id() const
++{
++	static tinfo_t id = find_tinfo_key("numeric");
++	return id;
++}
++
++const tinfo_t & print_order::constant_id() const
++{
++	static tinfo_t id = find_tinfo_key("constant");
++	return id;
++}
++
++
++
+ /** What Sage does for printing:
+  To print multivariate polynomials, SAGE uses "reversed" (bigger terms first)
+  'degrevlex' order i.e. "reversed" graded reversed lexicographic order, the
+@@ -50,16 +104,14 @@
+ /** Returns true if lhex > rhex for 'degrevlex' of Sage
+  i.e. graded reversed lexicographic order
+ */
+-bool print_order::operator() (const ex &lhex, const ex &rhex) const {
+-	const basic *lh = get_pointer(lhex.bp);
+-	const basic *rh = get_pointer(rhex.bp);
+-	return compare(lh, rh) == 1;
++bool print_order::operator() (const ex &lhex, const ex &rhex) const 
++{
++	return compare(lhex, rhex) == 1;
+ }
+ 
+-int print_order::compare (const ex &lhex, const ex &rhex) const {
+-	const basic *lh = get_pointer(lhex.bp);
+-	const basic *rh = get_pointer(rhex.bp);
+-	return compare(lh, rh);
++int print_order::compare(const ex &lhex, const ex &rhex) const 
++{
++	return compare(*lhex.bp, *rhex.bp);
+ }
+ 
+ bool print_order_pair_mul::operator() (const expair &lhex, const expair &rhex) const
+@@ -73,19 +125,15 @@
+ 
+ bool print_order_pair::operator() (const expair &lhex, const expair &rhex) const
+ {
+-	const basic *lh = get_pointer(lhex.rest.bp);
+-	const basic *rh = get_pointer(rhex.rest.bp);
+-
+ 	// compare rests
+-	int cmpval = print_order().compare(lh, rh);
++	int cmpval = print_order().compare(lhex.rest, rhex.rest);
+ 	if (cmpval != 0) {
+ 		return cmpval == 1;
+ 	}
+ 	return compare_degrees(lhex, rhex);
+ }
+ 
+-bool print_order_pair::compare_degrees(const expair &lhex,
+-		const expair &rhex) const
++bool print_order_pair::compare_degrees(const expair &lhex, const expair &rhex) const
+ {
+ 	// compare coeffs which are numerics
+ 	double lh_deg = numeric_to_double(ex_to<numeric>(lhex.coeff));
+@@ -108,123 +156,117 @@
+  1 if a > b
+  as <=> in Perl and GiNaC internal functions
+ */
++int print_order::compare(const basic &lh, const basic &rh) const 
++{
++	const tinfo_t typeid_lh = lh.tinfo();
++	const tinfo_t typeid_rh = rh.tinfo();
+ 
+-int print_order::compare(const basic *lh, const basic *rh) const {
+-	const tinfo_t typeid_lh = lh->tinfo();
+-	const tinfo_t typeid_rh = rh->tinfo();
+-
+-	if (typeid_rh==typeid_lh) {
+-		if (typeid_rh == mul_id) {
+-			return compare_same_type_mul(
+-					static_cast<const mul*>(lh),
+-					static_cast<const mul*>(rh));
+-		} else if (typeid_rh == add_id) {
++	if (typeid_rh==typeid_lh)
++		if (typeid_rh == mul_id())
++			return compare_same_type_mul(static_cast<const mul&>(lh),
++						     static_cast<const mul&>(rh));
++		else if (typeid_rh == add_id())
+ 			return compare_same_type_add(
+-					static_cast<const add*>(lh),
+-					static_cast<const add*>(rh));
+-		} else if (typeid_rh == symbol_id) {
+-			return compare_same_type_symbol(
+-					static_cast<const symbol*>(lh),
+-					static_cast<const symbol*>(rh));
+-		} else if (typeid_rh == power_id) {
+-			return compare_same_type_power(
+-					static_cast<const power*>(lh),
+-					static_cast<const power*>(rh));
+-		} else if (typeid_rh == function_id) {
+-			return compare_same_type_function(
+-					static_cast<const function*>(lh),
+-					static_cast<const function*>(rh));
+-		} else if (typeid_rh == fderivative_id) {
+-			return compare_same_type_fderivative(
+-					static_cast<const fderivative*>(lh),
+-					static_cast<const fderivative*>(rh));
+-		} else {
++						     static_cast<const add&>(lh),
++						     static_cast<const add&>(rh));
++		else if (typeid_rh == symbol_id())
++			return compare_same_type_symbol(static_cast<const symbol&>(lh),
++							static_cast<const symbol&>(rh));
++		else if (typeid_rh == power_id())
++			return compare_same_type_power(static_cast<const power&>(lh),
++						       static_cast<const power&>(rh));
++		else if (typeid_rh == function_id())
++			return compare_same_type_function(static_cast<const function&>(lh),
++							  static_cast<const function&>(rh));
++		else if (typeid_rh == fderivative_id())
++			return compare_same_type_fderivative(static_cast<const fderivative&>(lh),
++							     static_cast<const fderivative&>(rh));
++		else
+ 			// using GiNaC functions by default
+-			return lh->compare_same_type(*rh);
+-		}
++			return -lh.compare_same_type(rh);
++		
+ 	// at present numerics are combined into overall_coefficient
+ 	// even when hold parameter is used
+-	} else if (typeid_lh == numeric_id) {
++	else if (typeid_lh == numeric_id())
+ 	 	//print numerics before anything else
+ 		return 1;
+-	} else if (typeid_rh == numeric_id) {
++	else if (typeid_rh == numeric_id())
+ 	 	//print numerics before anything else
+ 		return -1;
+-	} else if (typeid_lh == constant_id) {
++	else if (typeid_lh == constant_id())
+ 	 	//print constants before anything else (but numerics)
+ 		return 1;
+-	} else if (typeid_rh == constant_id) {
++	else if (typeid_rh == constant_id())
+ 	 	//print constants before anything else (but numerics)
+ 		return -1;
+-	} else if (typeid_lh == fderivative_id) {
++	else if (typeid_lh == fderivative_id())
+ 		//print fderivatives after everything else
+ 		return -1;
+-	} else if (typeid_rh == fderivative_id) {
++	else if (typeid_rh == fderivative_id())
+ 		//print fderivatives after everything esle
+ 		return 1;
+-	} else if (typeid_lh == function_id) {
++	else if (typeid_lh == function_id())
+ 		//print functions before fderivatives, after anything else
+ 		return -1;
+-	} else if (typeid_rh == function_id) {
++	else if (typeid_rh == function_id())
+ 		//print functions before fderivatives, after anything else
+ 		return 1;
+-	} else if (typeid_lh == mul_id) {
+-		if (typeid_rh == power_id) {
++	else if (typeid_lh == mul_id())
++		if (typeid_rh == power_id())
+ 			return compare_mul_power(
+-					static_cast<const mul*>(lh),
+-					static_cast<const power*>(rh));
+-		} else if (typeid_rh == symbol_id) {
++					static_cast<const mul&>(lh),
++					static_cast<const power&>(rh));
++		else if (typeid_rh == symbol_id())
+ 			return compare_mul_symbol(
+-					static_cast<const mul*>(lh),
+-					static_cast<const symbol*>(rh));
+-		} else if (typeid_rh == add_id) {
++					static_cast<const mul&>(lh),
++					static_cast<const symbol&>(rh));
++		else if (typeid_rh == add_id())
+ 			return -compare_add_mul(
+-					static_cast<const add*>(rh),
+-					static_cast<const mul*>(lh));
+-		}
+-	} else if (typeid_lh == add_id) {
+-		if (typeid_rh == power_id) {
++					static_cast<const add&>(rh),
++					static_cast<const mul&>(lh));
++		else throw (std::runtime_error("comparing typeid's"));
++	else if (typeid_lh == add_id())
++		if (typeid_rh == power_id())
+ 			return compare_add_power(
+-					static_cast<const add*>(lh),
+-					static_cast<const power*>(rh));
+-		} else if (typeid_rh == symbol_id) {
++					static_cast<const add&>(lh),
++					static_cast<const power&>(rh));
++		else if (typeid_rh == symbol_id())
+ 			return compare_add_symbol(
+-					static_cast<const add*>(lh),
+-					static_cast<const symbol*>(rh));
+-		} else if (typeid_rh == mul_id) {
++					static_cast<const add&>(lh),
++					static_cast<const symbol&>(rh));
++		else if (typeid_rh == mul_id())
+ 			return compare_add_mul(
+-					static_cast<const add*>(lh),
+-					static_cast<const mul*>(rh));
+-		}
+-	} else if (typeid_lh == power_id) {
+-		if (typeid_rh == mul_id) {
++					static_cast<const add&>(lh),
++					static_cast<const mul&>(rh));
++		else throw (std::runtime_error("comparing typeid's"));
++	else if (typeid_lh == power_id())
++		if (typeid_rh == mul_id())
+ 			return -compare_mul_power(
+-					static_cast<const mul*>(rh),
+-					static_cast<const power*>(lh));
+-		} else if (typeid_rh == add_id) {
++					static_cast<const mul&>(rh),
++					static_cast<const power&>(lh));
++		else if (typeid_rh == add_id())
+ 			return -compare_add_power(
+-					static_cast<const add*>(rh),
+-					static_cast<const power*>(lh));
+-		} else if (typeid_rh == symbol_id) {
++					static_cast<const add&>(rh),
++					static_cast<const power&>(lh));
++		else if (typeid_rh == symbol_id())
+ 			return compare_power_symbol(
+-					static_cast<const power*>(lh),
+-					static_cast<const symbol*>(rh));
+-		}
+-	} else if (typeid_lh == symbol_id) {
+-		if (typeid_rh == mul_id) {
++					static_cast<const power&>(lh),
++					static_cast<const symbol&>(rh));
++		else throw (std::runtime_error("comparing typeid's"));
++	else if (typeid_lh == symbol_id())
++		if (typeid_rh == mul_id())
+ 			return -compare_mul_symbol(
+-					static_cast<const mul*>(rh),
+-					static_cast<const symbol*>(lh));
+-		} else if (typeid_rh == add_id) {
++					static_cast<const mul&>(rh),
++					static_cast<const symbol&>(lh));
++		else if (typeid_rh == add_id())
+ 			return -compare_add_symbol(
+-					static_cast<const add*>(rh),
+-					static_cast<const symbol*>(lh));
+-		} else if (typeid_rh == power_id) {
++					static_cast<const add&>(rh),
++					static_cast<const symbol&>(lh));
++		else if (typeid_rh == power_id())
+ 			return -compare_power_symbol(
+-					static_cast<const power*>(rh),
+-					static_cast<const symbol*>(lh));
+-		}
+-	}
++					static_cast<const power&>(rh),
++					static_cast<const symbol&>(lh));
++		else throw (std::runtime_error("comparing typeid's"));
+ 	throw (std::runtime_error("comparing typeid's"));
+ }
+ 
+@@ -232,32 +274,31 @@
+ // same behavior within mul and add objects:
+ // the total degree of the symbol is 1
+ // check total degree of mul then compare smallest item to symbol
+-int print_order::compare_mul_symbol(const mul *lh,
+-		const symbol *rh) const
++int print_order::compare_mul_symbol(const mul &lh, const symbol &rh) const
+ {
+ 	int cmpval;
+ 
+ 	double tdeg;
+-	tdeg = lh->total_degree();
++	tdeg = lh.total_degree();
+ 
+ 	if (tdeg != 1)
+ 		return tdeg > 1 ? 1 : -1;
+ 	
+-	const expair smallest_item = lh->get_sorted_seq()->back();
++	const expair smallest_item = lh.get_sorted_seq().back();
+ 
+ 	// compare bases
+-	cmpval = compare(get_pointer(smallest_item.rest.bp), rh);
++	cmpval = compare(*smallest_item.rest.bp, rh);
+ 	if (cmpval != 0) {
+ 		return cmpval;
+ 	}
+ 
+ 	// compare exponents
+-	cmpval = -compare(get_pointer(smallest_item.coeff.bp),_num1_p);
++	cmpval = -compare(*smallest_item.coeff.bp, *_num1_p);
+ 	if (cmpval != 0) {
+ 		return cmpval;
+ 	}
+ 
+-	if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
++	if (lh.seq.size() == 1 && lh.overall_coeff.is_equal(_ex1))
+ 		return 0;
+ 
+ 	// there is something of total degree 0 in front of the mul object
+@@ -269,39 +310,36 @@
+ // first we compare total degrees
+ // if equal we compare the smallest basis in the sequence to the basis in other
+ // then their exponents
+-int print_order::compare_mul_power(const mul *lh,
+-		const power *rh) const
++int print_order::compare_mul_power(const mul &lh, const power &rh) const
+ {
+ 	int cmpval;
+ 
+-	double lh_deg = lh->total_degree();
++	double lh_deg = lh.total_degree();
+ 	double rh_deg = 1;
+ 	numeric rh_exp;
+-	if (is_a<numeric>(rh->exponent)) {
+-		rh_deg = numeric_to_double(ex_to<numeric>(rh->exponent));
++	if (is_a<numeric>(rh.exponent)) {
++		rh_deg = numeric_to_double(ex_to<numeric>(rh.exponent));
+ 	}
+ 	if (rh_deg != lh_deg)
+ 		return lh_deg < rh_deg ? -1 : 1;
+ 	// same total degree
+ 
+ 	// smallest item is at the end of the sorted sequence
+-	const expair smallest_item = lh->get_sorted_seq()->back();
++	const expair smallest_item = lh.get_sorted_seq().back();
+ 	
+ 	// compare bases
+-	cmpval = compare(get_pointer(smallest_item.rest.bp),
+-			get_pointer(rh->basis.bp));
++	cmpval = compare(smallest_item.rest, rh.basis);
+ 	if (cmpval != 0) {
+ 		return cmpval;
+ 	}
+ 
+ 	// compare exponents
+-	cmpval = -compare(get_pointer(smallest_item.coeff.bp),
+-			get_pointer(rh->exponent.bp));
++	cmpval = -compare(smallest_item.coeff, rh.exponent);
+ 	if (cmpval != 0) {
+ 		return cmpval;
+ 	}
+ 
+-	if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex1))
++	if (lh.seq.size() == 1 && lh.overall_coeff.is_equal(_ex1))
+ 		return 0;
+ 
+ 	// there is something of total degree 0 in front of the mul object
+@@ -314,36 +352,33 @@
+ // if equal we compare the basis of the smallest items
+ // then their exponents
+ // and so on
+-int print_order::compare_same_type_mul(const mul *lh,
+-		const mul *rh) const
++int print_order::compare_same_type_mul(const mul &lh, const mul &rh) const
+ {
+ 	int cmpval;
+ 	
+ 	// compare total degrees
+-	double lh_deg = lh->total_degree();
+-	double rh_deg = rh->total_degree();
++	double lh_deg = lh.total_degree();
++	double rh_deg = rh.total_degree();
+ 	if (lh_deg != rh_deg)
+ 		return lh_deg < rh_deg ? -1 : 1;
+ 	
+ 	// compare each item in lh to corresponding element in rh
+-	const epvector *sorted_seq1 = lh->get_sorted_seq();
+-	const epvector *sorted_seq2 = rh->get_sorted_seq();
+-	epvector::const_reverse_iterator cit1 = sorted_seq1->rbegin();
+-	epvector::const_reverse_iterator cit2 = sorted_seq2->rbegin();
+-	epvector::const_reverse_iterator last1 = sorted_seq1->rend();
+-	epvector::const_reverse_iterator last2 = sorted_seq2->rend();
++	const epvector & sorted_seq1 = lh.get_sorted_seq();
++	const epvector & sorted_seq2 = rh.get_sorted_seq();
++	epvector::const_reverse_iterator cit1 = sorted_seq1.rbegin();
++	epvector::const_reverse_iterator cit2 = sorted_seq2.rbegin();
++	epvector::const_reverse_iterator last1 = sorted_seq1.rend();
++	epvector::const_reverse_iterator last2 = sorted_seq2.rend();
+ 
+ 	for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
+ 		// compare bases
+-		cmpval = compare(get_pointer(cit1->rest.bp),
+-				get_pointer(cit2->rest.bp));
++	  cmpval = compare(cit1->rest, cit2->rest);
+ 		if (cmpval != 0) {
+ 			return cmpval;
+ 		}
+ 
+ 		// compare exponents
+-		cmpval = -compare(get_pointer(cit1->coeff.bp),
+-				get_pointer(cit2->coeff.bp));
++		cmpval = -compare(cit1->coeff, cit2->coeff);
+ 		if (cmpval != 0) {
+ 			return cmpval;
+ 		}
+@@ -356,8 +391,7 @@
+ 		return -1;
+ 
+ 	// compare overall_coeff
+-	cmpval = compare(get_pointer(lh->overall_coeff.bp),
+-			get_pointer(rh->overall_coeff.bp));
++	cmpval = compare(lh.overall_coeff, rh.overall_coeff);
+ 
+ 	return cmpval;
+ }
+@@ -365,26 +399,25 @@
+ // compare an add and a symbol objects
+ // same behavior wihtin mul and add objects:
+ // the coefficient of the symbol is 1
+-int print_order::compare_add_symbol(const add *lh,
+-		const symbol *rh) const
++int print_order::compare_add_symbol(const add &lh, const symbol &rh) const
+ {
+ 	int cmpval;
+ 
+-	const expair biggest_item = lh->get_sorted_seq()->front();
++	const expair biggest_item = lh.get_sorted_seq().front();
+ 
+ 	// compare bases
+-	cmpval = print_order().compare(get_pointer(biggest_item.rest.bp), rh);
++	cmpval = print_order().compare(*biggest_item.rest.bp, rh);
+ 	if (cmpval != 0) {
+ 		return cmpval;
+ 	}
+ 
+ 	// compare coefficients
+-	cmpval = compare(get_pointer(biggest_item.coeff.bp),_num1_p);
++	cmpval = compare(*biggest_item.coeff.bp, *_num1_p);
+ 	if (cmpval != 0) {
+ 		return cmpval;
+ 	}
+ 
+-	if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex0))
++	if (lh.seq.size() == 1 && lh.overall_coeff.is_equal(_ex0))
+ 		return 0;
+ 
+ 	// there is something at the end of the add object
+@@ -394,25 +427,25 @@
+ // compare an add and a mul objects
+ // same behavior within mul and add objects:
+ // the coefficient of the mul object is 1
+-int print_order::compare_add_mul(const add *lh,
+-		const mul *rh) const
++int print_order::compare_add_mul(const add &lh,
++				 const mul &rh) const
+ {
+ 	int cmpval;
+-	const expair biggest_item = lh->get_sorted_seq()->front();
++	const expair biggest_item = lh.get_sorted_seq().front();
+ 
+ 	// compare bases
+-	cmpval = print_order().compare(get_pointer(biggest_item.rest.bp), rh);
++	cmpval = print_order().compare(*biggest_item.rest.bp, rh);
+ 	if (cmpval != 0) {
+ 		return cmpval;
+ 	}
+ 
+ 	// compare coefficients
+-	cmpval = compare(get_pointer(biggest_item.coeff.bp),_num1_p);
++	cmpval = compare(*biggest_item.coeff.bp, *_num1_p);
+ 	if (cmpval != 0) {
+ 		return cmpval;
+ 	}
+ 
+-	if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex0))
++	if (lh.seq.size() == 1 && lh.overall_coeff.is_equal(_ex0))
+ 		return 0;
+ 
+ 	// there is something at the end of the object
+@@ -422,25 +455,25 @@
+ // compare an add and a pow objects
+ // same behavior wihtin mul and add objects:
+ // the coefficient of the power object is 1
+-int print_order::compare_add_power(const add *lh,
+-		const power *rh) const
++int print_order::compare_add_power(const add &lh,
++		const power &rh) const
+ {
+ 	int cmpval;
+-	const expair biggest_item = lh->get_sorted_seq()->front();
++	const expair biggest_item = lh.get_sorted_seq().front();
+ 
+ 	// compare bases
+-	cmpval = print_order().compare(get_pointer(biggest_item.rest.bp), rh);
++	cmpval = print_order().compare(*biggest_item.rest.bp, rh);
+ 	if (cmpval != 0) {
+ 		return cmpval;
+ 	}
+ 
+ 	// compare coefficients
+-	cmpval = compare(get_pointer(biggest_item.coeff.bp),_num1_p);
++	cmpval = compare(*biggest_item.coeff.bp, *_num1_p);
+ 	if (cmpval != 0) {
+ 		return cmpval;
+ 	}
+ 
+-	if (lh->seq.size() == 1 && lh->overall_coeff.is_equal(_ex0))
++	if (lh.seq.size() == 1 && lh.overall_coeff.is_equal(_ex0))
+ 		return 0;
+ 
+ 	// there is something at the end of the object
+@@ -452,27 +485,26 @@
+ // first we compare the basis of the biggest items
+ // then their coefficients
+ // and so on
+-int print_order::compare_same_type_add(const add *lh,
+-		const add *rh) const
++int print_order::compare_same_type_add(const add &lh, const add &rh) const
+ {
+ 	int cmpval;
+ 
+-	const epvector *sorted_seq1 = lh->get_sorted_seq();
+-	const epvector *sorted_seq2 = rh->get_sorted_seq();
+-	epvector::const_iterator cit1 = sorted_seq1->begin();
+-	epvector::const_iterator cit2 = sorted_seq2->begin();
+-	epvector::const_iterator last1 = sorted_seq1->end();
+-	epvector::const_iterator last2 = sorted_seq2->end();
++	const epvector & sorted_seq1 = lh.get_sorted_seq();
++	const epvector & sorted_seq2 = rh.get_sorted_seq();
++	epvector::const_iterator cit1 = sorted_seq1.begin();
++	epvector::const_iterator cit2 = sorted_seq2.begin();
++	epvector::const_iterator last1 = sorted_seq1.end();
++	epvector::const_iterator last2 = sorted_seq2.end();
+ 
+ 	for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
+ 		// compare bases
+-		cmpval = print_order().compare(get_pointer(cit1->rest.bp),get_pointer(cit2->rest.bp));
++		cmpval = print_order().compare(cit1->rest, cit2->rest);
+ 		if (cmpval != 0) {
+ 			return cmpval;
+ 		}
+ 
+ 		// compare coefficients
+-		cmpval = compare(get_pointer(cit1->coeff.bp),get_pointer(cit2->coeff.bp));
++		cmpval = compare(cit1->coeff, cit2->coeff);
+ 		if (cmpval != 0) {
+ 			return cmpval;
+ 		}
+@@ -485,8 +517,7 @@
+ 		return -1;
+ 
+ 	// compare overall_coeff
+-	cmpval = compare(get_pointer(lh->overall_coeff.bp),
+-			get_pointer(rh->overall_coeff.bp));
++	cmpval = compare(lh.overall_coeff, rh.overall_coeff);
+ 	
+ 	return cmpval;
+ }
+@@ -499,32 +530,32 @@
+ // in add object:
+ // first exponents
+ // then bases
+-int print_order_mul::compare_power_symbol(const power *lh,
+-		const symbol *rh) const
++int print_order_mul::compare_power_symbol
++(const power &lh, const symbol &rh) const
+ {
+ 	int cmpval;
+-	cmpval = compare(get_pointer(lh->basis.bp), rh);
++	cmpval = compare(*lh.basis.bp, rh);
+ 	if (cmpval != 0)
+ 		  return cmpval;
+ 	
+-	cmpval = compare(get_pointer(lh->exponent.bp), _num1_p);
++	cmpval = compare(*lh.exponent.bp, *_num1_p);
+ 	
+ 	return cmpval;
+ }
+ 
+-int print_order::compare_power_symbol(const power *lh,
+-		const symbol *rh) const
++int print_order::compare_power_symbol(const power &lh,
++		const symbol &rh) const
+ {
+ 	int cmpval;
+ 
+ 	// We are in an add object
+-	if (is_a<numeric>(lh->exponent)) {
+-		double lh_deg = numeric_to_double(ex_to<numeric>(lh->exponent));
++	if (is_a<numeric>(lh.exponent)) {
++		double lh_deg = numeric_to_double(ex_to<numeric>(lh.exponent));
+ 		if (lh_deg != 1)
+ 			return lh_deg < 1 ? -1 : 1;
+ 	}
+ 
+-	cmpval = compare(get_pointer(lh->basis.bp), rh);
++	cmpval = compare(*lh.basis.bp, rh);
+ 
+ 	return cmpval;
+ }
+@@ -537,66 +568,64 @@
+ // in add object:
+ // first exponents
+ // then bases
+-int print_order_mul::compare_same_type_power(const power *lh,
+-		const power *rh) const
++int print_order_mul::compare_same_type_power(const power &lh, const power &rh) const
+ {
+ 	int cmpval;
+-	cmpval = compare(get_pointer(lh->basis.bp), get_pointer(rh->basis.bp));
++	cmpval = compare(lh.basis, rh.basis);
+ 	if (cmpval != 0)
+ 		  return cmpval;
+-	cmpval = compare(get_pointer(lh->exponent.bp), get_pointer(rh->exponent.bp));
++	cmpval = compare(lh.exponent, rh.exponent);
+ 	
+ 	return cmpval;
+ }
+-int print_order::compare_same_type_power(const power *lh,
+-		const power *rh) const
++
++
++int print_order::compare_same_type_power(const power &lh, const power &rh) const
+ {
+ 	int cmpval;
+ 
+ 	double lh_deg = 1;
+ 	double rh_deg = 1;
+-	if (is_a<numeric>(lh->exponent)) {
+-		lh_deg = numeric_to_double(ex_to<numeric>(lh->exponent));
++	if (is_a<numeric>(lh.exponent)) {
++		lh_deg = numeric_to_double(ex_to<numeric>(lh.exponent));
+ 	}
+-	if (is_a<numeric>(rh->exponent)) {
+-		rh_deg = numeric_to_double(ex_to<numeric>(rh->exponent));
++	if (is_a<numeric>(rh.exponent)) {
++		rh_deg = numeric_to_double(ex_to<numeric>(rh.exponent));
+ 	}
+ 	if (rh_deg != lh_deg)
+ 		return lh_deg < rh_deg ? -1 : 1;
+ 
+-	cmpval = compare(get_pointer(lh->basis.bp), get_pointer(rh->basis.bp));
++	cmpval = compare(lh.basis, rh.basis);
+ 	if (cmpval != 0)
+ 		return cmpval;
+ 
+-	if (is_a<numeric>(lh->exponent) && is_a<numeric>(rh->exponent))
++	if (is_a<numeric>(lh.exponent) && is_a<numeric>(rh.exponent))
+ 		return 0;
+-	return compare(get_pointer(lh->exponent.bp),
+-			get_pointer(rh->exponent.bp));
++	return compare(lh.exponent, rh.exponent);
+ }
+ 
+ // compare two symbol objects
+ // same behavior wihtin mul and add objects:
+ // we compare names
+-int print_order::compare_same_type_symbol(const symbol *lh,
+-		const symbol *rh) const
++int print_order::compare_same_type_symbol(const symbol &lh, const symbol &rh) const
+ {
+ 	/* Reversed ordering on char encoding (i.e. "a" < "b") then length
+ 	 * (i.e. "abc" < "abcd")
+ 	   i.e. "x" > "y" and "xyz" > "xyzt" */
+-	if (lh->serial==rh->serial) return 0;
+-	return lh->name < rh->name ? 1 : -1;
++	if (lh.serial==rh.serial) return 0;
++	return lh.name < rh.name ? 1 : -1;
+ }
+ 
+ // compare two containers of the same type
+ template <template <class T, class = std::allocator<T> > class C>
+-int print_order::compare_same_type_container(const container<C> *lh,
+-							 const container<C> *rh) const
++int print_order::compare_same_type_container(const container<C> &lh,
++					     const container<C> &rh) const
+ {
+-	typename C<ex>::const_iterator it1 = lh->seq.begin(), it1end = lh->seq.end(),
+-			      it2 = rh->seq.begin(), it2end = rh->seq.end();
++	typename C<ex>::const_iterator it1 = lh.seq.begin(), it1end = lh.seq.end(),
++			      it2 = rh.seq.begin(), it2end = rh.seq.end();
+ 
+ 	while (it1 != it1end && it2 != it2end) {
+-		int cmpval = compare(get_pointer(it1->bp), get_pointer(it2->bp));
++		int cmpval = compare(*it1, *it2);
+ 		if (cmpval)
+ 			return cmpval;
+ 		++it1; ++it2;
+@@ -608,27 +637,27 @@
+ // compare two function objects
+ // same behavior wihtin mul and add objects:
+ // we compare names
+-int print_order::compare_same_type_function(const function *lh,
+-		const function *rh) const
++int print_order::compare_same_type_function(const function &lh,
++					    const function &rh) const
+ {
+ 
+-	if (lh->serial==rh->serial)
+-		return compare_same_type_container(lh,rh);
+-	return lh->get_name() < rh->get_name() ? 1 : -1;	
++	if (lh.serial==rh.serial)
++		return compare_same_type_container(lh, rh);
++	return lh.get_name() < rh.get_name() ? 1 : -1;	
+ 
+ }
+ 
+ // compare two fderivative objects
+ // same behavior wihtin mul and add objects:
+ // we compare names
+-int print_order::compare_same_type_fderivative(const fderivative *lh,
+-		const fderivative *rh) const
++int print_order::compare_same_type_fderivative(const fderivative &lh,
++					       const fderivative &rh) const
+ {
+ 	int cmpval = compare_same_type_function(lh, rh);
+ 	if (cmpval != 0)
+ 		return cmpval;
+-	if (lh->parameter_set != rh->parameter_set)
+-		return lh->parameter_set < rh->parameter_set ? 1 : -1;
++	if (lh.parameter_set != rh.parameter_set)
++		return lh.parameter_set < rh.parameter_set ? 1 : -1;
+ 	return 0;
+ }
+ 
+diff --git a/ginac/order.h b/ginac/order.h
+--- a/ginac/order.h
++++ b/ginac/order.h
+@@ -36,68 +36,72 @@
+ namespace GiNaC {
+ 
+ class print_order : public std::binary_function<ex, ex, bool> {
+-	const tinfo_t function_id;// = find_tinfo_key("function");
+-	const tinfo_t fderivative_id;// = find_tinfo_key("fderivative");
+-	const tinfo_t power_id;// = find_tinfo_key("power");
+-	const tinfo_t symbol_id;// = find_tinfo_key("symbol");
+-	const tinfo_t mul_id;// = find_tinfo_key("mul");
+-	const tinfo_t add_id;// = find_tinfo_key("add");
+-	const tinfo_t numeric_id;// = find_tinfo_key("numeric");
+-	const tinfo_t constant_id;// = find_tinfo_key("constant");
++private:
++	const tinfo_t& function_id() const;
++	const tinfo_t& fderivative_id() const;
++	const tinfo_t& power_id() const;
++	const tinfo_t& symbol_id() const;
++	const tinfo_t& mul_id() const;
++	const tinfo_t& add_id() const;
++	const tinfo_t& numeric_id() const;
++	const tinfo_t& constant_id() const;
+ 
+-	public:
+-	print_order():
+-		function_id(find_tinfo_key("function")),
+-		fderivative_id(find_tinfo_key("fderivative")),
+-		power_id(find_tinfo_key("power")),
+-		symbol_id(find_tinfo_key("symbol")),
+-		mul_id(find_tinfo_key("mul")),
+-		add_id(find_tinfo_key("add")),
+-		numeric_id(find_tinfo_key("numeric")),
+-		constant_id(find_tinfo_key("constant")) {};
+-
++public:
+ 	bool operator() (const ex &lh, const ex &rh) const;
+ 	int compare(const ex &lh, const ex &rh) const;
+-	int compare(const basic *lh, const basic *rh) const;
++
++protected:
++	friend class print_order_pair;
++
++	//	int compare(const ptr<basic> &lh, const ptr<basic> &rh) const;
++
++	// all other compare() methods dispatch to this one
++	int compare(const basic &lh, const basic &rh) const;
++
+ 	// mul objects
+-	int compare_mul_symbol(const mul *lh, const symbol *rh) const;
+-	int compare_mul_power(const mul *lh, const power *rh) const;
+-	int compare_same_type_mul(const mul *lh, const mul *rh) const;
++	int compare_mul_symbol(const mul &lh, const symbol &rh) const;
++	int compare_mul_power(const mul &lh, const power &rh) const;
++	int compare_same_type_mul(const mul &lh, const mul &rh) const;
+ 	// add objects
+-	int compare_add_symbol(const add *lh, const symbol *rh) const;
+-	int compare_add_power(const add *lh, const power *rh) const;
+-	int compare_add_mul(const add *lh, const mul *rh) const;
+-	int compare_same_type_add(const add *lh, const add *rh) const;
++	int compare_add_symbol(const add &lh, const symbol &rh) const;
++	int compare_add_power(const add &lh, const power &rh) const;
++	int compare_add_mul(const add &lh, const mul &rh) const;
++	int compare_same_type_add(const add &lh, const add &rh) const;
+ 	// power objects
+-	virtual int compare_power_symbol(const power *lh, const symbol *rh) const;
+-	virtual int compare_same_type_power(const power *lh, const power *rh) const;
++	virtual int compare_power_symbol(const power &lh, const symbol &rh) const;
++	virtual int compare_same_type_power(const power &lh, const power &rh) const;
+ 	// symbol objects
+-	int compare_same_type_symbol(const symbol *lh, const symbol *rh) const;
++	int compare_same_type_symbol(const symbol &lh, const symbol &rh) const;
+ 	// container objects
+ 	template <template <class T, class = std::allocator<T> > class C>
+-	int compare_same_type_container(const container<C> *lh,const container<C> *rh) const;
++	int compare_same_type_container(const container<C> &lh, const container<C> &rh) const;
+ 	// function objects
+-	int compare_same_type_function(const function *lh, const function *rh) const;
++	int compare_same_type_function(const function &lh, const function &rh) const;
+ 	// fderivative objects
+-	int compare_same_type_fderivative(const fderivative *lh, const fderivative *rh) const;
++	int compare_same_type_fderivative(const fderivative &lh, const fderivative &rh) const;
+ };
+ 
++
+ class print_order_mul : public print_order {
+-	int compare_power_symbol(const power *lh, const symbol *rh) const;
+-	int compare_same_type_power(const power *lh, const power *rh) const;
++	int compare_power_symbol(const power &lh, const symbol &rh) const;
++	int compare_same_type_power(const power &lh, const power &rh) const;
+ };
+ 
++
+ // We have to define the following class to sort held expressions
+ // E.g. 3*x+2*x which does not get simplified to 5*x.
+-struct print_order_pair : \
+-		public std::binary_function<expair, expair, bool>
++class print_order_pair : 
++	public std::binary_function<expair, expair, bool>
+ {
++public:
+ 	bool operator() (const expair &lh, const expair &rh) const;
+ 	bool compare_degrees(const expair &lhex, const expair &rhex) const;
+ };
+ 
+-struct print_order_pair_mul : public print_order_pair
++
++class print_order_pair_mul : public print_order_pair
+ {
++public:
+ 	bool operator() (const expair &lh, const expair &rh) const;
+ };
+ 
+diff --git a/ginac/power.cpp b/ginac/power.cpp
+--- a/ginac/power.cpp
++++ b/ginac/power.cpp
+@@ -476,10 +476,7 @@
+ 		if (eexponent.info(info_flags::negative))
+ 			return _ex0;
+ 		if (eexponent.info(info_flags::positive))
+-			if (basis_inf.is_plus_infinity())
+-				return Infinity;
+-			else
+-				return UnsignedInfinity;
++			return mul(pow(basis_inf.get_direction(), eexponent), Infinity);
+ 		throw(std::domain_error("power::eval(): pow(Infinity, c)"
+ 					" for constant of undetermined sign is not defined."));
+ 	}
+@@ -493,7 +490,11 @@
+ 			throw(std::domain_error("power::eval(): pow(f(x), infinity) is not defined."));
+ 		// x^(c*oo) --> (x^c)^(+oo)
+ 		const ex abs_base = abs(pow(ebasis, exp_inf.get_direction()));
+-		if (abs_base > _ex1) return Infinity;
++		if (abs_base > _ex1) 
++			if (ebasis.info(info_flags::positive))
++				return Infinity;
++			else
++				return UnsignedInfinity;
+ 		if (abs_base < _ex1) return _ex0;
+ 		if (abs_base == _ex1)
+ 			throw(std::domain_error("power::eval(): pow(1, Infinity) is not defined."));