From 04f0c93e24cdb50f23cb3a6c0ecbeaac23b13ac0 Mon Sep 17 00:00:00 2001 From: Richard Kreckel Date: Tue, 8 May 2001 20:42:51 +0000 Subject: [PATCH] * All operators are now strictly following the semantics we all know from C/C++. I.e. e1+e2=42; is now impossible and other such stuff. For all remaining errors (i.e. ++e1 = e1+1;) the compiler alone is to blame... --- ginac/ex.cpp | 19 ------ ginac/ex.h | 10 ++-- ginac/operators.cpp | 140 +++++++++++++++++++++++++++++++++----------- ginac/operators.h | 51 +++++++++------- 4 files changed, 138 insertions(+), 82 deletions(-) diff --git a/ginac/ex.cpp b/ginac/ex.cpp index 77c79833..02d20e88 100644 --- a/ginac/ex.cpp +++ b/ginac/ex.cpp @@ -199,25 +199,6 @@ ex ex::rhs(void) const return (*static_cast(bp)).rhs(); } -/** Used internally by operator+() to add two ex objects together. */ -ex ex::exadd(const ex & rh) const -{ - return (new add(*this,rh))->setflag(status_flags::dynallocated); -} - -/** Used internally by operator*() to multiply two ex objects together. */ -ex ex::exmul(const ex & rh) const -{ - // Check if we are constructing a mul object or a ncmul object. Due to - // ncmul::eval()'s rule to pull out commutative elements we need to check - // only one of the elements. - if (rh.bp->return_type()==return_types::commutative || - bp->return_type()==return_types::commutative) - return (new mul(*this,rh))->setflag(status_flags::dynallocated); - else - return (new ncmul(*this,rh))->setflag(status_flags::dynallocated); -} - // private /** Make this ex writable (if more than one ex handle the same basic) by diff --git a/ginac/ex.h b/ginac/ex.h index 8ade899b..7b36eff8 100644 --- a/ginac/ex.h +++ b/ginac/ex.h @@ -52,7 +52,7 @@ public: ex(); ~ex(); ex(const ex & other); - const ex & operator=(const ex & other); + ex & operator=(const ex & other); // other ctors public: ex(const basic & other); @@ -124,9 +124,6 @@ public: unsigned return_type(void) const { return bp->return_type(); } unsigned return_type_tinfo(void) const { return bp->return_type_tinfo(); } unsigned gethash(void) const { return bp->gethash(); } - - ex exadd(const ex & rh) const; - ex exmul(const ex & rh) const; private: void construct_from_basic(const basic & other); void construct_from_int(int i); @@ -212,16 +209,17 @@ ex::ex(const ex & other) : bp(other.bp) } inline -const ex & ex::operator=(const ex & other) +ex & ex::operator=(const ex & other) { /*debugmsg("ex operator=",LOGLEVEL_ASSIGNMENT);*/ GINAC_ASSERT(bp!=0); GINAC_ASSERT(bp->flags & status_flags::dynallocated); GINAC_ASSERT(other.bp!=0); GINAC_ASSERT(other.bp->flags & status_flags::dynallocated); + // NB: must first increment other.bp->refcount, since other might be *this. + ++other.bp->refcount; if (--bp->refcount==0) delete bp; - ++other.bp->refcount; bp = other.bp; #ifdef OBSCURE_CINT_HACK update_last_created_or_assigned_bp(); diff --git a/ginac/operators.cpp b/ginac/operators.cpp index ee240174..3a4229ba 100644 --- a/ginac/operators.cpp +++ b/ginac/operators.cpp @@ -22,7 +22,10 @@ #include "operators.h" #include "numeric.h" +#include "add.h" +#include "mul.h" #include "power.h" +#include "ncmul.h" #include "relational.h" #include "print.h" #include "debugmsg.h" @@ -30,54 +33,79 @@ namespace GiNaC { +/** Used internally by operator+() to add two ex objects together. */ +static inline const ex exadd(const ex & lh, const ex & rh) +{ + return (new add(lh,rh))->setflag(status_flags::dynallocated); +} + +/** Used internally by operator*() to multiply two ex objects together. */ +static inline const ex exmul(const ex & lh, const ex & rh) +{ + // Check if we are constructing a mul object or a ncmul object. Due to + // ncmul::eval()'s rule to pull out commutative elements we need to check + // only one of the elements. + if (rh.return_type()==return_types::commutative || + lh.return_type()==return_types::commutative) + return (new mul(lh,rh))->setflag(status_flags::dynallocated); + else + return (new ncmul(lh,rh))->setflag(status_flags::dynallocated); +} + +/** Used internally by operator-() and friends to change the sign of an argument. */ +static inline const ex exminus(const ex & lh) +{ + return (new mul(lh,_ex_1()))->setflag(status_flags::dynallocated); +} + // binary arithmetic operators ex with ex -ex operator+(const ex & lh, const ex & rh) +const ex operator+(const ex & lh, const ex & rh) { debugmsg("operator+(ex,ex)",LOGLEVEL_OPERATOR); - return lh.exadd(rh); + return exadd(lh, rh); } -ex operator-(const ex & lh, const ex & rh) +const ex operator-(const ex & lh, const ex & rh) { debugmsg("operator-(ex,ex)",LOGLEVEL_OPERATOR); - return lh.exadd(rh.exmul(_ex_1())); + return exadd(lh, exminus(rh)); } -ex operator*(const ex & lh, const ex & rh) +const ex operator*(const ex & lh, const ex & rh) { debugmsg("operator*(ex,ex)",LOGLEVEL_OPERATOR); - return lh.exmul(rh); + return exmul(lh, rh); } -ex operator/(const ex & lh, const ex & rh) +const ex operator/(const ex & lh, const ex & rh) { debugmsg("operator/(ex,ex)",LOGLEVEL_OPERATOR); - return lh.exmul(power(rh,_ex_1())); + return exmul(lh, power(rh,_ex_1())); } // binary arithmetic operators numeric with numeric -numeric operator+(const numeric & lh, const numeric & rh) +const numeric operator+(const numeric & lh, const numeric & rh) { debugmsg("operator+(numeric,numeric)",LOGLEVEL_OPERATOR); return lh.add(rh); } -numeric operator-(const numeric & lh, const numeric & rh) +const numeric operator-(const numeric & lh, const numeric & rh) { debugmsg("operator-(numeric,numeric)",LOGLEVEL_OPERATOR); return lh.sub(rh); } -numeric operator*(const numeric & lh, const numeric & rh) +const numeric operator*(const numeric & lh, const numeric & rh) { debugmsg("operator*(numeric,numeric)",LOGLEVEL_OPERATOR); return lh.mul(rh); } -numeric operator/(const numeric & lh, const numeric & rh) +const numeric operator/(const numeric & lh, const numeric & rh) { debugmsg("operator/(numeric,ex)",LOGLEVEL_OPERATOR); return lh.div(rh); @@ -86,83 +114,125 @@ numeric operator/(const numeric & lh, const numeric & rh) // binary arithmetic assignment operators with ex -const ex & operator+=(ex & lh, const ex & rh) +ex & operator+=(ex & lh, const ex & rh) { debugmsg("operator+=(ex,ex)",LOGLEVEL_OPERATOR); - return (lh=lh.exadd(rh)); + return lh = exadd(lh, rh); } -const ex & operator-=(ex & lh, const ex & rh) +ex & operator-=(ex & lh, const ex & rh) { debugmsg("operator-=(ex,ex)",LOGLEVEL_OPERATOR); - return (lh=lh.exadd(rh.exmul(_ex_1()))); + return lh = exadd(lh, exminus(rh)); } -const ex & operator*=(ex & lh, const ex & rh) +ex & operator*=(ex & lh, const ex & rh) { debugmsg("operator*=(ex,ex)",LOGLEVEL_OPERATOR); - return (lh=lh.exmul(rh)); + return lh = exmul(lh, rh); } -const ex & operator/=(ex & lh, const ex & rh) +ex & operator/=(ex & lh, const ex & rh) { debugmsg("operator/=(ex,ex)",LOGLEVEL_OPERATOR); - return (lh=lh.exmul(power(rh,_ex_1()))); + return lh = exmul(lh, power(rh,_ex_1())); } // binary arithmetic assignment operators with numeric -const numeric & operator+=(numeric & lh, const numeric & rh) +numeric & operator+=(numeric & lh, const numeric & rh) { debugmsg("operator+=(numeric,numeric)",LOGLEVEL_OPERATOR); - return (lh=lh.add(rh)); + lh = lh.add(rh); + return lh; } -const numeric & operator-=(numeric & lh, const numeric & rh) +numeric & operator-=(numeric & lh, const numeric & rh) { debugmsg("operator-=(numeric,numeric)",LOGLEVEL_OPERATOR); - return (lh=lh.sub(rh)); + lh = lh.sub(rh); + return lh; } -const numeric & operator*=(numeric & lh, const numeric & rh) +numeric & operator*=(numeric & lh, const numeric & rh) { debugmsg("operator*=(numeric,numeric)",LOGLEVEL_OPERATOR); - return (lh=lh.mul(rh)); + lh = lh.mul(rh); + return lh; } -const numeric & operator/=(numeric & lh, const numeric & rh) +numeric & operator/=(numeric & lh, const numeric & rh) { debugmsg("operator/=(numeric,numeric)",LOGLEVEL_OPERATOR); - return (lh=lh.div(rh)); + lh = lh.div(rh); + return lh; } + // unary operators -ex operator+(const ex & lh) +const ex operator+(const ex & lh) { debugmsg("operator+(ex)",LOGLEVEL_OPERATOR); return lh; } -ex operator-(const ex & lh) +const ex operator-(const ex & lh) { debugmsg("operator-(ex)",LOGLEVEL_OPERATOR); - return lh.exmul(_ex_1()); + return exminus(lh); } -numeric operator+(const numeric & lh) +const numeric operator+(const numeric & lh) { debugmsg("operator+(numeric)",LOGLEVEL_OPERATOR); return lh; } -numeric operator-(const numeric & lh) +const numeric operator-(const numeric & lh) { debugmsg("operator-(numeric)",LOGLEVEL_OPERATOR); return _num_1().mul(lh); } + +// increment / decrement operators + +/** Expression prefix increment. Adds 1 and returns incremented ex. */ +ex & operator++(ex & rh) +{ + debugmsg("operator++(ex)",LOGLEVEL_OPERATOR); + return rh = exadd(rh, _ex1()); +} + +/** Expression prefix decrement. Subtracts 1 and returns decremented ex. */ +ex & operator--(ex & rh) +{ + debugmsg("operator--(ex)",LOGLEVEL_OPERATOR); + return rh = exadd(rh, _ex_1()); +} + +/** Expression postfix increment. Returns the ex and leaves the original + * incremented by 1. */ +const ex operator++(ex & lh, int) +{ + debugmsg("operator++(ex,int)",LOGLEVEL_OPERATOR); + ex tmp(lh); + lh = exadd(lh, _ex1()); + return tmp; +} + +/** Expression Postfix decrement. Returns the ex and leaves the original + * decremented by 1. */ +const ex operator--(ex & lh, int) +{ + debugmsg("operator--(ex,int)",LOGLEVEL_OPERATOR); + ex tmp(lh); + lh = exadd(lh, _ex_1()); + return tmp; +} + /** Numeric prefix increment. Adds 1 and returns incremented number. */ numeric& operator++(numeric & rh) { @@ -181,7 +251,7 @@ numeric& operator--(numeric & rh) /** Numeric postfix increment. Returns the number and leaves the original * incremented by 1. */ -numeric operator++(numeric & lh, int) +const numeric operator++(numeric & lh, int) { debugmsg("operator++(numeric,int)",LOGLEVEL_OPERATOR); numeric tmp(lh); @@ -191,7 +261,7 @@ numeric operator++(numeric & lh, int) /** Numeric Postfix decrement. Returns the number and leaves the original * decremented by 1. */ -numeric operator--(numeric & lh, int) +const numeric operator--(numeric & lh, int) { debugmsg("operator--(numeric,int)",LOGLEVEL_OPERATOR); numeric tmp(lh); diff --git a/ginac/operators.h b/ginac/operators.h index 47d1b745..b84d38b6 100644 --- a/ginac/operators.h +++ b/ginac/operators.h @@ -32,39 +32,46 @@ class numeric; class relational; // binary arithmetic operators ex with ex -ex operator+(const ex & lh, const ex & rh); -ex operator-(const ex & lh, const ex & rh); -ex operator*(const ex & lh, const ex & rh); -ex operator/(const ex & lh, const ex & rh); +const ex operator+(const ex & lh, const ex & rh); +const ex operator-(const ex & lh, const ex & rh); +const ex operator*(const ex & lh, const ex & rh); +const ex operator/(const ex & lh, const ex & rh); // binary arithmetic operators numeric with numeric -numeric operator+(const numeric & lh, const numeric & rh); -numeric operator-(const numeric & lh, const numeric & rh); -numeric operator*(const numeric & lh, const numeric & rh); -numeric operator/(const numeric & lh, const numeric & rh); +const numeric operator+(const numeric & lh, const numeric & rh); +const numeric operator-(const numeric & lh, const numeric & rh); +const numeric operator*(const numeric & lh, const numeric & rh); +const numeric operator/(const numeric & lh, const numeric & rh); // binary arithmetic assignment operators with ex -const ex & operator+=(ex & lh, const ex & rh); -const ex & operator-=(ex & lh, const ex & rh); -const ex & operator*=(ex & lh, const ex & rh); -const ex & operator/=(ex & lh, const ex & rh); +ex & operator+=(ex & lh, const ex & rh); +ex & operator-=(ex & lh, const ex & rh); +ex & operator*=(ex & lh, const ex & rh); +ex & operator/=(ex & lh, const ex & rh); // binary arithmetic assignment operators with numeric -const numeric & operator+=(numeric & lh, const numeric & rh); -const numeric & operator-=(numeric & lh, const numeric & rh); -const numeric & operator*=(numeric & lh, const numeric & rh); -const numeric & operator/=(numeric & lh, const numeric & rh); +numeric & operator+=(numeric & lh, const numeric & rh); +numeric & operator-=(numeric & lh, const numeric & rh); +numeric & operator*=(numeric & lh, const numeric & rh); +numeric & operator/=(numeric & lh, const numeric & rh); // unary operators -ex operator+(const ex & lh); -ex operator-(const ex & lh); +const ex operator+(const ex & lh); +const ex operator-(const ex & lh); + +const numeric operator+(const numeric & lh); +const numeric operator-(const numeric & lh); + +// increment / decrement operators +ex & operator++(ex & rh); +ex & operator--(ex & rh); +const ex operator++(ex & lh, int); +const ex operator--(ex & lh, int); -numeric operator+(const numeric & lh); -numeric operator-(const numeric & lh); numeric& operator++(numeric & rh); numeric& operator--(numeric & rh); -numeric operator++(numeric & lh, int); -numeric operator--(numeric & lh, int); +const numeric operator++(numeric & lh, int); +const numeric operator--(numeric & lh, int); // binary relational operators ex with ex relational operator==(const ex & lh, const ex & rh); -- 2.44.0