- See if __GNUC__ < 2.97 before using std::vector<..,malloc_alloc>. Sorry,
[ginac.git] / ginac / expair.h
1 /** @file expair.h
2  *
3  *  Definition of expression pairs (building blocks of expairseq). */
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 #ifndef __GINAC_EXPAIR_H__
24 #define __GINAC_EXPAIR_H__
25
26 #include "ex.h"
27 #include "numeric.h"
28
29 #ifndef NO_NAMESPACE_GINAC
30 namespace GiNaC {
31 #endif // ndef NO_NAMESPACE_GINAC
32
33 /** A pair of expressions.
34  *  This similar to, but slightly extended STL's pair<> but we need to account
35  *  for methods like .compare() */
36 class expair
37 {
38 public:
39         expair() {}
40         ~expair() {}
41
42         expair(const expair & other) : rest(other.rest), coeff(other.coeff)
43         {
44                 GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
45         }
46
47         const expair & operator=(const expair & other)
48         {
49                 if (this != &other) {
50                         rest=other.rest;
51                         coeff=other.coeff;
52                 }
53                 return *this;
54         }
55
56         expair(const ex & r, const ex & c) : rest(r), coeff(c)
57         {
58                 GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
59         }
60         
61         bool is_numeric_with_coeff_1(void) const
62         {
63                 GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
64                 return is_ex_exactly_of_type(rest,numeric)
65                     && (coeff.is_equal(ex(1)));
66         }
67
68         bool is_equal(const expair & other) const
69         {
70                 return (rest.is_equal(other.rest) && coeff.is_equal(other.coeff));
71         }
72
73         bool is_less(const expair & other) const 
74         {
75                 return (rest.compare(other.rest)<0)
76                     || (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
77         }
78
79         int compare(const expair & other) const
80         {
81                 int cmpval=rest.compare(other.rest);
82                 if (cmpval!=0) return cmpval;
83                 cmpval=coeff.compare(other.coeff);
84                 return cmpval;
85         }
86
87         bool is_less_old2(const expair & other) const 
88         {
89                 /*
90                 bool this_numeric_with_coeff_1=is_numeric_with_coeff_1();
91                 bool other_numeric_with_coeff_1=other.is_numeric_with_coeff_1();
92                 if (this_numeric_with_coeff_1) {
93                         if (other_numeric_with_coeff_1) {
94                                 // both have coeff 1: compare rests
95                                 return rest.compare(other.rest)<0;
96                         }
97                         // only this has coeff 1: >
98                         return false;
99                 } else if (other_numeric_with_coeff_1) {
100                         // only other has coeff 1: <
101                         return true;
102                 }
103                 return (rest.compare(other.rest)<0)
104                     || (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
105                 */
106                 if (is_ex_exactly_of_type(rest,numeric) &&
107                         is_ex_exactly_of_type(other.rest,numeric)) {
108                         if (coeff.is_equal(ex(1))) {
109                                 if ((other.coeff).is_equal(ex(1))) {
110                                         // both have coeff 1: compare rests
111                                         return rest.compare(other.rest)<0;
112                                 }
113                                 // only this has coeff 1: >
114                                 return false;
115                         } else if ((other.coeff).is_equal(ex(1))) {
116                                 // only other has coeff 1: <
117                                 return true;
118                         }
119                         // neither has coeff 1: usual compare        
120                 }
121                 return (rest.compare(other.rest)<0)
122                     || (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
123         }
124
125         int compare_old2(const expair & other) const
126         {
127                 if (is_ex_exactly_of_type(rest,numeric) &&
128                         is_ex_exactly_of_type(other.rest,numeric)) {
129                         if ((coeff).is_equal(ex(1))) {
130                                 if ((other.coeff).is_equal(ex(1))) {
131                                         // both have coeff 1: compare rests
132                                         return rest.compare(other.rest);
133                                 }
134                                 // only this has coeff 1: >
135                                 return 1;
136                         } else if ((other.coeff).is_equal(ex(1))) {
137                                 // only other has coeff 1: <
138                                 return -1;
139                         }
140                         // neither has coeff 1: usual compare        
141                 }
142                 /*
143                 bool this_numeric_with_coeff_1=is_numeric_with_coeff_1();
144                 bool other_numeric_with_coeff_1=other.is_numeric_with_coeff_1();
145                 if (this_numeric_with_coeff_1) {
146                         if (other_numeric_with_coeff_1) {
147                                 // both have coeff 1: compare rests
148                                 return rest.compare(other.rest);
149                         }
150                         // only this has coeff 1: >
151                         return 1;
152                 } else if (other_numeric_with_coeff_1) {
153                         // only other has coeff 1: <
154                         return -1;
155                         // neither has coeff 1: usual compare        
156                 }
157                 */
158                 int cmpval=rest.compare(other.rest);
159                 if (cmpval!=0) return cmpval;
160                 return coeff.compare(other.coeff);
161         }
162
163         bool is_less_old(const expair & other) const 
164         {
165                 return (rest.compare(other.rest)<0)
166                     || (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
167         }
168         int compare_old(const expair & other) const
169         {
170                 int cmpval=rest.compare(other.rest);
171                 if (cmpval!=0) return cmpval;
172                 cmpval=coeff.compare(other.coeff);
173                 return cmpval;
174         }
175
176         void printraw(std::ostream & os) const
177         {
178                 os << "expair(";
179                 rest.printraw(os);
180                 os << ",";
181                 coeff.printraw(os);
182                 os << ")";
183         }
184
185         ex rest;
186         ex coeff;
187 };
188
189 class expair_is_less
190 {
191 public:
192         bool operator()(const expair & lh, const expair & rh) const
193         {
194                 return lh.is_less(rh);
195         }
196 };
197
198 class expair_is_less_old
199 {
200 public:
201         bool operator()(const expair & lh, const expair & rh) const
202         {
203                 return lh.is_less_old(rh);
204         }
205 };
206
207 #ifndef NO_NAMESPACE_GINAC
208 } // namespace GiNaC
209 #endif // ndef NO_NAMESPACE_GINAC
210
211 #endif // ndef __GINAC_EXPAIR_H__