sort_test.cpp revision e46c9386c4f79aa40185f79a19fc5b2a7ef528b3
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)
13using namespace std;
14#endif
15
16//
17// TestCase class
18//
19class 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
33protected:
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
48CPPUNIT_TEST_SUITE_REGISTRATION(SortTest);
49
50//
51// tests implementation
52//
53void 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
77struct 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
86private:
87  int m_index, m_value;
88};
89
90void 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
113void 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
127void 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
143void 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 */
162struct 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
172private:
173  //explicitely defined as private to avoid warnings:
174  SortTestAux& operator = (SortTestAux const&);
175};
176
177template <class _Tp>
178void SortTestFunc (_Tp) {
179}
180
181void 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)
196void 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