#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