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