- modified GiNaC headers to Alexander's liking
[ginac.git] / ginac / expair.h
1 /** @file expair.h
2  *
3  *  GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #ifndef __GINAC_EXPAIR_H__
21 #define __GINAC_EXPAIR_H__
22
23 #include <ginac/ex.h>
24 #include <ginac/numeric.h>
25
26 /** A pair of expressions.
27  *  This similar to, but slightly extended STL's pair<> but we need to account
28  *  for methods like .compare() */
29 class expair
30 {
31 public:
32     expair() {}
33     ~expair() {}
34     expair(expair const & other) : rest(other.rest), coeff(other.coeff)
35     {
36         ASSERT(is_ex_exactly_of_type(coeff,numeric));
37     }
38     expair const & operator=(expair const & other)
39     {
40         if (this != &other) {
41             rest=other.rest;
42             coeff=other.coeff;
43         }
44         return *this;
45     }
46     expair(ex const & r, ex const & c) : rest(r), coeff(c)
47     {
48         ASSERT(is_ex_exactly_of_type(coeff,numeric));
49     }
50     
51     bool is_numeric_with_coeff_1(void) const
52     {
53         ASSERT(is_ex_exactly_of_type(coeff,numeric));
54         return is_ex_exactly_of_type(rest,numeric) &&
55                (ex_to_numeric(coeff).compare(numONE())==0);
56     }
57
58     bool is_equal(expair const & other) const
59     {
60         return (rest.is_equal(other.rest) && coeff.is_equal(other.coeff));
61     }
62     bool is_less(expair const & other) const 
63     {
64         return (rest.compare(other.rest)<0) ||
65                (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
66     }
67     int compare(expair const & other) const
68     {
69         int cmpval=rest.compare(other.rest);
70         if (cmpval!=0) return cmpval;
71         cmpval=coeff.compare(other.coeff);
72         return cmpval;
73     }
74
75     bool is_less_old2(expair const & other) const 
76     {
77         /*
78         bool this_numeric_with_coeff_1=is_numeric_with_coeff_1();
79         bool other_numeric_with_coeff_1=other.is_numeric_with_coeff_1();
80         if (this_numeric_with_coeff_1) {
81             if (other_numeric_with_coeff_1) {
82                 // both have coeff 1: compare rests
83                 return rest.compare(other.rest)<0;
84             }
85             // only this has coeff 1: >
86             return false;
87         } else if (other_numeric_with_coeff_1) {
88             // only other has coeff 1: <
89             return true;
90         }
91         return (rest.compare(other.rest)<0) ||
92                (!(other.rest.compare(rest)<0) &&
93                  (coeff.compare(other.coeff)<0));
94         */
95         if (is_ex_exactly_of_type(rest,numeric) &&
96             is_ex_exactly_of_type(other.rest,numeric)) {
97             if (ex_to_numeric(coeff).compare(numONE())==0) {
98                 if (ex_to_numeric(other.coeff).compare(numONE())==0) {
99                     // both have coeff 1: compare rests
100                     return rest.compare(other.rest)<0;
101                 }
102                 // only this has coeff 1: >
103                 return false;
104             } else if (ex_to_numeric(other.coeff).compare(numONE())==0) {
105                 // only other has coeff 1: <
106                 return true;
107             }
108             // neither has coeff 1: usual compare        
109         }
110         return (rest.compare(other.rest)<0) ||
111                (!(other.rest.compare(rest)<0) &&
112                  (coeff.compare(other.coeff)<0));
113     }
114     int compare_old2(expair const & other) const
115     {
116         if (is_ex_exactly_of_type(rest,numeric) &&
117             is_ex_exactly_of_type(other.rest,numeric)) {
118             if (ex_to_numeric(coeff).compare(numONE())==0) {
119                 if (ex_to_numeric(other.coeff).compare(numONE())==0) {
120                     // both have coeff 1: compare rests
121                     return rest.compare(other.rest);
122                 }
123                 // only this has coeff 1: >
124                 return 1;
125             } else if (ex_to_numeric(other.coeff).compare(numONE())==0) {
126                 // only other has coeff 1: <
127                 return -1;
128             }
129             // neither has coeff 1: usual compare        
130         }
131         /*
132         bool this_numeric_with_coeff_1=is_numeric_with_coeff_1();
133         bool other_numeric_with_coeff_1=other.is_numeric_with_coeff_1();
134         if (this_numeric_with_coeff_1) {
135             if (other_numeric_with_coeff_1) {
136                 // both have coeff 1: compare rests
137                 return rest.compare(other.rest);
138             }
139             // only this has coeff 1: >
140             return 1;
141         } else if (other_numeric_with_coeff_1) {
142             // only other has coeff 1: <
143             return -1;
144             // neither has coeff 1: usual compare        
145         }
146         */
147         int cmpval=rest.compare(other.rest);
148         if (cmpval!=0) return cmpval;
149         return coeff.compare(other.coeff);
150     }
151     bool is_less_old(expair const & other) const 
152     {
153         return (rest.compare(other.rest)<0) ||
154                (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
155     }
156     int compare_old(expair const & other) const
157     {
158         int cmpval=rest.compare(other.rest);
159         if (cmpval!=0) return cmpval;
160         cmpval=coeff.compare(other.coeff);
161         return cmpval;
162     }
163
164     void printraw(ostream & os) const
165     {
166         os << "expair(";
167         rest.printraw(os);
168         os << ",";
169         coeff.printraw(os);
170         os << ")";
171     }
172
173     ex rest;
174     ex coeff;
175 };
176
177 class expair_is_less
178 {
179 public:
180     bool operator()(expair const & lh, expair const & rh) const
181     {
182         return lh.is_less(rh);
183     }
184 };
185
186 class expair_is_less_old
187 {
188 public:
189     bool operator()(expair const & lh, expair const & rh) const
190     {
191         return lh.is_less_old(rh);
192     }
193 };
194
195 #endif // ndef __GINAC_EXPAIR_H__