* ginac/registrar.h: dtor is inlined now.
[ginac.git] / ginac / operators.cpp
1 /** @file operators.cpp
2  *
3  *  Implementation of GiNaC's overloaded operators. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include "operators.h"
24 #include "numeric.h"
25 #include "power.h"
26 #include "relational.h"
27 #include "debugmsg.h"
28 #include "utils.h"
29
30 namespace GiNaC {
31
32 // binary arithmetic operators ex with ex
33
34 ex operator+(const ex & lh, const ex & rh)
35 {
36         debugmsg("operator+(ex,ex)",LOGLEVEL_OPERATOR);
37         return lh.exadd(rh);
38 }
39
40 ex operator-(const ex & lh, const ex & rh)
41 {
42         debugmsg("operator-(ex,ex)",LOGLEVEL_OPERATOR);
43         return lh.exadd(rh.exmul(_ex_1()));
44 }
45
46 ex operator*(const ex & lh, const ex & rh)
47 {
48         debugmsg("operator*(ex,ex)",LOGLEVEL_OPERATOR);
49         return lh.exmul(rh);
50 }
51
52 ex operator/(const ex & lh, const ex & rh)
53 {
54         debugmsg("operator/(ex,ex)",LOGLEVEL_OPERATOR);
55         return lh.exmul(power(rh,_ex_1()));
56 }
57
58 ex operator%(const ex & lh, const ex & rh)
59 {
60         debugmsg("operator%(ex,ex)",LOGLEVEL_OPERATOR);
61         return lh.exncmul(rh);
62 }
63
64
65 // binary arithmetic operators numeric with numeric
66
67 numeric operator+(const numeric & lh, const numeric & rh)
68 {
69         debugmsg("operator+(numeric,numeric)",LOGLEVEL_OPERATOR);
70         return lh.add(rh);
71 }
72
73 numeric operator-(const numeric & lh, const numeric & rh)
74 {
75         debugmsg("operator-(numeric,numeric)",LOGLEVEL_OPERATOR);
76         return lh.sub(rh);
77 }
78
79 numeric operator*(const numeric & lh, const numeric & rh)
80 {
81         debugmsg("operator*(numeric,numeric)",LOGLEVEL_OPERATOR);
82         return lh.mul(rh);
83 }
84
85 numeric operator/(const numeric & lh, const numeric & rh)
86 {
87         debugmsg("operator/(numeric,ex)",LOGLEVEL_OPERATOR);
88         return lh.div(rh);
89 }
90
91
92 // binary arithmetic assignment operators with ex
93
94 const ex & operator+=(ex & lh, const ex & rh)
95 {
96         debugmsg("operator+=(ex,ex)",LOGLEVEL_OPERATOR);
97         return (lh=lh.exadd(rh));
98 }
99
100 const ex & operator-=(ex & lh, const ex & rh)
101 {
102         debugmsg("operator-=(ex,ex)",LOGLEVEL_OPERATOR);
103         return (lh=lh.exadd(rh.exmul(_ex_1())));
104 }
105
106 const ex & operator*=(ex & lh, const ex & rh)
107 {
108         debugmsg("operator*=(ex,ex)",LOGLEVEL_OPERATOR);
109         return (lh=lh.exmul(rh));
110 }
111
112 const ex & operator/=(ex & lh, const ex & rh)
113 {
114         debugmsg("operator/=(ex,ex)",LOGLEVEL_OPERATOR);
115         return (lh=lh.exmul(power(rh,_ex_1())));
116 }
117
118 const ex & operator%=(ex & lh, const ex & rh)
119 {
120         debugmsg("operator%=(ex,ex)",LOGLEVEL_OPERATOR);
121         return (lh=lh%rh);
122 }
123
124
125 // binary arithmetic assignment operators with numeric
126
127 const numeric & operator+=(numeric & lh, const numeric & rh)
128 {
129         debugmsg("operator+=(numeric,numeric)",LOGLEVEL_OPERATOR);
130         return (lh=lh.add(rh));
131 }
132
133 const numeric & operator-=(numeric & lh, const numeric & rh)
134 {
135         debugmsg("operator-=(numeric,numeric)",LOGLEVEL_OPERATOR);
136         return (lh=lh.sub(rh));
137 }
138
139 const numeric & operator*=(numeric & lh, const numeric & rh)
140 {
141         debugmsg("operator*=(numeric,numeric)",LOGLEVEL_OPERATOR);
142         return (lh=lh.mul(rh));
143 }
144
145 const numeric & operator/=(numeric & lh, const numeric & rh)
146 {
147         debugmsg("operator/=(numeric,numeric)",LOGLEVEL_OPERATOR);
148         return (lh=lh.div(rh));
149 }
150
151 // unary operators
152
153 ex operator+(const ex & lh)
154 {
155         debugmsg("operator+(ex)",LOGLEVEL_OPERATOR);
156         return lh;
157 }
158
159 ex operator-(const ex & lh)
160 {
161         debugmsg("operator-(ex)",LOGLEVEL_OPERATOR);
162         return lh.exmul(_ex_1());
163 }
164
165 numeric operator+(const numeric & lh)
166 {
167         debugmsg("operator+(numeric)",LOGLEVEL_OPERATOR);
168         return lh;
169 }
170
171 numeric operator-(const numeric & lh)
172 {
173         debugmsg("operator-(numeric)",LOGLEVEL_OPERATOR);
174         return _num_1().mul(lh);
175 }
176
177 /** Numeric prefix increment.  Adds 1 and returns incremented number. */
178 numeric& operator++(numeric & rh)
179 {
180         debugmsg("operator++(numeric)",LOGLEVEL_OPERATOR);
181         rh = rh.add(_num1());
182         return rh;
183 }
184
185 /** Numeric prefix decrement.  Subtracts 1 and returns decremented number. */
186 numeric& operator--(numeric & rh)
187 {
188         debugmsg("operator--(numeric)",LOGLEVEL_OPERATOR);
189         rh = rh.add(_num_1());
190         return rh;
191 }
192
193 /** Numeric postfix increment.  Returns the number and leaves the original
194  *  incremented by 1. */
195 numeric operator++(numeric & lh, int)
196 {
197         debugmsg("operator++(numeric,int)",LOGLEVEL_OPERATOR);
198         numeric tmp(lh);
199         lh = lh.add(_num1());
200         return tmp;
201 }
202
203 /** Numeric Postfix decrement.  Returns the number and leaves the original
204  *  decremented by 1. */
205 numeric operator--(numeric & lh, int)
206 {
207         debugmsg("operator--(numeric,int)",LOGLEVEL_OPERATOR);
208         numeric tmp(lh);
209         lh = lh.add(_num_1());
210         return tmp;
211 }
212
213 // binary relational operators ex with ex
214
215 relational operator==(const ex & lh, const ex & rh)
216 {
217         debugmsg("operator==(ex,ex)",LOGLEVEL_OPERATOR);
218         return relational(lh,rh,relational::equal);
219 }
220
221 relational operator!=(const ex & lh, const ex & rh)
222 {
223         debugmsg("operator!=(ex,ex)",LOGLEVEL_OPERATOR);
224         return relational(lh,rh,relational::not_equal);
225 }
226
227 relational operator<(const ex & lh, const ex & rh)
228 {
229         debugmsg("operator<(ex,ex)",LOGLEVEL_OPERATOR);
230         return relational(lh,rh,relational::less);
231 }
232
233 relational operator<=(const ex & lh, const ex & rh)
234 {
235         debugmsg("operator<=(ex,ex)",LOGLEVEL_OPERATOR);
236         return relational(lh,rh,relational::less_or_equal);
237 }
238
239 relational operator>(const ex & lh, const ex & rh)
240 {
241         debugmsg("operator>(ex,ex)",LOGLEVEL_OPERATOR);
242         return relational(lh,rh,relational::greater);
243 }
244
245 relational operator>=(const ex & lh, const ex & rh)
246 {
247         debugmsg("operator>=(ex,ex)",LOGLEVEL_OPERATOR);
248         return relational(lh,rh,relational::greater_or_equal);
249 }
250
251 // input/output stream operators
252
253 std::ostream & operator<<(std::ostream & os, const ex & e)
254 {
255         e.print(os);
256         return os;
257 }
258
259 std::istream & operator>>(std::istream & is, ex & e)
260 {
261         throw (std::logic_error("expression input from streams not implemented"));
262 }
263
264 } // namespace GiNaC