Home | History | Annotate | Download | only in unit
      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