sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // To make GLib C++ closer to STLport behavior we need this macro: sl@0: // Only mandatory when building unit tests without STLport, do not change sl@0: // anything when building with STLport sl@0: // sl@0: // sl@0: sl@0: #define _GLIBCXX_FULLY_DYNAMIC_STRING sl@0: sl@0: //Has to be first for StackAllocator swap overload to be taken sl@0: //into account (at least using GCC 4.0.1) sl@0: #include "stack_allocator.h" sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS) sl@0: # include sl@0: #endif sl@0: sl@0: #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) sl@0: # include sl@0: #endif sl@0: sl@0: #if !defined (STLPORT) || defined (_STLP_THREADS) sl@0: # if defined (STLPORT) && defined (_STLP_PTHREADS) || \ sl@0: defined (__GNUC__) && !defined (__MINGW32__) sl@0: # define USE_PTHREAD_API sl@0: # include sl@0: # endif sl@0: sl@0: # if defined (STLPORT) && defined (_STLP_WIN32THREADS) || \ sl@0: defined (__GNUC__) && defined (__MINGW32__) || \ sl@0: defined (_MSC_VER) sl@0: # define USE_WINDOWS_API sl@0: # include sl@0: # endif sl@0: #endif sl@0: sl@0: #include "stack_allocator.h" sl@0: #include "cppunit/cppunit_proxy.h" sl@0: sl@0: #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) sl@0: using namespace std; sl@0: #endif sl@0: sl@0: // sl@0: // TestCase class sl@0: // sl@0: class StringTest : public CPPUNIT_NS::TestCase sl@0: { sl@0: CPPUNIT_TEST_SUITE(StringTest); sl@0: CPPUNIT_TEST(constructor); sl@0: CPPUNIT_TEST(reserve); sl@0: CPPUNIT_TEST(assign); sl@0: CPPUNIT_TEST(erase); sl@0: CPPUNIT_TEST(data); sl@0: CPPUNIT_TEST(c_str); sl@0: CPPUNIT_TEST(null_char); sl@0: CPPUNIT_TEST(insert); sl@0: CPPUNIT_TEST(replace); sl@0: CPPUNIT_TEST(resize); sl@0: CPPUNIT_TEST(short_string); sl@0: CPPUNIT_TEST(find); sl@0: CPPUNIT_TEST(rfind); sl@0: CPPUNIT_TEST(find_last_of); sl@0: CPPUNIT_TEST(find_last_not_of); sl@0: CPPUNIT_TEST(copy); sl@0: #if !defined (USE_PTHREAD_API) && !defined (USE_WINDOWS_API) sl@0: CPPUNIT_IGNORE; sl@0: #endif sl@0: CPPUNIT_TEST(mt); sl@0: CPPUNIT_STOP_IGNORE; sl@0: CPPUNIT_TEST(short_string_optim_bug); sl@0: CPPUNIT_TEST(compare); sl@0: #if defined (__DMC__) sl@0: CPPUNIT_IGNORE; sl@0: #endif sl@0: CPPUNIT_TEST(template_expression); sl@0: #if defined (STLPORT) && defined (_STLP_MSVC) && (_STLP_MSVC < 1300) sl@0: # define TE_TMP_TEST_IGNORED sl@0: CPPUNIT_IGNORE; sl@0: #endif sl@0: CPPUNIT_TEST(te_tmp); sl@0: #if defined (TE_TMP_TEST_IGNORED) sl@0: CPPUNIT_STOP_IGNORE; sl@0: #endif sl@0: #if defined (STLPORT) && defined (_STLP_NO_WCHAR_T) sl@0: CPPUNIT_IGNORE; sl@0: #endif sl@0: #if defined (__CYGWIN__) && !defined (STLPORT) sl@0: CPPUNIT_IGNORE; sl@0: #endif sl@0: CPPUNIT_TEST(template_wexpression); sl@0: CPPUNIT_STOP_IGNORE; sl@0: #if defined (STLPORT) && defined (_STLP_USE_NO_IOSTREAMS) sl@0: CPPUNIT_IGNORE; sl@0: #endif sl@0: CPPUNIT_TEST(io); sl@0: CPPUNIT_STOP_IGNORE; sl@0: #if defined (STLPORT) && defined (_STLP_NO_CUSTOM_IO) sl@0: CPPUNIT_IGNORE; sl@0: #endif sl@0: CPPUNIT_TEST(allocator_with_state); sl@0: CPPUNIT_STOP_IGNORE; sl@0: CPPUNIT_TEST(capacity); sl@0: CPPUNIT_TEST(str_cov1); sl@0: CPPUNIT_TEST(str_cov2); sl@0: CPPUNIT_TEST(str_cov3); sl@0: CPPUNIT_TEST(str_cov4); sl@0: CPPUNIT_TEST(str_cov5); sl@0: CPPUNIT_TEST(str_cov6); sl@0: CPPUNIT_TEST_SUITE_END(); sl@0: sl@0: protected: sl@0: void constructor(); sl@0: void reserve(); sl@0: void erase(); sl@0: void data(); sl@0: void c_str(); sl@0: void null_char(); sl@0: void insert(); sl@0: void replace(); sl@0: void resize(); sl@0: void short_string(); sl@0: void find(); sl@0: void rfind(); sl@0: void find_last_of(); sl@0: void find_last_not_of(); sl@0: void copy(); sl@0: void assign(); sl@0: void mt(); sl@0: void short_string_optim_bug(); sl@0: void compare(); sl@0: void template_expression(); sl@0: void te_tmp(); sl@0: void template_wexpression(); sl@0: void io(); sl@0: void allocator_with_state(); sl@0: void capacity(); sl@0: void str_cov1(); sl@0: void str_cov2(); sl@0: void str_cov3(); sl@0: void str_cov4(); sl@0: void str_cov5(); sl@0: void str_cov6(); sl@0: static string func(const string& par) { sl@0: string tmp( par ); sl@0: return tmp; sl@0: } sl@0: sl@0: #if defined (USE_PTHREAD_API) || defined (USE_WINDOWS_API) sl@0: # if defined (USE_PTHREAD_API) sl@0: static void* f(void*) sl@0: # else sl@0: static DWORD __stdcall f(void*) sl@0: # endif sl@0: { sl@0: string s( "qyweyuewunfkHBUKGYUGL,wehbYGUW^(@T@H!BALWD:h^&@#*@(#:JKHWJ:CND" ); sl@0: sl@0: for ( int i = 0; i < 2000000; ++i ) { sl@0: string sx = func( s ); sl@0: } sl@0: sl@0: return 0; sl@0: } sl@0: #endif sl@0: sl@0: }; sl@0: sl@0: CPPUNIT_TEST_SUITE_REGISTRATION(StringTest); sl@0: sl@0: // sl@0: // tests implementation sl@0: // sl@0: void StringTest::constructor() sl@0: { sl@0: #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) sl@0: try { sl@0: string s((size_t)-1, 'a'); sl@0: CPPUNIT_ASSERT( false ); sl@0: } sl@0: catch (length_error const&) { sl@0: } sl@0: catch (...) { sl@0: //Expected exception is length_error: sl@0: CPPUNIT_ASSERT( false ); sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: void StringTest::reserve() sl@0: { sl@0: string s; sl@0: #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) sl@0: try { sl@0: s.reserve(s.max_size() + 1); sl@0: CPPUNIT_ASSERT( false ); sl@0: } sl@0: catch (length_error const&) { sl@0: } sl@0: catch (...) { sl@0: //Expected exception is length_error: sl@0: CPPUNIT_ASSERT( false ); sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: void StringTest::mt() sl@0: { sl@0: #if defined (USE_PTHREAD_API) || defined (USE_WINDOWS_API) sl@0: const int nth = 2; sl@0: # if defined (USE_PTHREAD_API) sl@0: pthread_t t[nth]; sl@0: sl@0: for ( int i = 0; i < nth; ++i ) { sl@0: pthread_create( &t[i], 0, f, 0 ); sl@0: } sl@0: sl@0: for ( int i = 0; i < nth; ++i ) { sl@0: pthread_join( t[i], 0 ); sl@0: } sl@0: # endif // PTHREAD sl@0: sl@0: # if defined (USE_WINDOWS_API) sl@0: //DWORD start = GetTickCount(); sl@0: sl@0: HANDLE t[nth]; sl@0: sl@0: int i; // VC6 not support in-loop scope of cycle var sl@0: for ( i = 0; i < nth; ++i ) { sl@0: t[i] = CreateThread(NULL, 0, f, 0, 0, NULL); sl@0: } sl@0: sl@0: if (WaitForMultipleObjects(nth, t, TRUE, INFINITE) == WAIT_FAILED) { sl@0: // On some platforms (evc3/evc4) WaitForMultipleObjects() with fWaitAll == TRUE sl@0: // is not supported. We then wait with a loop on each thread: sl@0: for ( i = 0; i < nth; ++i ) { sl@0: WaitForSingleObject(t[i], INFINITE); sl@0: } sl@0: } sl@0: sl@0: /* sl@0: DWORD duration = GetTickCount() - start; sl@0: ostringstream ostr; sl@0: ostr << "Duration: " << duration << endl; sl@0: CPPUNIT_MESSAGE(ostr.str().c_str()); sl@0: */ sl@0: # endif sl@0: #endif sl@0: } sl@0: sl@0: void StringTest::short_string() sl@0: { sl@0: string const ref_short_str1("str1"), ref_short_str2("str2"); sl@0: string short_str1(ref_short_str1), short_str2(ref_short_str2); sl@0: string const ref_long_str1("str 1"); sl@0: string const ref_long_str2("str 2"); sl@0: string long_str1(ref_long_str1), long_str2(ref_long_str2); sl@0: sl@0: CPPUNIT_ASSERT(short_str1 == ref_short_str1); sl@0: CPPUNIT_ASSERT(long_str1 == ref_long_str1); sl@0: sl@0: { sl@0: string str1(short_str1); sl@0: str1 = long_str1; sl@0: CPPUNIT_ASSERT(str1 == ref_long_str1); sl@0: } sl@0: sl@0: { sl@0: string str1(long_str1); sl@0: str1 = short_str1; sl@0: CPPUNIT_ASSERT(str1 == ref_short_str1); sl@0: } sl@0: sl@0: { sl@0: short_str1.swap(short_str2); sl@0: CPPUNIT_ASSERT((short_str1 == ref_short_str2) && (short_str2 == ref_short_str1)); sl@0: short_str1.swap(short_str2); sl@0: } sl@0: sl@0: { sl@0: long_str1.swap(long_str2); sl@0: CPPUNIT_ASSERT((long_str1 == ref_long_str2) && (long_str2 == ref_long_str1)); sl@0: long_str1.swap(long_str2); sl@0: } sl@0: sl@0: { sl@0: short_str1.swap(long_str1); sl@0: CPPUNIT_ASSERT((short_str1 == ref_long_str1) && (long_str1 == ref_short_str1)); sl@0: short_str1.swap(long_str1); sl@0: } sl@0: sl@0: { sl@0: long_str1.swap(short_str1); sl@0: CPPUNIT_ASSERT((short_str1 == ref_long_str1) && (long_str1 == ref_short_str1)); sl@0: long_str1.swap(short_str1); sl@0: } sl@0: sl@0: { sl@0: //This is to test move constructor sl@0: vector str_vect; sl@0: str_vect.push_back(short_str1); sl@0: str_vect.push_back(long_str1); sl@0: str_vect.push_back(short_str2); sl@0: str_vect.push_back(long_str2); sl@0: CPPUNIT_ASSERT((str_vect[0] == ref_short_str1) && sl@0: (str_vect[1] == ref_long_str1) && sl@0: (str_vect[2] == ref_short_str2) && sl@0: (str_vect[3] == ref_long_str2)); sl@0: } sl@0: } sl@0: sl@0: void StringTest::erase() sl@0: { sl@0: char const* c_str = "Hello, World!"; sl@0: string str(c_str); sl@0: CPPUNIT_ASSERT( str == c_str ); sl@0: sl@0: str.erase(str.begin() + 1, str.end() - 1); // Erase all but first and last. sl@0: sl@0: size_t i; sl@0: for (i = 0; i < str.size(); ++i) { sl@0: switch ( i ) { sl@0: case 0: sl@0: CPPUNIT_ASSERT( str[i] == 'H' ); sl@0: break; sl@0: case 1: sl@0: CPPUNIT_ASSERT( str[i] == '!' ); sl@0: break; sl@0: default: sl@0: CPPUNIT_ASSERT( false ); sl@0: } sl@0: } sl@0: sl@0: str.insert(1, c_str); sl@0: str.erase(str.begin()); // Erase first element. sl@0: str.erase(str.end() - 1); // Erase last element. sl@0: CPPUNIT_ASSERT( str == c_str ); sl@0: str.clear(); // Erase all. sl@0: CPPUNIT_ASSERT( str.empty() ); sl@0: sl@0: str = c_str; sl@0: CPPUNIT_ASSERT( str == c_str ); sl@0: sl@0: str.erase(1, str.size() - 1); // Erase all but first and last. sl@0: for (i = 0; i < str.size(); i++) { sl@0: switch ( i ) { sl@0: case 0: sl@0: CPPUNIT_ASSERT( str[i] == 'H' ); sl@0: break; sl@0: case 1: sl@0: CPPUNIT_ASSERT( str[i] == '!' ); sl@0: break; sl@0: default: sl@0: CPPUNIT_ASSERT( false ); sl@0: } sl@0: } sl@0: sl@0: str.erase(1); sl@0: CPPUNIT_ASSERT( str == "H" ); sl@0: } sl@0: sl@0: void StringTest::data() sl@0: { sl@0: string xx; sl@0: sl@0: CPPUNIT_ASSERT( xx.data() != 0 ); // ISO-IEC-14882:1998(E), 21.3.6, paragraph 3 sl@0: #if 0 sl@0: /* This test really not required: in ISO-IEC-14882:1998(E) paragraph 3 stated: sl@0: * '... and can have zero added to it', again: 'CAN', but not 'MUST'. sl@0: * That's why I am comment this test. But I don't remove it due to I had sl@0: * unevident problem with misinterpretation of data() return (i.e. data() sl@0: * and c_str() provide different functionality!) and expect that this is sl@0: * more-or-less common pitfall. sl@0: * - ptr sl@0: */ sl@0: string low( "2004-01-01" ); sl@0: // Blocks A and B should follow each other. sl@0: // Block A: sl@0: xx = "123456"; sl@0: xx += low; sl@0: if ( strcmp( xx.data(), "1234562004-01-01" ) != 0 ) { sl@0: return -1; sl@0: } sl@0: // End of block A sl@0: sl@0: // Block B: sl@0: xx = "1234"; sl@0: xx += ";"; sl@0: sl@0: if ( strcmp( xx.data(), "1234;" ) != 0 ) { sl@0: return -1; sl@0: } sl@0: // End of block B sl@0: #endif sl@0: } sl@0: sl@0: void StringTest::c_str() sl@0: { sl@0: string low( "2004-01-01" ); sl@0: string xx; sl@0: string yy; sl@0: sl@0: CPPUNIT_ASSERT( *(yy.c_str()) == '\0' ); // ISO-IEC-14882:1998(E), 21.3.6, paragraph 1 sl@0: sl@0: // Blocks A and B should follow each other. sl@0: // Block A: sl@0: xx = "123456"; sl@0: xx += low; sl@0: CPPUNIT_ASSERT( strcmp( xx.c_str(), "1234562004-01-01" ) == 0 ); sl@0: // End of block A sl@0: sl@0: // Block B: sl@0: xx = "1234"; sl@0: xx += ";"; sl@0: CPPUNIT_ASSERT( strcmp( xx.c_str(), "1234;" ) == 0 ); sl@0: // End of block B sl@0: } sl@0: sl@0: void StringTest::null_char() sl@0: { sl@0: // ISO/IEC 14882:1998(E), ISO/IEC 14882:2003(E), 21.3.4 ('... the const version') sl@0: const string s( "123456" ); sl@0: sl@0: CPPUNIT_CHECK( s[s.size()] == '\0' ); sl@0: sl@0: #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) sl@0: try { sl@0: //Check is only here to avoid warning about value of expression not used sl@0: CPPUNIT_CHECK( s.at(s.size()) == '\0' ); sl@0: CPPUNIT_ASSERT( false ); sl@0: } sl@0: catch (out_of_range const&) { sl@0: CPPUNIT_ASSERT( true ); sl@0: } sl@0: catch ( ... ) { sl@0: CPPUNIT_ASSERT( false ); sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: void StringTest::insert() sl@0: { sl@0: string strorg = "This is test string for string calls"; sl@0: string str; sl@0: /* sl@0: * In case of reallocation there is no auto reference problem sl@0: * so we reserve a big enough string to be sure to test this sl@0: * particular point. sl@0: */ sl@0: str.reserve(100); sl@0: str = strorg; sl@0: sl@0: //test self insertion: sl@0: str.insert(10, str.c_str() + 5, 15); sl@0: CPPUNIT_ASSERT( str == "This is teis test string st string for string calls" ); sl@0: sl@0: str = strorg; sl@0: str.insert(15, str.c_str() + 5, 25); sl@0: CPPUNIT_ASSERT( str == "This is test stis test string for stringring for string calls" ); sl@0: sl@0: str = strorg; sl@0: str.insert(0, str.c_str() + str.size() - 4, 4); sl@0: CPPUNIT_ASSERT( str == "allsThis is test string for string calls" ); sl@0: sl@0: str = strorg; sl@0: str.insert(0, str.c_str() + str.size() / 2 - 1, str.size() / 2 + 1); sl@0: CPPUNIT_ASSERT( str == "ng for string callsThis is test string for string calls" ); sl@0: sl@0: str = strorg; sl@0: string::iterator b = str.begin(); sl@0: string::const_iterator s = str.begin() + str.size() / 2 - 1; sl@0: string::const_iterator e = str.end(); sl@0: str.insert( b, s, e ); sl@0: CPPUNIT_ASSERT( str == "ng for string callsThis is test string for string calls" ); sl@0: sl@0: str = strorg; sl@0: str.insert(str.begin(), str.begin() + str.size() / 2 - 1, str.end()); sl@0: CPPUNIT_ASSERT( str == "ng for string callsThis is test string for string calls" ); sl@0: sl@0: #ifdef _STLP_MEMBER_TEMPLATES sl@0: vector int_vect; sl@0: //Just a compile time test: sl@0: str.insert(str.end(), int_vect.begin(), int_vect.end()); sl@0: #endif sl@0: sl@0: string str0; sl@0: str0.insert(str0.begin(), 5, '0'); sl@0: CPPUNIT_ASSERT( str0 == "00000" ); sl@0: sl@0: string str1; sl@0: { sl@0: string::size_type pos = 0, nb = 2; sl@0: str1.insert(pos, nb, '1'); sl@0: } sl@0: CPPUNIT_ASSERT( str1 == "11" ); sl@0: sl@0: str0.insert(0, str1); sl@0: CPPUNIT_ASSERT( str0 == "1100000" ); sl@0: sl@0: string str2("2345"); sl@0: str0.insert(str0.size(), str2, 1, 2); sl@0: CPPUNIT_ASSERT( str0 == "110000034" ); sl@0: sl@0: str1.insert(str1.begin() + 1, 2, '2'); sl@0: CPPUNIT_ASSERT( str1 == "1221" ); sl@0: sl@0: str1.insert(2, "333333", 3); sl@0: CPPUNIT_ASSERT( str1 == "1233321" ); sl@0: sl@0: str1.insert(4, "4444"); sl@0: CPPUNIT_ASSERT( str1 == "12334444321" ); sl@0: sl@0: str1.insert(str1.begin() + 6, '5'); sl@0: CPPUNIT_ASSERT( str1 == "123344544321" ); sl@0: } sl@0: sl@0: void StringTest::replace() sl@0: { sl@0: /* sl@0: * This test case is for the non template basic_string::replace method, sl@0: * this is why we play with the const iterators and reference to guaranty sl@0: * that the right method is called. sl@0: */ sl@0: const string v( "78" ); sl@0: string s( "123456" ); sl@0: string const& cs = s; sl@0: sl@0: string::iterator i = s.begin() + 1; sl@0: s.replace(i, i + 3, v.begin(), v.end()); sl@0: CPPUNIT_ASSERT( s == "17856" ); sl@0: sl@0: s = "123456"; sl@0: i = s.begin() + 1; sl@0: s.replace(i, i + 1, v.begin(), v.end()); sl@0: CPPUNIT_ASSERT( s == "1783456" ); sl@0: sl@0: s = "123456"; sl@0: i = s.begin() + 1; sl@0: string::const_iterator ci = s.begin() + 1; sl@0: s.replace(i, i + 3, ci + 3, cs.end()); sl@0: CPPUNIT_ASSERT( s == "15656" ); sl@0: sl@0: s = "123456"; sl@0: i = s.begin() + 1; sl@0: ci = s.begin() + 1; sl@0: s.replace(i, i + 3, ci, ci + 2); sl@0: CPPUNIT_ASSERT( s == "12356" ); sl@0: sl@0: s = "123456"; sl@0: i = s.begin() + 1; sl@0: ci = s.begin() + 1; sl@0: s.replace(i, i + 3, ci + 1, cs.end()); sl@0: CPPUNIT_ASSERT( s == "1345656" ); sl@0: sl@0: s = "123456"; sl@0: s.replace(s.begin() + 4, s.end(), cs.begin(), cs.end()); sl@0: CPPUNIT_ASSERT( s == "1234123456" ); sl@0: sl@0: /* sl@0: * This is the test for the template replace method. sl@0: */ sl@0: s = "123456"; sl@0: string::iterator b = s.begin() + 4; sl@0: string::iterator e = s.end(); sl@0: string::const_iterator rb = s.begin(); sl@0: string::const_iterator re = s.end(); sl@0: s.replace(b, e, rb, re); sl@0: CPPUNIT_ASSERT( s == "1234123456" ); sl@0: sl@0: s = "123456"; sl@0: s.replace(s.begin() + 4, s.end(), s.begin(), s.end()); sl@0: CPPUNIT_ASSERT( s == "1234123456" ); sl@0: sl@0: string strorg("This is test string for string calls"); sl@0: string str = strorg; sl@0: str.replace(5, 15, str.c_str(), 10); sl@0: CPPUNIT_ASSERT( str == "This This is tefor string calls" ); sl@0: sl@0: str = strorg; sl@0: str.replace(5, 5, str.c_str(), 10); sl@0: CPPUNIT_ASSERT( str == "This This is test string for string calls" ); sl@0: sl@0: #if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATES) sl@0: deque cdeque; sl@0: cdeque.push_back('I'); sl@0: str.replace(str.begin(), str.begin() + 11, cdeque.begin(), cdeque.end()); sl@0: CPPUNIT_ASSERT( str == "Is test string for string calls" ); sl@0: #endif sl@0: } sl@0: sl@0: void StringTest::resize() sl@0: { sl@0: string s; sl@0: sl@0: s.resize(0); sl@0: sl@0: CPPUNIT_ASSERT( *s.c_str() == 0 ); sl@0: sl@0: s = "1234567"; sl@0: sl@0: s.resize(0); sl@0: CPPUNIT_ASSERT( *s.c_str() == 0 ); sl@0: sl@0: s = "1234567"; sl@0: s.resize(1); sl@0: CPPUNIT_ASSERT( s.size() == 1 ); sl@0: CPPUNIT_ASSERT( *s.c_str() == '1' ); sl@0: CPPUNIT_ASSERT( *(s.c_str() + 1) == 0 ); sl@0: sl@0: s = "1234567"; sl@0: s.resize(10); sl@0: CPPUNIT_ASSERT( s.size() == 10 ); sl@0: CPPUNIT_ASSERT( s[6] == '7' ); sl@0: CPPUNIT_ASSERT( s[7] == 0 ); sl@0: CPPUNIT_ASSERT( s[8] == 0 ); sl@0: CPPUNIT_ASSERT( s[9] == 0 ); sl@0: } sl@0: sl@0: void StringTest::find() sl@0: { sl@0: string s("one two three one two three"); sl@0: CPPUNIT_ASSERT( s.find("one") == 0 ); sl@0: CPPUNIT_ASSERT( s.find('t') == 4 ); sl@0: CPPUNIT_ASSERT( s.find('t', 5) == 8 ); sl@0: //We are trying to get a const reference to the npos string static member to sl@0: //force the compiler to allocate memory for this variable. It used to reveal sl@0: //a bug of STLport which was simply declaring npos without instanciating it. sl@0: #if !defined (STLPORT) || !defined (_STLP_STATIC_CONST_INIT_BUG) sl@0: string::size_type const& npos_local = string::npos; sl@0: #else sl@0: # define npos_local string::npos sl@0: #endif sl@0: CPPUNIT_ASSERT( s.find("four") == npos_local ); sl@0: CPPUNIT_ASSERT( s.find("one", string::npos) == npos_local ); sl@0: sl@0: CPPUNIT_ASSERT( s.find_first_of("abcde") == 2 ); sl@0: sl@0: CPPUNIT_ASSERT( s.find_first_not_of("enotw ") == 9 ); sl@0: } sl@0: sl@0: void StringTest::rfind() sl@0: { sl@0: // 21.3.6.2 sl@0: string s("one two three one two three"); sl@0: sl@0: CPPUNIT_ASSERT( s.rfind("two") == 18 ); sl@0: CPPUNIT_ASSERT( s.rfind("two", 0) == string::npos ); sl@0: CPPUNIT_ASSERT( s.rfind("two", 11) == 4 ); sl@0: CPPUNIT_ASSERT( s.rfind('w') == 19 ); sl@0: sl@0: string test( "aba" ); sl@0: sl@0: CPPUNIT_CHECK( test.rfind( "a", 2, 1 ) == 2 ); sl@0: CPPUNIT_CHECK( test.rfind( "a", 1, 1 ) == 0 ); sl@0: CPPUNIT_CHECK( test.rfind( "a", 0, 1 ) == 0 ); sl@0: sl@0: CPPUNIT_CHECK( test.rfind( 'a', 2 ) == 2 ); sl@0: CPPUNIT_CHECK( test.rfind( 'a', 1 ) == 0 ); sl@0: CPPUNIT_CHECK( test.rfind( 'a', 0 ) == 0 ); sl@0: } sl@0: sl@0: void StringTest::find_last_of() sl@0: { sl@0: // 21.3.6.4 sl@0: string s("one two three one two three"); sl@0: sl@0: CPPUNIT_ASSERT( s.find_last_of("abcde") == 26 ); sl@0: sl@0: string test( "aba" ); sl@0: sl@0: CPPUNIT_CHECK( test.find_last_of( "a", 2, 1 ) == 2 ); sl@0: CPPUNIT_CHECK( test.find_last_of( "a", 1, 1 ) == 0 ); sl@0: CPPUNIT_CHECK( test.find_last_of( "a", 0, 1 ) == 0 ); sl@0: sl@0: CPPUNIT_CHECK( test.find_last_of( 'a', 2 ) == 2 ); sl@0: CPPUNIT_CHECK( test.find_last_of( 'a', 1 ) == 0 ); sl@0: CPPUNIT_CHECK( test.find_last_of( 'a', 0 ) == 0 ); sl@0: } sl@0: sl@0: void StringTest::find_last_not_of() sl@0: { sl@0: // 21.3.6.6 sl@0: string s("one two three one two three"); sl@0: sl@0: CPPUNIT_ASSERT( s.find_last_not_of("ehortw ") == 15 ); sl@0: sl@0: string test( "aba" ); sl@0: sl@0: CPPUNIT_CHECK( test.find_last_not_of( "a", 2, 1 ) == 1 ); sl@0: CPPUNIT_CHECK( test.find_last_not_of( "b", 2, 1 ) == 2 ); sl@0: CPPUNIT_CHECK( test.find_last_not_of( "a", 1, 1 ) == 1 ); sl@0: CPPUNIT_CHECK( test.find_last_not_of( "b", 1, 1 ) == 0 ); sl@0: CPPUNIT_CHECK( test.find_last_not_of( "a", 0, 1 ) == string::npos ); sl@0: CPPUNIT_CHECK( test.find_last_not_of( "b", 0, 1 ) == 0 ); sl@0: sl@0: CPPUNIT_CHECK( test.find_last_not_of( 'a', 2 ) == 1 ); sl@0: CPPUNIT_CHECK( test.find_last_not_of( 'b', 2 ) == 2 ); sl@0: CPPUNIT_CHECK( test.find_last_not_of( 'a', 1 ) == 1 ); sl@0: CPPUNIT_CHECK( test.find_last_not_of( 'b', 1 ) == 0 ); sl@0: CPPUNIT_CHECK( test.find_last_not_of( 'a', 0 ) == string::npos ); sl@0: CPPUNIT_CHECK( test.find_last_not_of( 'b', 0 ) == 0 ); sl@0: } sl@0: sl@0: void StringTest::copy() sl@0: { sl@0: string s("foo"); sl@0: char dest[4]; sl@0: dest[0] = dest[1] = dest[2] = dest[3] = 1; sl@0: s.copy(dest, 4); sl@0: int pos = 0; sl@0: CPPUNIT_ASSERT( dest[pos++] == 'f' ); sl@0: CPPUNIT_ASSERT( dest[pos++] == 'o' ); sl@0: CPPUNIT_ASSERT( dest[pos++] == 'o' ); sl@0: CPPUNIT_ASSERT( dest[pos++] == 1 ); sl@0: sl@0: dest[0] = dest[1] = dest[2] = dest[3] = 1; sl@0: s.copy(dest, 4, 2); sl@0: pos = 0; sl@0: CPPUNIT_ASSERT( dest[pos++] == 'o' ); sl@0: CPPUNIT_ASSERT( dest[pos++] == 1 ); sl@0: sl@0: #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) sl@0: try { sl@0: s.copy(dest, 4, 5); sl@0: CPPUNIT_ASSERT( false ); sl@0: } sl@0: catch (out_of_range const&) { sl@0: CPPUNIT_ASSERT( true ); sl@0: } sl@0: catch ( ... ) { sl@0: CPPUNIT_ASSERT( false ); sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: void StringTest::assign() sl@0: { sl@0: string s; sl@0: char const* cstr = "test string for assign"; sl@0: sl@0: s.assign(cstr, cstr + 22); sl@0: CPPUNIT_ASSERT( s == "test string for assign" ); sl@0: sl@0: string s2("other test string"); sl@0: s.assign(s2); sl@0: CPPUNIT_ASSERT( s == s2 ); sl@0: sl@0: static string str1; sl@0: static string str2; sl@0: sl@0: // short string optim: sl@0: str1 = "123456"; sl@0: // longer than short string: sl@0: str2 = "1234567890123456789012345678901234567890"; sl@0: sl@0: CPPUNIT_ASSERT(str1[5] == '6'); sl@0: CPPUNIT_ASSERT(str2[29] == '0'); sl@0: } sl@0: sl@0: /* This test is to check if std::string properly supports the short string sl@0: * optimization. It has been found out that eMbedded Visual C++ 3.0 and .NET sl@0: * compilers for the ARM platform fail to pass structs and classes of certain sl@0: * size per value. This seems to be a known compiler bug. For other processors sl@0: * (e.g. x86) the error doesn't occur. sl@0: * (The ARM compiler creates a temporary object from teststr on the stack, to sl@0: * pass it to the helper function. It uses the copy constructor for this. sl@0: * After this the temporary object is copied to another place on the stack. sl@0: * The result is that the _M_finish pointer then points to the wrong buffer sl@0: * end and the size of the short string is incorrectly calculated.) sl@0: */ sl@0: void StringTest::short_string_optim_bug() sl@0: { sl@0: string teststr("shortest"); sl@0: sl@0: bool short_string_optim_bug_helper(string teststr); sl@0: sl@0: CPPUNIT_ASSERT(true == short_string_optim_bug_helper(teststr)); sl@0: } sl@0: sl@0: bool short_string_optim_bug_helper(string teststr) sl@0: { sl@0: size_t ss = teststr.size(); sl@0: return (ss == 8); sl@0: } sl@0: sl@0: void StringTest::compare() sl@0: { sl@0: string str1("abcdef"); sl@0: string str2; sl@0: sl@0: str2 = "abcdef"; sl@0: CPPUNIT_ASSERT( str1.compare(str2) == 0 ); sl@0: str2 = "abcde"; sl@0: CPPUNIT_ASSERT( str1.compare(str2) > 0 ); sl@0: str2 = "abcdefg"; sl@0: CPPUNIT_ASSERT( str1.compare(str2) < 0 ); sl@0: sl@0: CPPUNIT_ASSERT( str1.compare("abcdef") == 0 ); sl@0: CPPUNIT_ASSERT( str1.compare("abcde") > 0 ); sl@0: CPPUNIT_ASSERT( str1.compare("abcdefg") < 0 ); sl@0: sl@0: str2 = "cde"; sl@0: CPPUNIT_ASSERT( str1.compare(2, 3, str2) == 0 ); sl@0: str2 = "cd"; sl@0: CPPUNIT_ASSERT( str1.compare(2, 3, str2) > 0 ); sl@0: str2 = "cdef"; sl@0: CPPUNIT_ASSERT( str1.compare(2, 3, str2) < 0 ); sl@0: sl@0: str2 = "abcdef"; sl@0: CPPUNIT_ASSERT( str1.compare(2, 3, str2, 2, 3) == 0 ); sl@0: CPPUNIT_ASSERT( str1.compare(2, 3, str2, 2, 2) > 0 ); sl@0: CPPUNIT_ASSERT( str1.compare(2, 3, str2, 2, 4) < 0 ); sl@0: sl@0: CPPUNIT_ASSERT( str1.compare(2, 3, "cdefgh", 3) == 0 ); sl@0: CPPUNIT_ASSERT( str1.compare(2, 3, "cdefgh", 2) > 0 ); sl@0: CPPUNIT_ASSERT( str1.compare(2, 3, "cdefgh", 4) < 0 ); sl@0: } sl@0: sl@0: /* sl@0: class mystring : public string { sl@0: public: sl@0: mystring() {} sl@0: mystring(string const& s) : string(s) {} sl@0: sl@0: mystring& operator = (string const& s) { sl@0: string::operator = (s); sl@0: return *this; sl@0: }; sl@0: }; sl@0: */ sl@0: sl@0: void StringTest::template_expression() sl@0: { sl@0: string one("one"), two("two"), three("three"); sl@0: string space(1, ' '); sl@0: sl@0: // check availability of [un]equality operators sl@0: { sl@0: // string-string sl@0: one == two; sl@0: one != two; sl@0: // string-literal sl@0: one == "two"; sl@0: one != "two"; sl@0: // literal-string sl@0: "one" == two; sl@0: "one" != two; sl@0: // strsum-string sl@0: (one + two) == three; sl@0: (one + two) != three; sl@0: // string-strsum sl@0: one == (two + three); sl@0: one != (two + three); sl@0: // strsum-literal sl@0: (one + two) == "three"; sl@0: (one + two) != "three"; sl@0: // literal-strsum sl@0: "one" == (two + three); sl@0: "one" != (two + three); sl@0: // strsum-strsum sl@0: (one + two) == (two + three); sl@0: (one + two) != (two + three); sl@0: } sl@0: sl@0: { sl@0: string result(one + ' ' + two + ' ' + three); sl@0: CPPUNIT_CHECK( result == "one two three" ); sl@0: } sl@0: sl@0: { sl@0: string result(one + ' ' + two + ' ' + three, 4); sl@0: CPPUNIT_CHECK( result == "two three" ); sl@0: } sl@0: sl@0: { sl@0: string result(one + ' ' + two + ' ' + three, 4, 3); sl@0: CPPUNIT_CHECK( result == "two" ); sl@0: } sl@0: sl@0: //2 members expressions: sl@0: CPPUNIT_CHECK( (' ' + one) == " one" ); sl@0: CPPUNIT_CHECK( (one + ' ') == "one " ); sl@0: CPPUNIT_CHECK( (one + " two") == "one two" ); sl@0: CPPUNIT_CHECK( ("one " + two) == "one two" ); sl@0: CPPUNIT_CHECK( (one + space) == "one " ); sl@0: sl@0: //3 members expressions: sl@0: CPPUNIT_CHECK( ((one + space) + "two") == "one two" ); sl@0: CPPUNIT_CHECK( ("one" + (space + two)) == "one two" ); sl@0: CPPUNIT_CHECK( ((one + space) + two) == "one two" ); sl@0: CPPUNIT_CHECK( (one + (space + two)) == "one two" ); sl@0: CPPUNIT_CHECK( ((one + space) + 't') == "one t" ); sl@0: CPPUNIT_CHECK( ('o' + (space + two)) == "o two" ); sl@0: sl@0: //4 members expressions: sl@0: CPPUNIT_CHECK( ((one + space) + (two + space)) == "one two " ); sl@0: sl@0: //special operators sl@0: { sl@0: string result; sl@0: result = one + space + two; sl@0: CPPUNIT_CHECK( result == "one two" ); sl@0: sl@0: result += space + three; sl@0: CPPUNIT_CHECK( result == "one two three" ); sl@0: } sl@0: sl@0: //special append method sl@0: { sl@0: string result; sl@0: //Use reserve to avoid reallocation and really test auto-referencing problems: sl@0: result.reserve(64); sl@0: sl@0: result.append(one + space + two); sl@0: CPPUNIT_CHECK( result == "one two" ); sl@0: sl@0: result.append(space + result + space + three); sl@0: CPPUNIT_CHECK( result == "one two one two three" ); sl@0: sl@0: result = "one two"; sl@0: result.append(space + three, 1, 2); sl@0: CPPUNIT_ASSERT( result == "one twoth" ); sl@0: sl@0: result.append(space + result); sl@0: CPPUNIT_CHECK( result == "one twoth one twoth" ); sl@0: } sl@0: sl@0: //special assign method sl@0: { sl@0: string result; sl@0: //Use reserve to avoid reallocation and really test auto-referencing problems: sl@0: result.reserve(64); sl@0: sl@0: result.assign(one + space + two + space + three); sl@0: CPPUNIT_CHECK( result == "one two three" ); sl@0: sl@0: result.assign(one + space + two + space + three, 3, 5); sl@0: CPPUNIT_CHECK( result == " two " ); sl@0: sl@0: result.assign(one + result + three); sl@0: CPPUNIT_CHECK( result == "one two three" ); sl@0: } sl@0: sl@0: { sl@0: CPPUNIT_CHECK( !(one + ' ' + two).empty() ); sl@0: sl@0: char result = (one + ' ' + two)[3]; sl@0: CPPUNIT_CHECK( result == ' ' ); sl@0: sl@0: result = (one + ' ' + two).at(3); sl@0: CPPUNIT_CHECK( result == ' ' ); sl@0: sl@0: #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) sl@0: try { sl@0: result = (one + ' ' + two).at(10); sl@0: CPPUNIT_ASSERT(false); sl@0: } sl@0: catch (out_of_range const&) { sl@0: CPPUNIT_ASSERT( result == ' ' ); sl@0: } sl@0: catch (...) { sl@0: CPPUNIT_ASSERT(false); sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: /* sl@0: mystring a("ing"); sl@0: //gcc failed to compile following expression when template expressions are activated. sl@0: //MSVC sees no problem. gcc limitation or MSVC is too cool ?? sl@0: mystring b = "str" + a; sl@0: */ sl@0: } sl@0: sl@0: #if !defined (TE_TMP_TEST_IGNORED) sl@0: class superstring sl@0: { sl@0: public: sl@0: superstring() : sl@0: s("super") sl@0: {} sl@0: sl@0: superstring( const string& str ) : sl@0: s( str ) sl@0: {} sl@0: sl@0: superstring operator / (const string& str ) sl@0: { return superstring( s + "/" + str ); } sl@0: sl@0: superstring operator / (const char* str ) sl@0: { return superstring( s + "/" + str ); } sl@0: sl@0: private: sl@0: string s; sl@0: }; sl@0: #endif sl@0: sl@0: void StringTest::te_tmp() sl@0: { sl@0: #if !defined (TE_TMP_TEST_IGNORED) sl@0: superstring s; sl@0: string more( "more" ); sl@0: string less( "less" ); sl@0: sl@0: superstring r = s / (more + less); sl@0: #endif sl@0: } sl@0: sl@0: void StringTest::template_wexpression() sl@0: { sl@0: #if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T) sl@0: # if !defined (__CYGWIN__) || defined (STLPORT) sl@0: wstring one(L"one"), two(L"two"), three(L"three"); sl@0: wstring space(1, L' '); sl@0: sl@0: { sl@0: wstring result(one + L' ' + two + L' ' + three); sl@0: CPPUNIT_CHECK( result == L"one two three" ); sl@0: } sl@0: sl@0: { sl@0: wstring result(one + L' ' + two + L' ' + three, 4); sl@0: CPPUNIT_CHECK( result == L"two three" ); sl@0: } sl@0: sl@0: { sl@0: wstring result(one + L' ' + two + L' ' + three, 4, 3); sl@0: CPPUNIT_CHECK( result == L"two" ); sl@0: } sl@0: sl@0: //2 members expressions: sl@0: CPPUNIT_CHECK( (L' ' + one) == L" one" ); sl@0: CPPUNIT_CHECK( (one + L' ') == L"one " ); sl@0: CPPUNIT_CHECK( (one + L" two") == L"one two" ); sl@0: CPPUNIT_CHECK( (L"one " + two) == L"one two" ); sl@0: CPPUNIT_CHECK( (one + space) == L"one " ); sl@0: sl@0: //3 members expressions: sl@0: CPPUNIT_CHECK( ((one + space) + L"two") == L"one two" ); sl@0: CPPUNIT_CHECK( (L"one" + (space + two)) == L"one two" ); sl@0: CPPUNIT_CHECK( ((one + space) + two) == L"one two" ); sl@0: CPPUNIT_CHECK( (one + (space + two)) == L"one two" ); sl@0: CPPUNIT_CHECK( ((one + space) + L't') == L"one t" ); sl@0: CPPUNIT_CHECK( (L'o' + (space + two)) == L"o two" ); sl@0: sl@0: //4 members expressions: sl@0: CPPUNIT_CHECK( ((one + space) + (two + space)) == L"one two " ); sl@0: sl@0: //special operators sl@0: { sl@0: wstring result; sl@0: result = one + space + two; sl@0: CPPUNIT_CHECK( result == L"one two" ); sl@0: sl@0: result += space + three; sl@0: CPPUNIT_CHECK( result == L"one two three" ); sl@0: } sl@0: sl@0: //special append method sl@0: { sl@0: wstring result; sl@0: //Use reserve to avoid reallocation and really test auto-referencing problems: sl@0: result.reserve(64); sl@0: sl@0: result.append(one + space + two); sl@0: CPPUNIT_CHECK( result == L"one two" ); sl@0: sl@0: result.append(space + result + space + three); sl@0: CPPUNIT_CHECK( result == L"one two one two three" ); sl@0: sl@0: result = L"one two"; sl@0: result.append(space + three, 1, 2); sl@0: CPPUNIT_ASSERT( result == L"one twoth" ); sl@0: sl@0: result.append(space + result); sl@0: CPPUNIT_CHECK( result == L"one twoth one twoth" ); sl@0: } sl@0: sl@0: //special assign method sl@0: { sl@0: wstring result; sl@0: //Use reserve to avoid reallocation and really test auto-referencing problems: sl@0: result.reserve(64); sl@0: sl@0: result.assign(one + space + two + space + three); sl@0: CPPUNIT_CHECK( result == L"one two three" ); sl@0: sl@0: result.assign(one + space + two + space + three, 3, 5); sl@0: CPPUNIT_CHECK( result == L" two " ); sl@0: sl@0: result.assign(one + result + three); sl@0: CPPUNIT_CHECK( result == L"one two three" ); sl@0: } sl@0: sl@0: { sl@0: CPPUNIT_CHECK( !(one + L' ' + two).empty() ); sl@0: sl@0: wchar_t result = (one + L' ' + two)[3]; sl@0: CPPUNIT_CHECK( result == L' ' ); sl@0: sl@0: result = (one + L' ' + two).at(3); sl@0: CPPUNIT_CHECK( result == L' ' ); sl@0: sl@0: # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) sl@0: try { sl@0: result = (one + L' ' + two).at(10); sl@0: CPPUNIT_ASSERT(false); sl@0: } sl@0: catch (out_of_range const&) { sl@0: CPPUNIT_ASSERT( result == L' ' ); sl@0: } sl@0: catch (...) { sl@0: CPPUNIT_ASSERT(false); sl@0: } sl@0: # endif sl@0: } sl@0: # endif sl@0: #endif sl@0: } sl@0: sl@0: void StringTest::io() sl@0: { sl@0: #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS) sl@0: string str("STLport"); sl@0: { sl@0: ostringstream ostr; sl@0: ostr << str; sl@0: CPPUNIT_ASSERT( ostr.good() ); sl@0: CPPUNIT_ASSERT( ostr.str() == str ); sl@0: } sl@0: { sl@0: istringstream istr(str); sl@0: string istr_content; sl@0: istr >> istr_content; sl@0: CPPUNIT_ASSERT( !istr.fail() && istr.eof() ); sl@0: CPPUNIT_ASSERT( istr_content == str ); sl@0: } sl@0: { sl@0: istringstream istr(str); sl@0: istr.width(3); sl@0: string istr_content; sl@0: istr >> istr_content; sl@0: CPPUNIT_ASSERT( !istr.fail() && !istr.eof() ); sl@0: CPPUNIT_ASSERT( istr_content == "STL" ); sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: void StringTest::allocator_with_state() sl@0: { sl@0: #if !(defined (STLPORT) && defined (_STLP_NO_CUSTOM_IO)) sl@0: sl@0: char buf1[1024]; sl@0: StackAllocator stack1(buf1, buf1 + sizeof(buf1)); sl@0: sl@0: char buf2[1024]; sl@0: StackAllocator stack2(buf2, buf2 + sizeof(buf2)); sl@0: sl@0: typedef basic_string, StackAllocator > StackString; sl@0: { sl@0: StackString str1("string stack1", stack1); sl@0: StackString str1Cpy(str1); sl@0: sl@0: StackString str2("string stack2", stack2); sl@0: StackString str2Cpy(str2); sl@0: sl@0: str1.swap(str2); sl@0: sl@0: CPPUNIT_ASSERT( str1.get_allocator().swaped() ); sl@0: CPPUNIT_ASSERT( str2.get_allocator().swaped() ); sl@0: sl@0: CPPUNIT_ASSERT( str1 == str2Cpy ); sl@0: CPPUNIT_ASSERT( str2 == str1Cpy ); sl@0: CPPUNIT_ASSERT( str1.get_allocator() == stack2 ); sl@0: CPPUNIT_ASSERT( str2.get_allocator() == stack1 ); sl@0: } sl@0: CPPUNIT_ASSERT( stack1.ok() ); sl@0: CPPUNIT_ASSERT( stack2.ok() ); sl@0: stack1.reset(); stack2.reset(); sl@0: sl@0: { sl@0: StackString str1("longer string from stack1 allocator instance for dynamic allocation", stack1); sl@0: StackString str1Cpy(str1); sl@0: sl@0: StackString str2("longer string from stack2 allocator instance for dynamic allocation", stack2); sl@0: StackString str2Cpy(str2); sl@0: sl@0: str1.swap(str2); sl@0: sl@0: CPPUNIT_ASSERT( str1.get_allocator().swaped() ); sl@0: CPPUNIT_ASSERT( str2.get_allocator().swaped() ); sl@0: sl@0: CPPUNIT_ASSERT( str1 == str2Cpy ); sl@0: CPPUNIT_ASSERT( str2 == str1Cpy ); sl@0: CPPUNIT_ASSERT( str1.get_allocator() == stack2 ); sl@0: CPPUNIT_ASSERT( str2.get_allocator() == stack1 ); sl@0: } sl@0: CPPUNIT_ASSERT( stack1.ok() ); sl@0: CPPUNIT_ASSERT( stack2.ok() ); sl@0: stack1.reset(); stack2.reset(); sl@0: sl@0: sl@0: { sl@0: StackString str1("string stack1", stack1); sl@0: StackString str1Cpy(str1); sl@0: sl@0: StackString str2("longer string from stack2 allocator instance for dynamic allocation", stack2); sl@0: StackString str2Cpy(str2); sl@0: sl@0: str1.swap(str2); sl@0: sl@0: CPPUNIT_ASSERT( str1.get_allocator().swaped() ); sl@0: CPPUNIT_ASSERT( str2.get_allocator().swaped() ); sl@0: sl@0: CPPUNIT_ASSERT( str1 == str2Cpy ); sl@0: CPPUNIT_ASSERT( str2 == str1Cpy ); sl@0: CPPUNIT_ASSERT( str1.get_allocator() == stack2 ); sl@0: CPPUNIT_ASSERT( str2.get_allocator() == stack1 ); sl@0: } sl@0: CPPUNIT_ASSERT( stack1.ok() ); sl@0: CPPUNIT_ASSERT( stack2.ok() ); sl@0: stack1.reset(); stack2.reset(); sl@0: sl@0: sl@0: { sl@0: StackString str1("longer string from stack1 allocator instance for dynamic allocation", stack1); sl@0: StackString str1Cpy(str1); sl@0: sl@0: StackString str2("string stack2", stack2); sl@0: StackString str2Cpy(str2); sl@0: sl@0: str1.swap(str2); sl@0: sl@0: CPPUNIT_ASSERT( str1.get_allocator().swaped() ); sl@0: CPPUNIT_ASSERT( str2.get_allocator().swaped() ); sl@0: sl@0: CPPUNIT_ASSERT( str1 == str2Cpy ); sl@0: CPPUNIT_ASSERT( str2 == str1Cpy ); sl@0: CPPUNIT_ASSERT( str1.get_allocator() == stack2 ); sl@0: CPPUNIT_ASSERT( str2.get_allocator() == stack1 ); sl@0: } sl@0: CPPUNIT_ASSERT( stack1.ok() ); sl@0: CPPUNIT_ASSERT( stack2.ok() ); sl@0: stack1.reset(); stack2.reset(); sl@0: #endif sl@0: } sl@0: sl@0: void StringTest::capacity() sl@0: { sl@0: string s; sl@0: sl@0: CPPUNIT_CHECK( s.capacity() > 0 ); sl@0: CPPUNIT_CHECK( s.capacity() < s.max_size() ); sl@0: CPPUNIT_CHECK( s.capacity() >= s.size() ); sl@0: sl@0: #ifndef _STLP_SHORT_STRING_SZ sl@0: # define _STLP_SHORT_STRING_SZ 16 // see stlport/stl/_string_base.h sl@0: #endif sl@0: sl@0: for ( int i = 0; i < _STLP_SHORT_STRING_SZ + 2; ++i ) { sl@0: s += ' '; sl@0: CPPUNIT_CHECK( s.capacity() > 0 ); sl@0: CPPUNIT_CHECK( s.capacity() < s.max_size() ); sl@0: CPPUNIT_CHECK( s.capacity() >= s.size() ); sl@0: } sl@0: } sl@0: void StringTest::str_cov1() sl@0: { sl@0: { sl@0: string example( "this is an example string" ); sl@0: string::iterator it = example.begin(); sl@0: example.replace(it+4,example.end()-4,4,'o'); sl@0: CPPUNIT_CHECK(example == "thisooooring" ); sl@0: } sl@0: { sl@0: string str4 ( "This perfectly unclear." ); sl@0: basic_string ::size_type indexCh4a; sl@0: string str4a ( "clear" ); sl@0: indexCh4a = str4.rfind ( str4a , 15 ); sl@0: CPPUNIT_CHECK(indexCh4a == -1 ); sl@0: } sl@0: { sl@0: string str1f ( "Hello " ), str2f ( "Wide World " ); sl@0: swap(str1f,str2f); sl@0: CPPUNIT_CHECK(str1f == "Wide World "); sl@0: CPPUNIT_CHECK(str2f == "Hello "); sl@0: } sl@0: sl@0: } sl@0: void StringTest::str_cov2() sl@0: { sl@0: { sl@0: string result1a, result1b; sl@0: string s1o ( "AAAAAAAA" ); sl@0: string s1p ( "BBB" ); sl@0: const char* cs1p = "CCC"; sl@0: result1a = s1o.replace ( 1 , 3 , s1p ); sl@0: CPPUNIT_CHECK(result1a == "ABBBAAAA"); sl@0: result1b = s1o.replace ( 5 , 3 , cs1p ); sl@0: CPPUNIT_CHECK(result1b == "ABBBACCC"); sl@0: string result2a, result2b; sl@0: string s2o ( "AAAAAAAA" ); sl@0: string s2p ( "BBB" ); sl@0: result2a = s2o.replace ( 1 , 3 , s2p , 1 , 2 ); sl@0: CPPUNIT_CHECK(result2a == "ABBAAAA"); sl@0: string result3a; sl@0: string s3o ( "AAAAAAAA" ); sl@0: char ch3p = 'C'; sl@0: result3a = s3o.replace ( 1 , 3 , 4 , ch3p ); sl@0: CPPUNIT_CHECK(result3a == "ACCCCAAAA"); sl@0: string s4o ( "AAAAAAAA" ); sl@0: string s4p ( "BBB" ); sl@0: const char* cs4p = "CCC"; sl@0: basic_string::iterator IterF0, IterL0; sl@0: IterF0 = s4o.begin ( ); sl@0: IterL0 = s4o.begin ( ) + 3; sl@0: string result4a, result4b; sl@0: result4a = s4o.replace ( IterF0 , IterL0 , s4p ); sl@0: CPPUNIT_CHECK(result4a == "BBBAAAAA"); sl@0: result4b = s4o.replace ( IterF0 , IterL0 , cs4p ); sl@0: CPPUNIT_CHECK(result4b == "CCCAAAAA"); sl@0: string s5o ( "AAAAAAAF" ); sl@0: const char* cs5p = "CCCBB"; sl@0: basic_string::iterator IterF1, IterL1; sl@0: IterF1 = s5o.begin ( ); sl@0: IterL1 = s5o.begin ( ) + 4; sl@0: string result5a; sl@0: result5a = s5o.replace ( IterF1 , IterL1 , cs5p , 4 ); sl@0: CPPUNIT_CHECK(result5a == "CCCBAAAF"); sl@0: string s6o ( "AAAAAAAG" ); sl@0: char ch6p = 'q'; sl@0: basic_string::iterator IterF2, IterL2; sl@0: IterF2 = s6o.begin ( ); sl@0: IterL2 = s6o.begin ( ) + 3; sl@0: string result6a; sl@0: result6a = s6o.replace ( IterF2 , IterL2 , 4 , ch6p ); sl@0: CPPUNIT_CHECK(result6a == "qqqqAAAAG"); sl@0: } sl@0: } sl@0: void StringTest::str_cov3() sl@0: { sl@0: { sl@0: string str1 ("This is the sample test string"), str2; sl@0: basic_string ::reverse_iterator str_rIter, str1_rIter, str2_rIter; sl@0: basic_string ::const_reverse_iterator str1_rcIter; sl@0: str1_rIter = str1.rend ( ); sl@0: str1_rIter--; sl@0: CPPUNIT_CHECK(*str1_rIter == 'T'); sl@0: str_rIter = str1.rbegin( ); sl@0: CPPUNIT_CHECK(*str_rIter == 'g'); sl@0: str1_rcIter = str1.rbegin( ); sl@0: CPPUNIT_CHECK(*str1_rcIter == 'g'); sl@0: str1_rcIter = str1.rend ( ); sl@0: str1_rcIter--; sl@0: CPPUNIT_CHECK(*str1_rcIter == 'T'); sl@0: } sl@0: { sl@0: string str1a ( "Hello " ); sl@0: str1a = "0"; sl@0: CPPUNIT_CHECK(str1a == "0"); sl@0: } sl@0: { sl@0: string str1 ("Hello world"); sl@0: CPPUNIT_CHECK(str1.length ( ) == 11); sl@0: } sl@0: { sl@0: int comp5a; sl@0: string s5o ( "AACAB" ); sl@0: const char* cs5p = "CAB"; sl@0: comp5a = s5o.compare ( 2 , 3 , cs5p ); sl@0: CPPUNIT_CHECK(comp5a == 0); sl@0: } sl@0: sl@0: } sl@0: void StringTest::str_cov4() sl@0: { sl@0: { sl@0: string str4 ( "12-ab-12-ab" ); sl@0: basic_string ::size_type indexCh4a; sl@0: string str4a ( "ba3" ); sl@0: indexCh4a = str4.find_last_of ( str4a , 8 ); sl@0: CPPUNIT_CHECK(indexCh4a == 4); sl@0: } sl@0: { sl@0: string str4 ( "12-ab-12-ab" ); sl@0: basic_string ::size_type indexCh4a; sl@0: string str4a ( "b-a" ); sl@0: indexCh4a = str4.find_last_not_of ( str4a , 5 ); sl@0: CPPUNIT_CHECK(indexCh4a == 1); sl@0: } sl@0: { sl@0: string str1 ( "abcd-1234-abcd-1234" ); sl@0: basic_string ::size_type indexCh1a; sl@0: sl@0: indexCh1a = str1.find_first_of ( "d" , 5 ); sl@0: CPPUNIT_CHECK(indexCh1a == 13); sl@0: string str2 ( "12-ab-12-ab" ); sl@0: basic_string ::size_type indexCh2a; sl@0: sl@0: string str2a ( "ba3" ); sl@0: indexCh2a = str2.find_first_of ( str2a , 5 ); sl@0: CPPUNIT_CHECK( indexCh2a == 9 ); sl@0: } sl@0: { sl@0: string str4 ( "12-ab-12-ab" ); sl@0: basic_string ::size_type indexCh4a; sl@0: sl@0: string str4a ( "ba3" ); sl@0: indexCh4a = str4.find_first_not_of ( str4a , 5 ); sl@0: CPPUNIT_CHECK(indexCh4a == 5 ); sl@0: } sl@0: } sl@0: void StringTest::str_cov5() sl@0: { sl@0: { sl@0: string str4 ( "clearly this perfectly unclear." ); sl@0: basic_string ::size_type indexCh4a; sl@0: sl@0: string str4a ( "clear" ); sl@0: indexCh4a = str4.find ( str4a , 5 ); sl@0: CPPUNIT_CHECK( indexCh4a != string::npos ); sl@0: } sl@0: { sl@0: const char *cstr1a = "Hello Out There."; sl@0: basic_string str1a ( cstr1a , 5); sl@0: CPPUNIT_CHECK( str1a == "Hello" ); sl@0: } sl@0: { sl@0: string str1a,str1b; sl@0: const char *cstr1a = "Out There"; sl@0: str1a.assign ( cstr1a ); sl@0: CPPUNIT_CHECK(str1a == "Out There"); sl@0: sl@0: str1b.assign ( cstr1a , 3 ); sl@0: CPPUNIT_CHECK(str1b == "Out"); sl@0: sl@0: string str1f ( "Hello " ), str2f ( "Wide World " ); sl@0: str1f.assign ( str2f.begin ( ) + 5 , str2f.end ( ) - 1 ); sl@0: CPPUNIT_CHECK(str1f == "World"); sl@0: } sl@0: { sl@0: string str1f ( "Hello " ), str2f ( "Wide World " ); sl@0: str1f.append ( str2f.begin ( ) + 5 , str2f.end ( ) - 1 ); sl@0: CPPUNIT_CHECK(str1f == "Hello World"); sl@0: sl@0: string str1b ( "Hello " ); sl@0: const char *cstr1b = "Out There "; sl@0: str1b.append ( cstr1b , 3 ); sl@0: CPPUNIT_CHECK(str1b == "Hello Out"); sl@0: } sl@0: } sl@0: void StringTest::str_cov6() sl@0: { sl@0: { sl@0: string s1 ( "AACAB" ); sl@0: string s2 ( "BACAB" ); sl@0: const char* s3 = "CAB"; sl@0: sl@0: bool flag; sl@0: sl@0: flag = s2 >= s1; sl@0: CPPUNIT_CHECK(flag == true); sl@0: sl@0: flag = s3 >= s1; sl@0: CPPUNIT_CHECK(flag == true); sl@0: sl@0: flag = s1 >= s3; sl@0: CPPUNIT_CHECK(flag == false); sl@0: sl@0: flag = s2 > s1; sl@0: CPPUNIT_CHECK(flag == true); sl@0: sl@0: flag = s3 > s1; sl@0: CPPUNIT_CHECK(flag == true); sl@0: sl@0: flag = s1 > s3; sl@0: CPPUNIT_CHECK(flag == false); sl@0: sl@0: flag = s2 <= s1; sl@0: CPPUNIT_CHECK(flag == false); sl@0: sl@0: flag = s3 <= s1; sl@0: CPPUNIT_CHECK(flag == false); sl@0: sl@0: flag = s1 <= s3; sl@0: CPPUNIT_CHECK(flag == true); sl@0: sl@0: flag = s3 < s1; sl@0: CPPUNIT_CHECK(flag == false); sl@0: sl@0: flag = s1 < s3; sl@0: CPPUNIT_CHECK(flag == true); sl@0: } sl@0: { sl@0: string str1 ( "xddd-1234-abcd" ); sl@0: basic_string ::size_type indexCh1a; sl@0: sl@0: indexCh1a = str1.find_first_not_of ( "d" , 2 ); sl@0: CPPUNIT_CHECK(indexCh1a == 4); sl@0: } sl@0: } sl@0: