| #include <vector> |
| #include <algorithm> |
| #include <functional> |
| |
| #if defined (STLPORT) && defined (_STLP_DEBUG) && defined (_STLP_DEBUG_MODE_THROWS) |
| # define _STLP_DO_CHECK_BAD_PREDICATE |
| # include <stdexcept> |
| #endif |
| |
| #include "cppunit/cppunit_proxy.h" |
| |
| #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) |
| using namespace std; |
| #endif |
| |
| // |
| // TestCase class |
| // |
| class SortTest : public CPPUNIT_NS::TestCase |
| { |
| CPPUNIT_TEST_SUITE(SortTest); |
| CPPUNIT_TEST(sort1); |
| CPPUNIT_TEST(sort2); |
| CPPUNIT_TEST(sort3); |
| CPPUNIT_TEST(sort4); |
| CPPUNIT_TEST(stblsrt1); |
| CPPUNIT_TEST(stblsrt2); |
| #if defined (_STLP_DO_CHECK_BAD_PREDICATE) |
| CPPUNIT_TEST(bad_predicate_detected); |
| #endif |
| CPPUNIT_TEST_SUITE_END(); |
| |
| protected: |
| void sort1(); |
| void sort2(); |
| void sort3(); |
| void sort4(); |
| void stblsrt1(); |
| void stblsrt2(); |
| void bad_predicate_detected(); |
| |
| static bool string_less(const char* a_, const char* b_) |
| { |
| return strcmp(a_, b_) < 0 ? 1 : 0; |
| } |
| }; |
| |
| CPPUNIT_TEST_SUITE_REGISTRATION(SortTest); |
| |
| // |
| // tests implementation |
| // |
| void SortTest::stblsrt1() |
| { |
| //Check that stable_sort do sort |
| int numbers[6] = { 1, 50, -10, 11, 42, 19 }; |
| stable_sort(numbers, numbers + 6); |
| //-10 1 11 19 42 50 |
| CPPUNIT_ASSERT(numbers[0]==-10); |
| CPPUNIT_ASSERT(numbers[1]==1); |
| CPPUNIT_ASSERT(numbers[2]==11); |
| CPPUNIT_ASSERT(numbers[3]==19); |
| CPPUNIT_ASSERT(numbers[4]==42); |
| CPPUNIT_ASSERT(numbers[5]==50); |
| |
| char const* letters[6] = {"bb", "aa", "ll", "dd", "qq", "cc" }; |
| stable_sort(letters, letters + 6, string_less); |
| // aa bb cc dd ll qq |
| CPPUNIT_ASSERT( strcmp(letters[0], "aa") == 0 ); |
| CPPUNIT_ASSERT( strcmp(letters[1], "bb") == 0 ); |
| CPPUNIT_ASSERT( strcmp(letters[2], "cc") == 0 ); |
| CPPUNIT_ASSERT( strcmp(letters[3], "dd") == 0 ); |
| CPPUNIT_ASSERT( strcmp(letters[4], "ll") == 0 ); |
| CPPUNIT_ASSERT( strcmp(letters[5], "qq") == 0 ); |
| } |
| |
| struct Data { |
| Data(int index, int value) |
| : m_index(index), m_value(value) {} |
| |
| bool operator == (const Data& other) const |
| { return m_index == other.m_index && m_value == other.m_value; } |
| bool operator < (const Data& other) const |
| { return m_value < other.m_value; } |
| |
| private: |
| int m_index, m_value; |
| }; |
| |
| void SortTest::stblsrt2() |
| { |
| //Check that stable_sort is stable: |
| Data datas[] = { |
| Data(0, 10), |
| Data(1, 8), |
| Data(2, 6), |
| Data(3, 6), |
| Data(4, 6), |
| Data(5, 4), |
| Data(6, 9) |
| }; |
| stable_sort(datas, datas + 7); |
| |
| CPPUNIT_ASSERT( datas[0] == Data(5, 4) ); |
| CPPUNIT_ASSERT( datas[1] == Data(2, 6) ); |
| CPPUNIT_ASSERT( datas[2] == Data(3, 6) ); |
| CPPUNIT_ASSERT( datas[3] == Data(4, 6) ); |
| CPPUNIT_ASSERT( datas[4] == Data(1, 8) ); |
| CPPUNIT_ASSERT( datas[5] == Data(6, 9) ); |
| CPPUNIT_ASSERT( datas[6] == Data(0, 10) ); |
| } |
| |
| void SortTest::sort1() |
| { |
| int numbers[6] = { 1, 50, -10, 11, 42, 19 }; |
| |
| sort(numbers, numbers + 6); |
| // -10 1 11 19 42 50 |
| CPPUNIT_ASSERT(numbers[0]==-10); |
| CPPUNIT_ASSERT(numbers[1]==1); |
| CPPUNIT_ASSERT(numbers[2]==11); |
| CPPUNIT_ASSERT(numbers[3]==19); |
| CPPUNIT_ASSERT(numbers[4]==42); |
| CPPUNIT_ASSERT(numbers[5]==50); |
| } |
| |
| void SortTest::sort2() |
| { |
| int numbers[] = { 1, 50, -10, 11, 42, 19 }; |
| |
| int count = sizeof(numbers) / sizeof(numbers[0]); |
| sort(numbers, numbers + count, greater<int>()); |
| |
| // 50 42 19 11 1 -10 |
| CPPUNIT_ASSERT(numbers[5]==-10); |
| CPPUNIT_ASSERT(numbers[4]==1); |
| CPPUNIT_ASSERT(numbers[3]==11); |
| CPPUNIT_ASSERT(numbers[2]==19); |
| CPPUNIT_ASSERT(numbers[1]==42); |
| CPPUNIT_ASSERT(numbers[0]==50); |
| } |
| |
| void SortTest::sort3() |
| { |
| vector<bool> boolVector; |
| |
| boolVector.push_back( true ); |
| boolVector.push_back( false ); |
| |
| sort( boolVector.begin(), boolVector.end() ); |
| |
| CPPUNIT_ASSERT(boolVector[0]==false); |
| CPPUNIT_ASSERT(boolVector[1]==true); |
| } |
| |
| /* |
| * A small utility class to check a potential compiler bug |
| * that can result in a bad sort algorithm behavior. The type |
| * _Tp of the SortTestFunc has to be SortTestAux without any |
| * reference qualifier. |
| */ |
| struct SortTestAux { |
| SortTestAux (bool &b) : _b(b) |
| {} |
| |
| SortTestAux (SortTestAux const&other) : _b(other._b) { |
| _b = true; |
| } |
| |
| bool &_b; |
| |
| private: |
| //explicitely defined as private to avoid warnings: |
| SortTestAux& operator = (SortTestAux const&); |
| }; |
| |
| template <class _Tp> |
| void SortTestFunc (_Tp) { |
| } |
| |
| void SortTest::sort4() |
| { |
| bool copy_constructor_called = false; |
| SortTestAux instance(copy_constructor_called); |
| SortTestAux &r_instance = instance; |
| SortTestAux const& rc_instance = instance; |
| |
| SortTestFunc(r_instance); |
| CPPUNIT_ASSERT(copy_constructor_called); |
| copy_constructor_called = false; |
| SortTestFunc(rc_instance); |
| CPPUNIT_ASSERT(copy_constructor_called); |
| } |
| |
| #if defined (_STLP_DO_CHECK_BAD_PREDICATE) |
| void SortTest::bad_predicate_detected() |
| { |
| int numbers[] = { 0, 0, 1, 0, 0, 1, 0, 0 }; |
| try { |
| sort(numbers, numbers + sizeof(numbers) / sizeof(numbers[0]), less_equal<int>()); |
| |
| //Here is means that no exception has been raised |
| CPPUNIT_ASSERT( false ); |
| } |
| catch (runtime_error const&) |
| { /*OK bad predicate has been detected.*/ } |
| |
| try { |
| stable_sort(numbers, numbers + sizeof(numbers) / sizeof(numbers[0]), less_equal<int>()); |
| |
| //Here is means that no exception has been raised |
| CPPUNIT_ASSERT( false ); |
| } |
| catch (runtime_error const&) |
| { /*OK bad predicate has been detected.*/ } |
| } |
| #endif |