Added internal code for multivariate factorization.
[ginac.git] / check / exam_hashmap.cpp
1 /** @file exam_hashmap.cpp
2  *
3  *  Regression tests for the exhashmap<> container. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2008 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 #include <iostream>
24 #include "ginac.h"
25 using namespace std;
26 using namespace GiNaC;
27
28 unsigned exam_hashmap()
29 {
30         unsigned result = 0;
31         unsigned N = 100;
32
33         cout << "examining hash maps" << flush;
34
35         // Create empty container
36         exhashmap<unsigned> M1;
37         if (M1.size() != 0) {
38                 clog << "Newly constructed container has size() != 0" << endl;
39                 ++result;
40         }
41         if (!M1.empty()) {
42                 clog << "Newly constructed container is not empty" << endl;
43                 ++result;
44         }
45
46         cout << '.' << flush;
47
48         // Insert elements
49         for (unsigned i = 0; i < N; ++i)
50                 M1.insert(make_pair(i, i));
51
52         if (M1.size() != N) {
53                 clog << "After " << N << " insertions, size() returns " << M1.size() << " instead of " << N << endl;
54                 ++result;
55         }
56
57         for (unsigned i = 0; i < N; ++i) {
58                 if (M1[i] != i) {
59                         clog << "Lookup of key " << i << " in M1 didn't return correct value" << endl;
60                         ++result;
61                         break;
62                 }
63         }
64
65         if (M1.size() != N) {
66                 clog << "After " << N << " lookups, size() returns " << M1.size() << " instead of " << N << endl;
67                 ++result;
68         }
69
70         cout << '.' << flush;
71
72         // Test constructor from two iterators and operator==
73         exhashmap<unsigned> M2(M1.begin(), M1.end());
74         if (M2.size() != M1.size()) {
75                 clog << "Constructor from two iterators: size of destination container (" << M2.size() << ") not equal to size of source (" << M1.size() << ")" << endl;
76                 ++result;
77         }
78
79         for (unsigned i = 0; i < N; ++i) {
80                 if (M2[i] != i) {
81                         clog << "Lookup of key " << i << " in M2 didn't return correct value" << endl;
82                         ++result;
83                         break;
84                 }
85         }
86
87         if (M2 != M1) {
88                 clog << "Copied container not equal to source" << endl;
89                 ++result;
90         }
91
92         cout << '.' << flush;
93
94         // Test assignment operator
95         exhashmap<unsigned> M3;
96         M3 = M1;
97         if (M3.size() != N) {
98                 clog << "Assignment operator: size of assigned container not equal to size of original" << endl;
99                 ++result;
100         }
101
102         for (unsigned i = 0; i < N; ++i) {
103                 if (M3[i] != i) {
104                         clog << "Lookup of key " << i << " in M3 didn't return correct value" << endl;
105                         ++result;
106                         break;
107                 }
108         }
109
110         cout << '.' << flush;
111
112         // Test insert(it, it)
113         exhashmap<unsigned> M4;
114         M4.insert(M1.begin(), M1.end());
115
116         if (M4.size() != M1.size()) {
117                 clog << "insert(it, it): size of destination container not equal to size of source" << endl;
118                 ++result;
119         }
120
121         for (unsigned i = 0; i < N; ++i) {
122                 if (M4[i] != i) {
123                         clog << "Lookup of key " << i << " in M4 didn't return correct value" << endl;
124                         ++result;
125                         break;
126                 }
127         }
128
129         cout << '.' << flush;
130
131         // Test insert()/find()
132         symbol x("x"), y("y");
133         exhashmap<unsigned> M5;
134         M5.insert(make_pair(x-2, 1));
135         M5.insert(make_pair(sin(x+y), 2));
136         M5.insert(make_pair(Pi, 3));
137         M5.insert(make_pair(0, 4));
138         M5.insert(make_pair(4*pow(x, y), 5));
139         if (M5.size() != 5) {
140                 clog << "After 5 insertions, size() returns " << M5.size() << " instead of 5" << endl;
141                 ++result;
142         }
143
144         exhashmap<unsigned>::const_iterator cit = M5.find(sin(x+y));
145         if (cit == M5.end()) {
146                 clog << "Lookup of sin(x+y) didn't find anything" << endl;
147                 ++result;
148         }
149         if (!cit->first.is_equal(sin(x+y))) {
150                 clog << "Lookup of sin(x+y) returned an incorrect iterator" << endl;
151                 ++result;
152         }
153         if (cit->second != 2) {
154                 clog << "Lookup of sin(x+y) returned wrong value" << endl;
155                 ++result;
156         }
157
158         cout << '.' << flush;
159
160         // Test re-inserting insert()
161         pair<exhashmap<unsigned>::iterator, bool> pit = M5.insert(make_pair(sin(x+y), 42));
162         if (pit.second) {
163                 clog << "Reinsertion of sin(x+y) inserted a new value" << endl;
164                 ++result;
165         }
166         if (!pit.first->first.is_equal(sin(x+y))) {
167                 clog << "Reinsertion of sin(x+y) returned an incorrect iterator" << endl;
168                 ++result;
169         }
170         if (pit.first->second != 2) {
171                 clog << "Reinsertion of sin(x+y) changed the value" << endl;
172                 ++result;
173         }
174
175         cout << '.' << flush;
176
177         // Test operator[]
178         unsigned v = M5[sin(x+y)];
179         if (M5.size() != 5) {
180                 clog << "operator[] with an existing key changed the container size" << endl;
181                 ++result;
182         }
183         if (v != 2) {
184                 clog << "operator[] with an existing key returned the wrong value" << endl;
185                 ++result;
186         }
187
188         v = M5[y+1];
189         if (M5.size() != 6) {
190                 clog << "operator[] with a new key didn't insert a new value" << endl;
191                 ++result;
192         }
193         if (v != 0) {
194                 clog << "operator[] with a new key returned the wrong value" << endl;
195                 ++result;
196         }
197
198         cout << '.' << flush;
199
200         // Test erase()
201         exhashmap<unsigned>::iterator it = M5.find(y+1);
202         if (it == M5.end()) {
203                 clog << "Key y+1 wasn't found" << endl;
204                 ++result;
205         }
206         if (!it->first.is_equal(y+1)) {
207                 clog << "find() returned an incorrect iterator" << endl;
208                 ++result;
209         }
210         if (it->second != 0) {
211                 clog << "find() returned an incorrect value" << endl;
212                 +result;
213         }
214
215         M5.erase(it);
216         if (M5.size() != 5) {
217                 clog << "erase(it) didn't reduce the size of the container" << endl;
218                 ++result;
219         }
220
221         it = M5.find(y+1);
222         if (it != M5.end()) {
223                 clog << "Key was still found after erase()" << endl;
224                 ++result;
225         }
226
227         exhashmap<unsigned>::size_type n = M5.erase(Pi);
228         if (n != 1) {
229                 clog << "erase(Pi) returned " << n << " instead of 1" << endl;
230                 ++result;
231         }
232         if (M5.size() != 4) {
233                 clog << "erase(Pi) didn't reduce the size of the container" << endl;
234                 ++result;
235         }
236
237         n = M5.erase(42);
238         if (n != 0) {
239                 clog << "erase(42) returned " << n << " instead of 0" << endl;
240                 ++result;
241         }
242         if (M5.size() != 4) {
243                 clog << "erase(42) reduced the size of the container" << endl;
244                 ++result;
245         }
246
247         cout << '.' << flush;
248
249         // Test swap()
250         exhashmap<unsigned> M6;
251         M6.swap(M1);
252         if (M6.size() != N) {
253                 clog << "After swap, size() returns " << M6.size() << " instead of " << N << endl;
254                 ++result;
255         }
256         if (M1.size() != 0) {
257                 clog << "After swap with empty container, size() returns " << M1.size() << " instead of 0" << endl;
258                 ++result;
259         }
260
261         cout << '.' << flush;
262
263         // Test clear()
264         M2.clear();
265         if (M2.size() != 0) {
266                 clog << "Size of cleared container is " << M5.size() << " instead of 0" << endl;
267                 ++result;
268         }
269
270         cout << '.' << flush;
271
272         // Test count()
273         n = M5.count(Pi);
274         if (n != 0) {
275                 clog << "count(Pi) returns " << n << " instead of 0" << endl;
276                 ++result;
277         }
278
279         n = M5.count(4*pow(x, y));
280         if (n != 1) {
281                 clog << "count(4*x^y) returns " << n << " instead of 1" << endl;
282                 ++result;
283         }
284         cout << '.' << flush;
285
286         return result;
287 }
288
289 int main(int argc, char** argv)
290 {
291         return exam_hashmap();
292 }