12
12
#include < catch.hpp>
13
13
#include < gfx/timsort.hpp>
14
14
15
+ namespace {
16
+ // Helper types for the tests
17
+
18
+ // //////////////////////////////////////////////////////////
19
+ // Timsort should work with types that are not
20
+ // default-constructible
21
+
22
+ struct NonDefaultConstructible {
23
+ int i;
24
+
25
+ NonDefaultConstructible (int i_) : i(i_) {
26
+ }
27
+
28
+ friend bool operator <(NonDefaultConstructible const &x, NonDefaultConstructible const &y) {
29
+ return x.i < y.i ;
30
+ }
31
+ };
32
+
33
+ // //////////////////////////////////////////////////////////
34
+ // Tools to test the stability of the sort
35
+
36
+ enum id { foo, bar, baz };
37
+
38
+ typedef std::pair<int , id> pair_t ;
39
+
40
+ inline bool less_in_first (pair_t x, pair_t y) {
41
+ return x.first < y.first ;
42
+ }
43
+
44
+ // //////////////////////////////////////////////////////////
45
+ // Timsort should work with iterators that don't have a
46
+ // post-increment or post-decrement operation
47
+
48
+ template <typename Iterator>
49
+ class NoPostIterator
50
+ {
51
+ public:
52
+
53
+ // //////////////////////////////////////////////////////////
54
+ // Public types
55
+
56
+ typedef typename std::iterator_traits<Iterator>::iterator_category iterator_category;
57
+ typedef Iterator iterator_type;
58
+ typedef typename std::iterator_traits<Iterator>::value_type value_type;
59
+ typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
60
+ typedef typename std::iterator_traits<Iterator>::pointer pointer;
61
+ typedef typename std::iterator_traits<Iterator>::reference reference;
62
+
63
+ // //////////////////////////////////////////////////////////
64
+ // Constructors
65
+
66
+ NoPostIterator () = default ;
67
+
68
+ explicit NoPostIterator (Iterator it) : _it(it) {
69
+ }
70
+
71
+ // //////////////////////////////////////////////////////////
72
+ // Members access
73
+
74
+ iterator_type base () const {
75
+ return _it;
76
+ }
77
+
78
+ // //////////////////////////////////////////////////////////
79
+ // Element access
80
+
81
+ reference operator *() const {
82
+ return *base ();
83
+ }
84
+
85
+ pointer operator ->() const {
86
+ return &(operator *());
87
+ }
88
+
89
+ // //////////////////////////////////////////////////////////
90
+ // Increment/decrement operators
91
+
92
+ NoPostIterator& operator ++() {
93
+ ++_it;
94
+ return *this ;
95
+ }
96
+
97
+ NoPostIterator& operator --() {
98
+ --_it;
99
+ return *this ;
100
+ }
101
+
102
+ NoPostIterator& operator +=(difference_type increment) {
103
+ _it += increment;
104
+ return *this ;
105
+ }
106
+
107
+ NoPostIterator& operator -=(difference_type increment) {
108
+ _it -= increment;
109
+ return *this ;
110
+ }
111
+
112
+ // //////////////////////////////////////////////////////////
113
+ // Comparison operators
114
+
115
+ friend bool operator ==(NoPostIterator const & lhs, NoPostIterator const & rhs) {
116
+ return lhs.base () == rhs.base ();
117
+ }
118
+
119
+ friend bool operator !=(NoPostIterator const & lhs, NoPostIterator const & rhs) {
120
+ return lhs.base () != rhs.base ();
121
+ }
122
+
123
+ // //////////////////////////////////////////////////////////
124
+ // Relational operators
125
+
126
+ friend bool operator <(NoPostIterator const & lhs, NoPostIterator const & rhs) {
127
+ return lhs.base () < rhs.base ();
128
+ }
129
+
130
+ friend bool operator <=(NoPostIterator const & lhs, NoPostIterator const & rhs) {
131
+ return lhs.base () <= rhs.base ();
132
+ }
133
+
134
+ friend bool operator >(NoPostIterator const & lhs, NoPostIterator const & rhs) {
135
+ return lhs.base () > rhs.base ();
136
+ }
137
+
138
+ friend bool operator >=(NoPostIterator const & lhs, NoPostIterator const & rhs) {
139
+ return lhs.base () >= rhs.base ();
140
+ }
141
+
142
+ // //////////////////////////////////////////////////////////
143
+ // Arithmetic operators
144
+
145
+ friend NoPostIterator operator +(NoPostIterator it, difference_type size) {
146
+ return it += size;
147
+ }
148
+
149
+ friend NoPostIterator operator +(difference_type size, NoPostIterator it) {
150
+ return it += size;
151
+ }
152
+
153
+ friend NoPostIterator operator -(NoPostIterator it, difference_type size) {
154
+ return it -= size;
155
+ }
156
+
157
+ friend difference_type operator -(NoPostIterator const & lhs, NoPostIterator const & rhs) {
158
+ return lhs.base () - rhs.base ();
159
+ }
160
+
161
+ private:
162
+
163
+ Iterator _it;
164
+ };
165
+
166
+ // //////////////////////////////////////////////////////////
167
+ // Construction function
168
+
169
+ template <typename Iterator>
170
+ NoPostIterator<Iterator> make_no_post_iterator (Iterator it) {
171
+ return NoPostIterator<Iterator>(it);
172
+ }
173
+
174
+ }
175
+
15
176
TEST_CASE ( " simple0" ) {
16
177
std::vector<int > a;
17
178
@@ -358,17 +519,6 @@ TEST_CASE( "string_array" ) {
358
519
CHECK (a[4 ] == " 9" );
359
520
}
360
521
361
- struct NonDefaultConstructible {
362
- int i;
363
-
364
- NonDefaultConstructible (int i_) : i(i_) {
365
- }
366
-
367
- friend bool operator <(NonDefaultConstructible const &x, NonDefaultConstructible const &y) {
368
- return x.i < y.i ;
369
- }
370
- };
371
-
372
522
TEST_CASE ( " non_default_constructible" ) {
373
523
NonDefaultConstructible a[] = {7 , 1 , 5 , 3 , 9 };
374
524
@@ -398,14 +548,6 @@ TEST_CASE( "default_compare_function" ) {
398
548
}
399
549
}
400
550
401
- enum id { foo, bar, baz };
402
-
403
- typedef std::pair<int , id> pair_t ;
404
-
405
- inline bool less_in_first (pair_t x, pair_t y) {
406
- return x.first < y.first ;
407
- }
408
-
409
551
TEST_CASE ( " stability" ) {
410
552
std::vector<pair_t > a;
411
553
@@ -446,13 +588,6 @@ TEST_CASE( "stability" ) {
446
588
CHECK (a[11 ].second == baz);
447
589
}
448
590
449
- inline bool less_in_pair (const std::pair<int , int > &x, const std::pair<int , int > &y) {
450
- if (x.first == y.first ) {
451
- return x.second < y.second ;
452
- }
453
- return x.first < y.first ;
454
- }
455
-
456
591
TEST_CASE ( " issue2_duplication" ) {
457
592
std::vector<std::pair<int , int > > a;
458
593
@@ -465,8 +600,8 @@ TEST_CASE( "issue2_duplication" ) {
465
600
466
601
std::vector<std::pair<int , int > > expected (a);
467
602
468
- std::sort (expected.begin (), expected.end (), &less_in_pair );
469
- gfx::timsort (a.begin (), a.end (), &less_in_pair );
603
+ std::sort (expected.begin (), expected.end ());
604
+ gfx::timsort (a.begin (), a.end ());
470
605
471
606
#if 0
472
607
for (std::size_t i = 0; i < a.size(); ++i) {
@@ -531,3 +666,11 @@ TEST_CASE( "projection" ) {
531
666
CHECK (vec[i] == i - 40 );
532
667
}
533
668
}
669
+
670
+ TEST_CASE ( " iterator without post-increment or post-decrement" ) {
671
+ std::vector<int > a;
672
+
673
+ gfx::timsort (make_no_post_iterator (a.begin ()), make_no_post_iterator (a.end ()));
674
+
675
+ CHECK (a.size () == std::size_t (0 ));
676
+ }
0 commit comments