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