- See if __GNUC__ < 2.97 before using std::vector<..,malloc_alloc>. Sorry,
[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 <iostream>
24 #include <stdexcept>
25
26 #include "operators.h"
27 #include "basic.h"
28 #include "ex.h"
29 #include "numeric.h"
30 #include "power.h"
31 #include "relational.h"
32 #include "debugmsg.h"
33 #include "utils.h"
34
35 #ifndef NO_NAMESPACE_GINAC
36 namespace GiNaC {
37 #endif // ndef NO_NAMESPACE_GINAC
38
39 // binary arithmetic operators ex with ex
40
41 ex operator+(const ex & lh, const ex & rh)
42 {
43         debugmsg("operator+(ex,ex)",LOGLEVEL_OPERATOR);
44         return lh.exadd(rh);
45 }
46
47 ex operator-(const ex & lh, const ex & rh)
48 {
49         debugmsg("operator-(ex,ex)",LOGLEVEL_OPERATOR);
50         return lh.exadd(rh.exmul(_ex_1()));
51 }
52
53 ex operator*(const ex & lh, const ex & rh)
54 {
55         debugmsg("operator*(ex,ex)",LOGLEVEL_OPERATOR);
56         return lh.exmul(rh);
57 }
58
59 ex operator/(const ex & lh, const ex & rh)
60 {
61         debugmsg("operator/(ex,ex)",LOGLEVEL_OPERATOR);
62         return lh.exmul(power(rh,_ex_1()));
63 }
64
65 ex operator%(const ex & lh, const ex & rh)
66 {
67         debugmsg("operator%(ex,ex)",LOGLEVEL_OPERATOR);
68         return lh.exncmul(rh);
69 }
70
71
72 // binary arithmetic operators numeric with numeric
73
74 numeric operator+(const numeric & lh, const numeric & rh)
75 {
76         debugmsg("operator+(numeric,numeric)",LOGLEVEL_OPERATOR);
77         return lh.add(rh);
78 }
79
80 numeric operator-(const numeric & lh, const numeric & rh)
81 {
82         debugmsg("operator-(numeric,numeric)",LOGLEVEL_OPERATOR);
83         return lh.sub(rh);
84 }
85
86 numeric operator*(const numeric & lh, const numeric & rh)
87 {
88         debugmsg("operator*(numeric,numeric)",LOGLEVEL_OPERATOR);
89         return lh.mul(rh);
90 }
91
92 numeric operator/(const numeric & lh, const numeric & rh)
93 {
94         debugmsg("operator/(numeric,ex)",LOGLEVEL_OPERATOR);
95         return lh.div(rh);
96 }
97
98
99 // binary arithmetic assignment operators with ex
100
101 const ex & operator+=(ex & lh, const ex & rh)
102 {
103         debugmsg("operator+=(ex,ex)",LOGLEVEL_OPERATOR);
104         return (lh=lh+rh);
105 }
106
107 const ex & operator-=(ex & lh, const ex & rh)
108 {
109         debugmsg("operator-=(ex,ex)",LOGLEVEL_OPERATOR);
110         return (lh=lh-rh);
111 }
112
113 const ex & operator*=(ex & lh, const ex & rh)
114 {
115         debugmsg("operator*=(ex,ex)",LOGLEVEL_OPERATOR);
116         return (lh=lh*rh);
117 }
118
119 const ex & operator/=(ex & lh, const ex & rh)
120 {
121         debugmsg("operator/=(ex,ex)",LOGLEVEL_OPERATOR);
122         return (lh=lh/rh);
123 }
124
125 const ex & operator%=(ex & lh, const ex & rh)
126 {
127         debugmsg("operator%=(ex,ex)",LOGLEVEL_OPERATOR);
128         return (lh=lh%rh);
129 }
130
131
132 // binary arithmetic assignment operators with numeric
133
134 const numeric & operator+=(numeric & lh, const numeric & rh)
135 {
136         debugmsg("operator+=(numeric,numeric)",LOGLEVEL_OPERATOR);
137         return (lh=lh.add(rh));
138 }
139
140 const numeric & operator-=(numeric & lh, const numeric & rh)
141 {
142         debugmsg("operator-=(numeric,numeric)",LOGLEVEL_OPERATOR);
143         return (lh=lh.sub(rh));
144 }
145
146 const numeric & operator*=(numeric & lh, const numeric & rh)
147 {
148         debugmsg("operator*=(numeric,numeric)",LOGLEVEL_OPERATOR);
149         return (lh=lh.mul(rh));
150 }
151
152 const numeric & operator/=(numeric & lh, const numeric & rh)
153 {
154         debugmsg("operator/=(numeric,numeric)",LOGLEVEL_OPERATOR);
155         return (lh=lh.div(rh));
156 }
157
158 // unary operators
159
160 ex operator+(const ex & lh)
161 {
162         debugmsg("operator+(ex)",LOGLEVEL_OPERATOR);
163         return lh;
164 }
165
166 ex operator-(const ex & lh)
167 {
168         debugmsg("operator-(ex)",LOGLEVEL_OPERATOR);
169         return lh.exmul(_ex_1());
170 }
171
172 numeric operator+(const numeric & lh)
173 {
174         debugmsg("operator+(numeric)",LOGLEVEL_OPERATOR);
175         return lh;
176 }
177
178 numeric operator-(const numeric & lh)
179 {
180         debugmsg("operator-(numeric)",LOGLEVEL_OPERATOR);
181         return _num_1()*lh;
182 }
183
184 /** Numeric prefix increment.  Adds 1 and returns incremented number. */
185 numeric& operator++(numeric & rh)
186 {
187         debugmsg("operator++(numeric)",LOGLEVEL_OPERATOR);
188         rh = rh+_num1();
189         return rh;
190 }
191
192 /** Numeric prefix decrement.  Subtracts 1 and returns decremented number. */
193 numeric& operator--(numeric & rh)
194 {
195         debugmsg("operator--(numeric)",LOGLEVEL_OPERATOR);
196         rh = rh-_num1();
197         return rh;
198 }
199
200 /** Numeric postfix increment.  Returns the number and leaves the original
201  *  incremented by 1. */
202 numeric operator++(numeric & lh, int)
203 {
204         debugmsg("operator++(numeric,int)",LOGLEVEL_OPERATOR);
205         numeric tmp = lh;
206         lh = lh+_num1();
207         return tmp;
208 }
209
210 /** Numeric Postfix decrement.  Returns the number and leaves the original
211  *  decremented by 1. */
212 numeric operator--(numeric & lh, int)
213 {
214         debugmsg("operator--(numeric,int)",LOGLEVEL_OPERATOR);
215         numeric tmp = lh;
216         lh = lh-_num1();
217         return tmp;
218 }
219
220 // binary relational operators ex with ex
221
222 relational operator==(const ex & lh, const ex & rh)
223 {
224         debugmsg("operator==(ex,ex)",LOGLEVEL_OPERATOR);
225         return relational(lh,rh,relational::equal);
226 }
227
228 relational operator!=(const ex & lh, const ex & rh)
229 {
230         debugmsg("operator!=(ex,ex)",LOGLEVEL_OPERATOR);
231         return relational(lh,rh,relational::not_equal);
232 }
233
234 relational operator<(const ex & lh, const ex & rh)
235 {
236         debugmsg("operator<(ex,ex)",LOGLEVEL_OPERATOR);
237         return relational(lh,rh,relational::less);
238 }
239
240 relational operator<=(const ex & lh, const ex & rh)
241 {
242         debugmsg("operator<=(ex,ex)",LOGLEVEL_OPERATOR);
243         return relational(lh,rh,relational::less_or_equal);
244 }
245
246 relational operator>(const ex & lh, const ex & rh)
247 {
248         debugmsg("operator>(ex,ex)",LOGLEVEL_OPERATOR);
249         return relational(lh,rh,relational::greater);
250 }
251
252 relational operator>=(const ex & lh, const ex & rh)
253 {
254         debugmsg("operator>=(ex,ex)",LOGLEVEL_OPERATOR);
255         return relational(lh,rh,relational::greater_or_equal);
256 }
257
258 // input/output stream operators
259
260 std::ostream & operator<<(std::ostream & os, const ex & e)
261 {
262         e.print(os);
263         return os;
264 }
265
266 std::istream & operator>>(std::istream & is, ex & e)
267 {
268         throw (std::logic_error("expression input from streams not implemented"));
269 }
270
271 #ifndef NO_NAMESPACE_GINAC
272 } // namespace GiNaC
273 #endif // ndef NO_NAMESPACE_GINAC