1212#include < catch.hpp>
1313#include < gfx/timsort.hpp>
1414
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 () : _it() {
67+ }
68+
69+ explicit NoPostIterator (Iterator it) : _it(it) {
70+ }
71+
72+ // //////////////////////////////////////////////////////////
73+ // Members access
74+
75+ iterator_type base () const {
76+ return _it;
77+ }
78+
79+ // //////////////////////////////////////////////////////////
80+ // Element access
81+
82+ reference operator *() const {
83+ return *base ();
84+ }
85+
86+ pointer operator ->() const {
87+ return &(operator *());
88+ }
89+
90+ // //////////////////////////////////////////////////////////
91+ // Increment/decrement operators
92+
93+ NoPostIterator& operator ++() {
94+ ++_it;
95+ return *this ;
96+ }
97+
98+ NoPostIterator& operator --() {
99+ --_it;
100+ return *this ;
101+ }
102+
103+ NoPostIterator& operator +=(difference_type increment) {
104+ _it += increment;
105+ return *this ;
106+ }
107+
108+ NoPostIterator& operator -=(difference_type increment) {
109+ _it -= increment;
110+ return *this ;
111+ }
112+
113+ // //////////////////////////////////////////////////////////
114+ // Comparison operators
115+
116+ friend bool operator ==(NoPostIterator const & lhs, NoPostIterator const & rhs) {
117+ return lhs.base () == rhs.base ();
118+ }
119+
120+ friend bool operator !=(NoPostIterator const & lhs, NoPostIterator const & rhs) {
121+ return lhs.base () != rhs.base ();
122+ }
123+
124+ // //////////////////////////////////////////////////////////
125+ // Relational operators
126+
127+ friend bool operator <(NoPostIterator const & lhs, NoPostIterator const & rhs) {
128+ return lhs.base () < rhs.base ();
129+ }
130+
131+ friend bool operator <=(NoPostIterator const & lhs, NoPostIterator const & rhs) {
132+ return lhs.base () <= rhs.base ();
133+ }
134+
135+ friend bool operator >(NoPostIterator const & lhs, NoPostIterator const & rhs) {
136+ return lhs.base () > rhs.base ();
137+ }
138+
139+ friend bool operator >=(NoPostIterator const & lhs, NoPostIterator const & rhs) {
140+ return lhs.base () >= rhs.base ();
141+ }
142+
143+ // //////////////////////////////////////////////////////////
144+ // Arithmetic operators
145+
146+ friend NoPostIterator operator +(NoPostIterator it, difference_type size) {
147+ return it += size;
148+ }
149+
150+ friend NoPostIterator operator +(difference_type size, NoPostIterator it) {
151+ return it += size;
152+ }
153+
154+ friend NoPostIterator operator -(NoPostIterator it, difference_type size) {
155+ return it -= size;
156+ }
157+
158+ friend difference_type operator -(NoPostIterator const & lhs, NoPostIterator const & rhs) {
159+ return lhs.base () - rhs.base ();
160+ }
161+
162+ private:
163+
164+ Iterator _it;
165+ };
166+
167+ // //////////////////////////////////////////////////////////
168+ // Construction function
169+
170+ template <typename Iterator>
171+ NoPostIterator<Iterator> make_no_post_iterator (Iterator it) {
172+ return NoPostIterator<Iterator>(it);
173+ }
174+
175+ }
176+
15177TEST_CASE ( " simple0" ) {
16178 std::vector<int > a;
17179
@@ -358,17 +520,6 @@ TEST_CASE( "string_array" ) {
358520 CHECK (a[4 ] == " 9" );
359521}
360522
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-
372523TEST_CASE ( " non_default_constructible" ) {
373524 NonDefaultConstructible a[] = {7 , 1 , 5 , 3 , 9 };
374525
@@ -398,14 +549,6 @@ TEST_CASE( "default_compare_function" ) {
398549 }
399550}
400551
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-
409552TEST_CASE ( " stability" ) {
410553 std::vector<pair_t > a;
411554
@@ -446,13 +589,6 @@ TEST_CASE( "stability" ) {
446589 CHECK (a[11 ].second == baz);
447590}
448591
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-
456592TEST_CASE ( " issue2_duplication" ) {
457593 std::vector<std::pair<int , int > > a;
458594
@@ -465,8 +601,8 @@ TEST_CASE( "issue2_duplication" ) {
465601
466602 std::vector<std::pair<int , int > > expected (a);
467603
468- std::sort (expected.begin (), expected.end (), &less_in_pair );
469- gfx::timsort (a.begin (), a.end (), &less_in_pair );
604+ std::sort (expected.begin (), expected.end ());
605+ gfx::timsort (a.begin (), a.end ());
470606
471607#if 0
472608 for (std::size_t i = 0; i < a.size(); ++i) {
@@ -531,3 +667,11 @@ TEST_CASE( "projection" ) {
531667 CHECK (vec[i] == i - 40 );
532668 }
533669}
670+
671+ TEST_CASE ( " iterator without post-increment or post-decrement" ) {
672+ std::vector<int > a;
673+
674+ gfx::timsort (make_no_post_iterator (a.begin ()), make_no_post_iterator (a.end ()));
675+
676+ CHECK (a.size () == std::size_t (0 ));
677+ }
0 commit comments