1 #include <vector>
2 #include <algorithm>
3 #include <functional>
4
5 #if defined (STLPORT) && defined (_STLP_DEBUG) && defined (_STLP_DEBUG_MODE_THROWS)
6 # define _STLP_DO_CHECK_BAD_PREDICATE
7 # include <stdexcept>
8 #endif
9
10 #include "cppunit/cppunit_proxy.h"
11
12 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
13 using namespace std;
14 #endif
15
16 //
17 // TestCase class
18 //
19 class SortTest : public CPPUNIT_NS::TestCase
20 {
21 CPPUNIT_TEST_SUITE(SortTest);
22 CPPUNIT_TEST(sort1);
23 CPPUNIT_TEST(sort2);
24 CPPUNIT_TEST(sort3);
25 CPPUNIT_TEST(sort4);
26 CPPUNIT_TEST(stblsrt1);
27 CPPUNIT_TEST(stblsrt2);
28 #if defined (_STLP_DO_CHECK_BAD_PREDICATE)
29 CPPUNIT_TEST(bad_predicate_detected);
30 #endif
31 CPPUNIT_TEST_SUITE_END();
32
33 protected:
34 void sort1();
35 void sort2();
36 void sort3();
37 void sort4();
38 void stblsrt1();
39 void stblsrt2();
40 void bad_predicate_detected();
41
string_less(const char * a_,const char * b_)42 static bool string_less(const char* a_, const char* b_)
43 {
44 return strcmp(a_, b_) < 0 ? 1 : 0;
45 }
46 };
47
48 CPPUNIT_TEST_SUITE_REGISTRATION(SortTest);
49
50 //
51 // tests implementation
52 //
stblsrt1()53 void SortTest::stblsrt1()
54 {
55 //Check that stable_sort do sort
56 int numbers[6] = { 1, 50, -10, 11, 42, 19 };
57 stable_sort(numbers, numbers + 6);
58 //-10 1 11 19 42 50
59 CPPUNIT_ASSERT(numbers[0]==-10);
60 CPPUNIT_ASSERT(numbers[1]==1);
61 CPPUNIT_ASSERT(numbers[2]==11);
62 CPPUNIT_ASSERT(numbers[3]==19);
63 CPPUNIT_ASSERT(numbers[4]==42);
64 CPPUNIT_ASSERT(numbers[5]==50);
65
66 char const* letters[6] = {"bb", "aa", "ll", "dd", "qq", "cc" };
67 stable_sort(letters, letters + 6, string_less);
68 // aa bb cc dd ll qq
69 CPPUNIT_ASSERT( strcmp(letters[0], "aa") == 0 );
70 CPPUNIT_ASSERT( strcmp(letters[1], "bb") == 0 );
71 CPPUNIT_ASSERT( strcmp(letters[2], "cc") == 0 );
72 CPPUNIT_ASSERT( strcmp(letters[3], "dd") == 0 );
73 CPPUNIT_ASSERT( strcmp(letters[4], "ll") == 0 );
74 CPPUNIT_ASSERT( strcmp(letters[5], "qq") == 0 );
75 }
76
77 struct Data {
DataData78 Data(int index, int value)
79 : m_index(index), m_value(value) {}
80
operator ==Data81 bool operator == (const Data& other) const
82 { return m_index == other.m_index && m_value == other.m_value; }
operator <Data83 bool operator < (const Data& other) const
84 { return m_value < other.m_value; }
85
86 private:
87 int m_index, m_value;
88 };
89
stblsrt2()90 void SortTest::stblsrt2()
91 {
92 //Check that stable_sort is stable:
93 Data datas[] = {
94 Data(0, 10),
95 Data(1, 8),
96 Data(2, 6),
97 Data(3, 6),
98 Data(4, 6),
99 Data(5, 4),
100 Data(6, 9)
101 };
102 stable_sort(datas, datas + 7);
103
104 CPPUNIT_ASSERT( datas[0] == Data(5, 4) );
105 CPPUNIT_ASSERT( datas[1] == Data(2, 6) );
106 CPPUNIT_ASSERT( datas[2] == Data(3, 6) );
107 CPPUNIT_ASSERT( datas[3] == Data(4, 6) );
108 CPPUNIT_ASSERT( datas[4] == Data(1, 8) );
109 CPPUNIT_ASSERT( datas[5] == Data(6, 9) );
110 CPPUNIT_ASSERT( datas[6] == Data(0, 10) );
111 }
112
sort1()113 void SortTest::sort1()
114 {
115 int numbers[6] = { 1, 50, -10, 11, 42, 19 };
116
117 sort(numbers, numbers + 6);
118 // -10 1 11 19 42 50
119 CPPUNIT_ASSERT(numbers[0]==-10);
120 CPPUNIT_ASSERT(numbers[1]==1);
121 CPPUNIT_ASSERT(numbers[2]==11);
122 CPPUNIT_ASSERT(numbers[3]==19);
123 CPPUNIT_ASSERT(numbers[4]==42);
124 CPPUNIT_ASSERT(numbers[5]==50);
125 }
126
sort2()127 void SortTest::sort2()
128 {
129 int numbers[] = { 1, 50, -10, 11, 42, 19 };
130
131 int count = sizeof(numbers) / sizeof(numbers[0]);
132 sort(numbers, numbers + count, greater<int>());
133
134 // 50 42 19 11 1 -10
135 CPPUNIT_ASSERT(numbers[5]==-10);
136 CPPUNIT_ASSERT(numbers[4]==1);
137 CPPUNIT_ASSERT(numbers[3]==11);
138 CPPUNIT_ASSERT(numbers[2]==19);
139 CPPUNIT_ASSERT(numbers[1]==42);
140 CPPUNIT_ASSERT(numbers[0]==50);
141 }
142
sort3()143 void SortTest::sort3()
144 {
145 vector<bool> boolVector;
146
147 boolVector.push_back( true );
148 boolVector.push_back( false );
149
150 sort( boolVector.begin(), boolVector.end() );
151
152 CPPUNIT_ASSERT(boolVector[0]==false);
153 CPPUNIT_ASSERT(boolVector[1]==true);
154 }
155
156 /*
157 * A small utility class to check a potential compiler bug
158 * that can result in a bad sort algorithm behavior. The type
159 * _Tp of the SortTestFunc has to be SortTestAux without any
160 * reference qualifier.
161 */
162 struct SortTestAux {
SortTestAuxSortTestAux163 SortTestAux (bool &b) : _b(b)
164 {}
165
SortTestAuxSortTestAux166 SortTestAux (SortTestAux const&other) : _b(other._b) {
167 _b = true;
168 }
169
170 bool &_b;
171
172 private:
173 //explicitely defined as private to avoid warnings:
174 SortTestAux& operator = (SortTestAux const&);
175 };
176
177 template <class _Tp>
SortTestFunc(_Tp)178 void SortTestFunc (_Tp) {
179 }
180
sort4()181 void SortTest::sort4()
182 {
183 bool copy_constructor_called = false;
184 SortTestAux instance(copy_constructor_called);
185 SortTestAux &r_instance = instance;
186 SortTestAux const& rc_instance = instance;
187
188 SortTestFunc(r_instance);
189 CPPUNIT_ASSERT(copy_constructor_called);
190 copy_constructor_called = false;
191 SortTestFunc(rc_instance);
192 CPPUNIT_ASSERT(copy_constructor_called);
193 }
194
195 #if defined (_STLP_DO_CHECK_BAD_PREDICATE)
bad_predicate_detected()196 void SortTest::bad_predicate_detected()
197 {
198 int numbers[] = { 0, 0, 1, 0, 0, 1, 0, 0 };
199 try {
200 sort(numbers, numbers + sizeof(numbers) / sizeof(numbers[0]), less_equal<int>());
201
202 //Here is means that no exception has been raised
203 CPPUNIT_ASSERT( false );
204 }
205 catch (runtime_error const&)
206 { /*OK bad predicate has been detected.*/ }
207
208 try {
209 stable_sort(numbers, numbers + sizeof(numbers) / sizeof(numbers[0]), less_equal<int>());
210
211 //Here is means that no exception has been raised
212 CPPUNIT_ASSERT( false );
213 }
214 catch (runtime_error const&)
215 { /*OK bad predicate has been detected.*/ }
216 }
217 #endif
218