source: trunk/test/segment.cc @ 4027

Last change on this file since 4027 was 4027, checked in by Peter, 2 years ago

refs #968; fix implementation of SegmentSet::insert_merge and add some tests to avoid similar regressions.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 13.7 KB
Line 
1// $Id: segment.cc 4027 2021-01-17 10:46:38Z peter $
2
3/*
4  Copyright (C) 2010, 2011, 2012, 2014, 2015, 2016, 2017 Peter Johansson
5
6  This file is part of the yat library, http://dev.thep.lu.se/yat
7
8  The yat library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 3 of the
11  License, or (at your option) any later version.
12
13  The yat library 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 GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with yat. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include <config.h>
23
24#include "Suite.h"
25
26#include "yat/utility/Segment.h"
27#include "yat/utility/SegmentMap.h"
28#include "yat/utility/SegmentSet.h"
29
30using namespace theplu::yat;
31using namespace utility;
32void test_compare(test::Suite& suite);
33void test_count(test::Suite&);
34void test_erase(test::Suite&);
35void test_includes(test::Suite&);
36void test_insert(test::Suite&);
37void test_insert_merge(test::Suite&);
38void test_make_segment(test::Suite&);
39void test_overlap(test::Suite&);
40void test_segment(test::Suite& suite);
41void test_operator(test::Suite& suite);
42void test_segment_map(test::Suite& suite);
43void test_segment_set(test::Suite& suite);
44void test_set_bound(test::Suite&);
45void test_union(test::Suite&);
46
47template<typename T>
48void avoid_pedantic_warning(T) {}
49
50int main(int argc, char* argv[])
51{
52  test::Suite suite(argc, argv);
53
54  test_compare(suite);
55  test_count(suite);
56  test_erase(suite);
57  test_includes(suite);
58  test_insert(suite);
59  test_insert_merge(suite);
60  test_make_segment(suite);
61  test_overlap(suite);
62  test_segment(suite);
63  test_set_bound(suite);
64  test_union(suite);
65
66  test_segment_map(suite);
67  test_segment_set(suite);
68
69  return suite.return_value();
70}
71
72
73void test_compare_(test::Suite& suite, double lhs_begin, double lhs_end, 
74                   double rhs_begin, double rhs_end, int expected)
75{
76  int result = compare_3way(Segment<double>(lhs_begin,lhs_end), 
77                            Segment<double>(rhs_begin,rhs_end));
78  if (result!=expected) {
79    suite.add(false);
80    suite.err() << "error:"
81                << "[" << lhs_begin << ", " << lhs_end << ") vs "
82                << "[" << rhs_begin << ", " << rhs_end << ")\n"
83                << "result: " << result << "\n"
84                << "expected: " << expected << "\n"
85                << "\n";
86  }
87
88  compare_3way(lhs_begin, Segment<double>(rhs_begin,rhs_end));
89  compare_3way(Segment<double>(rhs_begin,rhs_end), lhs_begin);
90}
91
92void test_compare(test::Suite& suite, double lhs_begin, double lhs_end, 
93                  double rhs_begin, double rhs_end, int expected)
94{
95  test_compare_(suite, lhs_begin, lhs_end, rhs_begin, rhs_end, expected);
96  // test symmetry
97  test_compare_(suite, rhs_begin, rhs_end, lhs_begin, lhs_end, -expected);
98}
99
100void test_compare(test::Suite& suite)
101{
102  test_compare(suite, 0, 10, 20, 30, -1);
103  test_compare(suite, 0, 10, 10, 30, -1);
104  test_compare(suite, 0, 10, 5, 30, 0);
105  test_compare(suite, 0, 10, -5, 5, 0);
106  test_compare(suite, 0, 10, -5, 0, 1);
107  test_compare(suite, 0, 10, -5, -1, 1);
108  // zero sized
109  test_compare(suite, 0, 0, 20, 30, -1);
110  test_compare(suite, 0, 0, 0, 1, -1);
111  test_compare(suite, 0, 0, -5, 5, 0);
112  test_compare(suite, 0, 0, -5, 0, 1);
113  test_compare(suite, 0, 0, -5, -1, 1);
114
115  // zero sized on both sides
116  test_compare(suite, 0, 0, 1, 1, -1);
117  test_compare(suite, 0, 0, 0, 0, 0);
118  test_compare(suite, 0, 0, -1, -1, 1);
119}
120
121
122void test_erase(test::Suite& suite)
123{
124  suite.out() << "test_erase\n";
125  suite.out() << "  SegmentSet\n";
126  SegmentSet<double> set;
127  set.insert(Segment<double>(0,2));
128  set.insert(Segment<double>(10,20));
129  set.insert(Segment<double>(30,50));
130  SegmentSet<double>::iterator iter = set.find(15);
131  set.erase(iter);
132  if (!suite.add(set.size()==2))
133    suite.err() << "size: " << set.size() << " expected 2\n";
134  set.erase(set.begin(), set.end());
135  if (!suite.add(set.size()==0))
136    suite.err() << "size: " << set.size() << " expected 0\n";
137  suite.out() << "  SegmentMap\n";
138  typedef SegmentMap<double, std::string> Map;
139  Map map;
140  Map::key_type s(0,2);
141  map.insert(Map::value_type(s, "aha"));
142  map.erase(map.begin());
143  map.erase(map.begin(), map.end());
144}
145
146
147void test_insert(test::Suite& suite)
148{
149  Segment<double> segment;
150  Segment<double> segment2(0,2);
151
152  SegmentSet<double> set;
153  if (set.size()!=0) {
154    suite.add(false);
155    suite.err() << "expected size 0\n";
156  }
157  set.insert(segment2);
158  if (set.size()!=1) {
159    suite.add(false);
160    suite.err() << "expected size 1\n";
161  }
162  set.insert(segment2);
163  if (set.size()!=1) {
164    suite.add(false);
165    suite.err() << "expected size 1\n";
166  }
167  set.insert(Segment<double>(1,3));
168  if (set.size()!=1) {
169    suite.add(false);
170    suite.err() << "expected size 1\n";
171  }
172  else if (set.begin()->begin()!=0.0 || set.begin()->end()!=2.0) {
173    suite.add(false);
174    suite.err() << "error: expected segment to be [0, 2)\n"
175                << "found: [" << set.begin()->begin() 
176                << ", " << set.begin()->end() << ")\n";
177  }
178  if (!suite.add(set.find(0)!=set.end()))
179    suite.err() << "error: set.find(0): expected not end()\n";
180}
181
182void test_count(test::Suite& suite)
183{
184  SegmentSet<double> set;
185  set.insert(Segment<double>(0,2));
186  // test count
187  if (!suite.add(set.count(0)==1))
188    suite.err() << "error: set.count(0): expected 1\n";
189  if (!suite.add(set.count(1)==1))
190    suite.err() << "error: set.count(1): expected 1\n";
191  if (!suite.add(set.count(2)==0))
192    suite.err() << "error: set.count(2): expected 0\n";
193}
194
195void test_insert_merge(test::Suite& suite)
196{
197  SegmentSet<double> set;
198  set.insert(Segment<double>(0,2));
199  set.insert_merge(Segment<double>(3,5));
200  if (!suite.add(set.size()==2))
201    suite.err() << "error: set.size(): expected 2\n";
202
203  set.insert_merge(Segment<double>(12,13));
204  if (!suite.add(set.size()==3))
205    suite.err() << "error: set.size(): expected 3\n";
206
207  set.insert_merge(Segment<double>(1,4));
208  if (!suite.add(set.size()==2))
209    suite.err() << "error: set.size(): " << set.size() << " expected 2\n";
210
211  set.insert_merge(Segment<double>(0,100));
212  if (!suite.add(set.size()==1))
213    suite.err() << "error: set.size(): " << set.size() << " expected 1\n";
214  set.insert_merge(set.end(), Segment<double>(200, 1000));
215
216  SegmentSet<double> set2;
217  set2.insert_merge(set.begin(), set.end());
218  std::vector<Segment<double> > vec(set.size());
219  std::copy(set.begin(), set.end(), vec.begin());
220  set2.insert_merge(vec.begin(), vec.end());
221}
222
223
224void make_segment_foo(Segment<int> seg)
225{
226}
227
228
229void test_make_segment(test::Suite& suite)
230{
231  make_segment_foo(make_segment(12, 18));
232}
233
234
235void test_set_bound(test::Suite& suite)
236{
237  SegmentSet<double> set;
238  set.insert(Segment<double>(0,2));
239  set.begin();
240  set.end();
241  if (!suite.add(set.lower_bound(-1)==set.begin()))
242    suite.err() << "error: expected set.lower_bound to return begin()\n";
243  if (!suite.add(set.lower_bound(1)==set.begin()))
244    suite.err() << "error: expected set.lower_bound to return begin()\n";
245  if (!suite.add(set.lower_bound(2)==set.end()))
246    suite.err() << "error: expected set.lower_bound to return end()\n";
247
248  if (!suite.add(set.upper_bound(0)==set.end()))
249    suite.err() << "error: expected set.upper_bound to return end()\n";
250  if (!suite.add(set.upper_bound(2)==set.end()))
251    suite.err() << "error: expected set.upper_bound to return end()\n";
252
253  set.insert_merge(Segment<double>(3,4));
254  SegmentSet<double>::const_iterator i=set.lower_bound(3.5);
255  if (i->begin() != 3 || i->end() != 4) {
256    suite.add(false);
257    suite.out() << "found: " << i->begin() << " " << i->end() << "\n";
258    suite.out() << "expected: 3 4\n";
259  }
260
261  i=set.lower_bound(1);
262  if (i->begin() != 0 || i->end() != 2) {
263    suite.add(false);
264    suite.out() << "found: " << i->begin() << " " << i->end() << "\n";
265    suite.out() << "expected: 0 2\n";
266  }
267
268  set.clear();
269}
270
271
272void test_segment_map(test::Suite& suite)
273{
274  typedef SegmentMap<double, std::string> Map;
275  Map map;
276  Map::element_type x = 0.0;
277  avoid_pedantic_warning(x);
278  Map::key_type key = Segment<double>(1.0,2.0);
279  Map::mapped_type  mapped = "foofana";
280
281  map.insert(Map::value_type(key, mapped));
282  suite.add(map.find(1.5) != map.end());
283  suite.add(map.find(1.5)->second == "foofana");
284
285  Map::iterator i = map.begin();
286  i = map.end();
287  const Map const_map(map);
288  Map::const_iterator ci = const_map.begin();
289  ci = const_map.end();
290
291  suite.add(map.size()==1);
292  map.clear();
293  suite.add(map.empty()==true);
294  suite.add(map.size()==0);
295  map = const_map;
296  suite.add(map.size()==1);
297  suite.add(const_map.count(1.0)==1);
298  suite.add(const_map.count(0.0)==0);
299  suite.add(const_map.empty()==false);
300  suite.add(const_map.find(1.0)==const_map.begin());
301  suite.add(const_map.find(30.0)==const_map.end());
302  ci = const_map.lower_bound(0.0);
303  ci = const_map.upper_bound(0.0);
304  i = map.lower_bound(0.0);
305  i = map.upper_bound(0.0);
306}
307
308
309void test_segment_set(test::Suite& suite)
310{
311  SegmentSet<double> set;
312  Segment<double> segment(0.12,23.2);
313  set.insert_merge(segment);
314  set.insert_merge(Segment<double>(0.12,23.2));
315  SegmentSet<double>::iterator hint = set.begin();
316  set.insert_merge(hint, segment);
317  set.insert_merge(hint, Segment<double>(0.12,23.2));
318  SegmentSet<double>::const_iterator chint = set.begin();
319  set.insert_merge(chint, segment);
320  set.insert_merge(chint, Segment<double>(0.12,23.2));
321  std::vector<Segment<double>> vec(set.begin(), set.end());
322  set.insert_merge(vec.begin(), vec.end());
323
324  // test functions inherited from SegmentTree
325  SegmentSet<double>::const_iterator citer = set.begin();
326  SegmentSet<double>::const_iterator iter = set.begin();
327
328  citer = set.end();
329  iter = set.end();
330
331  if (set.count(0.13)!=1) {
332    suite.add(false);
333    suite.err() << "error: expected count = 1\n";
334  }
335  if (set.count(0.02)!=0) {
336    suite.add(false);
337    suite.err() << "error: expected count = 0\n";
338  }
339  if (set.empty()) {
340    suite.add(false);
341    suite.err() << "error: expected empty() return false";
342  }
343  if (set.find(0.15) == set.end()) {
344    suite.add(false);
345    suite.err() << "error: find returned end()";
346  }
347  set.erase(set.begin());
348  set.clear();
349  set.erase(set.begin(), set.end());
350
351  set.insert(segment);
352  set.insert(Segment<double>(102, 200));
353
354  iter = set.lower_bound(1.0);
355  citer = set.lower_bound(1.0);
356  iter = set.upper_bound(1.0);
357  citer = set.upper_bound(1.0);
358  SegmentSet<double>::size_type s = set.size();
359  test::avoid_compiler_warning(s);
360}
361
362
363void test_segment(test::Suite& suite)
364{
365  Segment<double> segment12(0,2);
366  Segment<double> segment13(1,3);
367  if (segment12==segment13) {
368    suite.add(false);
369    suite.err() << "segment12==segment13 : expected false\n";
370  }
371  if (!(segment12!=segment13)) {
372    suite.add(false);
373    suite.err() << "segment12!=segment13 : expected true\n";
374  }
375  Segment<double> segment14 = intersection(segment12, segment13);
376  suite.add(segment14.begin()==1);
377  suite.add(segment14.end()==2);
378
379  if (!suite.add(compare(Segment<double>(0,2), Segment<double>(3,4))))
380    suite.err() << "error: compare: expected 1\n";
381  if (!suite.add(compare_3way(Segment<double>(0,2), Segment<double>(3,4))==-1))
382    suite.err() << "error: compare_3way: expected -1\n";
383
384  if (!suite.add(compare(Segment<double>(0,2), Segment<double>(1,2))==false))
385    suite.err() << "error: compare: expected 0\n";
386  if (!suite.add(compare_3way(Segment<double>(0,2), Segment<double>(1,2))==0))
387    suite.err() << "error: compare_3way: expected 0\n";
388
389  if (!suite.add(compare(Segment<double>(3,4), Segment<double>(0,2))==false))
390    suite.err() << "error: compare: expected 0\n";
391  if (!suite.add(compare_3way(Segment<double>(3,4), Segment<double>(0,2))==1))
392    suite.err() << "error: compare_3way: expected 1\n";
393
394}
395
396
397void test_includes(test::Suite& suite, const Segment<int>& a,
398                   const Segment<int>& b, bool answer)
399{
400  if (includes(a, b) != answer) {
401    suite.add(false);
402    suite.err() << "error: includes: "
403                << "[" << a.begin() << ", "
404                << a.end() << ") "
405                << "[" << b.begin() << ", "
406                << b.end() << ") "
407                << "expected: " << answer << "\n";
408  }
409}
410
411
412void test_includes(test::Suite& suite)
413{
414  Segment<int> a(0, 10);
415  Segment<int> b(0, 5);
416  Segment<int> c(5, 10);
417
418  test_includes(suite, a, a, true);
419  test_includes(suite, a, b, false);
420  test_includes(suite, a, c, false);
421
422  test_includes(suite, b, a, true);
423  test_includes(suite, b, b, true);
424  test_includes(suite, b, c, false);
425
426  test_includes(suite, c, a, true);
427  test_includes(suite, c, b, false);
428  test_includes(suite, c, c, true);
429}
430
431
432void test_overlap(test::Suite& suite, const Segment<int>& a,
433                  const Segment<int>& b, bool answer)
434{
435  if (overlap(a, b) != answer) {
436    suite.add(false);
437    suite.err() << "error: overlap: "
438                << "[" << a.begin() << ", "
439                << a.end() << ") "
440                << "[" << b.begin() << ", "
441                << b.end() << ") "
442                << "expected: " << answer << "\n";
443  }
444}
445
446
447void test_overlap(test::Suite& suite)
448{
449  Segment<int> a(0, 10);
450  Segment<int> b(0, 5);
451  Segment<int> c(5, 10);
452
453  test_overlap(suite, a, a, true);
454  test_overlap(suite, a, b, true);
455  test_overlap(suite, a, c, true);
456
457  test_overlap(suite, b, a, true);
458  test_overlap(suite, b, b, true);
459  test_overlap(suite, b, c, false);
460
461  test_overlap(suite, c, a, true);
462  test_overlap(suite, c, b, false);
463  test_overlap(suite, c, c, true);
464}
465
466
467void test_union(test::Suite& suite, const Segment<int>& a,
468                const Segment<int>& b, const Segment<int>& answer)
469{
470  if (set_union(a, b) != answer) {
471    suite.add(false);
472    suite.err() << "error: union: "
473                << "[" << a.begin() << ", "
474                << a.end() << ") "
475                << "[" << b.begin() << ", "
476                << b.end() << ") "
477                << "expected: [" << answer.begin() << "," << answer.end()
478                << " )\n";
479  }
480}
481
482
483void test_union(test::Suite& suite)
484{
485  Segment<int> a(0, 10);
486  Segment<int> b(0, 5);
487  Segment<int> c(5, 12);
488
489  test_union(suite, a, a, a);
490  test_union(suite, a, b, a);
491  test_union(suite, a, c, Segment<int>(0,12));
492
493  test_union(suite, b, a, a);
494  test_union(suite, b, b, b);
495  test_union(suite, b, c, Segment<int>(0,12));
496
497  test_union(suite, c, a, Segment<int>(0,12));
498  test_union(suite, c, b, Segment<int>(0,12));
499  test_union(suite, c, c, c);
500}
Note: See TracBrowser for help on using the repository browser.