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