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 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 // 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 { 78 Data(int index, int value) 79 : m_index(index), m_value(value) {} 80 81 bool operator == (const Data& other) const 82 { return m_index == other.m_index && m_value == other.m_value; } 83 bool operator < (const Data& other) const 84 { return m_value < other.m_value; } 85 86 private: 87 int m_index, m_value; 88 }; 89 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 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 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 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 { 163 SortTestAux (bool &b) : _b(b) 164 {} 165 166 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> 178 void SortTestFunc (_Tp) { 179 } 180 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) 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