Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstring_test.cpp
Go to the documentation of this file.
00001 //To make GLib C++ closer to STLport behavior we need this macro: 00002 //Only mandatory when building unit tests without STLport, do not change 00003 //anything when building with STLport 00004 #define _GLIBCXX_FULLY_DYNAMIC_STRING 00005 00006 //Has to be first for StackAllocator swap overload to be taken 00007 //into account (at least using GCC 4.0.1) 00008 #include "stack_allocator.h" 00009 00010 #include <vector> 00011 #include <deque> 00012 #include <string> 00013 #include <algorithm> 00014 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS) 00015 # include <sstream> 00016 #endif 00017 00018 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 00019 # include <stdexcept> 00020 #endif 00021 00022 #if !defined (STLPORT) || defined (_STLP_THREADS) 00023 # if defined (STLPORT) && defined (_STLP_PTHREADS) || \ 00024 defined (__GNUC__) && !defined (__MINGW32__) 00025 # define USE_PTHREAD_API 00026 # include <pthread.h> 00027 # endif 00028 00029 # if defined (STLPORT) && defined (_STLP_WIN32THREADS) || \ 00030 defined (__GNUC__) && defined (__MINGW32__) || \ 00031 defined (_MSC_VER) 00032 # define USE_WINDOWS_API 00033 # include <windows.h> 00034 # endif 00035 #endif 00036 00037 #include "stack_allocator.h" 00038 #include "cppunit/cppunit_proxy.h" 00039 00040 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) 00041 using namespace std; 00042 #endif 00043 00044 // 00045 // TestCase class 00046 // 00047 class StringTest : public CPPUNIT_NS::TestCase 00048 { 00049 CPPUNIT_TEST_SUITE(StringTest); 00050 CPPUNIT_TEST(constructor); 00051 CPPUNIT_TEST(trivial_char_compare); 00052 CPPUNIT_TEST(reserve); 00053 CPPUNIT_TEST(assign); 00054 CPPUNIT_TEST(erase); 00055 CPPUNIT_TEST(data); 00056 CPPUNIT_TEST(c_str); 00057 CPPUNIT_TEST(null_char); 00058 CPPUNIT_TEST(insert); 00059 CPPUNIT_TEST(replace); 00060 CPPUNIT_TEST(resize); 00061 CPPUNIT_TEST(short_string); 00062 CPPUNIT_TEST(find); 00063 CPPUNIT_TEST(bogus_edge_find); 00064 CPPUNIT_TEST(rfind); 00065 CPPUNIT_TEST(find_last_of); 00066 CPPUNIT_TEST(find_last_not_of); 00067 CPPUNIT_TEST(copy); 00068 #if !defined (USE_PTHREAD_API) && !defined (USE_WINDOWS_API) 00069 CPPUNIT_IGNORE; 00070 #endif 00071 CPPUNIT_TEST(mt); 00072 CPPUNIT_STOP_IGNORE; 00073 CPPUNIT_TEST(short_string_optim_bug); 00074 CPPUNIT_TEST(compare); 00075 CPPUNIT_TEST(template_expression); 00076 #if defined (STLPORT) && ((defined (_STLP_MSVC) && (_STLP_MSVC < 1300)) || \ 00077 (defined(__GNUC__) && defined(_STLP_USE_TEMPLATE_EXPRESSION) && \ 00078 ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)) ) ) 00079 # define TE_TMP_TEST_IGNORED 00080 CPPUNIT_IGNORE; 00081 #endif 00082 CPPUNIT_TEST(te_tmp); 00083 #if defined (TE_TMP_TEST_IGNORED) 00084 CPPUNIT_STOP_IGNORE; 00085 #endif 00086 CPPUNIT_TEST(oper_tmp); 00087 #if defined (STLPORT) && defined (_STLP_NO_WCHAR_T) 00088 CPPUNIT_IGNORE; 00089 #endif 00090 #if defined (__CYGWIN__) && !defined (STLPORT) 00091 CPPUNIT_IGNORE; 00092 #endif 00093 CPPUNIT_TEST(template_wexpression); 00094 CPPUNIT_STOP_IGNORE; 00095 #if defined (STLPORT) && defined (_STLP_USE_NO_IOSTREAMS) 00096 CPPUNIT_IGNORE; 00097 #endif 00098 CPPUNIT_TEST(io); 00099 CPPUNIT_STOP_IGNORE; 00100 #if defined (STLPORT) && defined (_STLP_NO_CUSTOM_IO) 00101 CPPUNIT_IGNORE; 00102 #endif 00103 CPPUNIT_TEST(allocator_with_state); 00104 CPPUNIT_STOP_IGNORE; 00105 CPPUNIT_TEST(capacity); 00106 CPPUNIT_TEST(concat24); 00107 CPPUNIT_TEST_SUITE_END(); 00108 00109 protected: 00110 void constructor(); 00111 void trivial_char_compare(); 00112 void reserve(); 00113 void erase(); 00114 void data(); 00115 void c_str(); 00116 void null_char(); 00117 void insert(); 00118 void replace(); 00119 void resize(); 00120 void short_string(); 00121 void find(); 00122 void bogus_edge_find(); 00123 void rfind(); 00124 void find_last_of(); 00125 void find_last_not_of(); 00126 void copy(); 00127 void assign(); 00128 void mt(); 00129 void short_string_optim_bug(); 00130 void compare(); 00131 void template_expression(); 00132 void te_tmp(); 00133 void oper_tmp(); 00134 void template_wexpression(); 00135 void io(); 00136 void allocator_with_state(); 00137 void capacity(); 00138 void concat24(); 00139 00140 static string func(const string& par) { 00141 string tmp( par ); 00142 return tmp; 00143 } 00144 00145 #if defined (USE_PTHREAD_API) || defined (USE_WINDOWS_API) 00146 # if defined (USE_PTHREAD_API) 00147 static void* f(void*) 00148 # else 00149 static DWORD __stdcall f(void*) 00150 # endif 00151 { 00152 string s( "qyweyuewunfkHBUKGYUGL,wehbYGUW^(@T@H!BALWD:h^&@#*@(#:JKHWJ:CND" ); 00153 00154 for ( int i = 0; i < 2000000; ++i ) { 00155 string sx = func( s ); 00156 } 00157 00158 return 0; 00159 } 00160 #endif 00161 00162 }; 00163 00164 CPPUNIT_TEST_SUITE_REGISTRATION(StringTest); 00165 00166 // 00167 // tests implementation 00168 // 00169 void StringTest::constructor() 00170 { 00171 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 00172 try { 00173 string s((size_t)-1, 'a'); 00174 CPPUNIT_FAIL; 00175 } 00176 catch (length_error const&) { 00177 } 00178 catch (...) { 00179 //Expected exception is length_error: 00180 CPPUNIT_FAIL; 00181 } 00182 #endif 00183 } 00184 00185 void StringTest::trivial_char_compare() 00186 { 00187 string s( "message" ); 00188 00189 CPPUNIT_CHECK( s == "message" ); 00190 CPPUNIT_CHECK( "message" == s ); 00191 } 00192 00193 void StringTest::reserve() 00194 { 00195 string s; 00196 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 00197 try { 00198 s.reserve(s.max_size() + 1); 00199 CPPUNIT_FAIL; 00200 } 00201 catch (length_error const&) { 00202 } 00203 catch (...) { 00204 //Expected exception is length_error: 00205 CPPUNIT_FAIL; 00206 } 00207 #endif 00208 } 00209 00210 void StringTest::mt() 00211 { 00212 #if defined (USE_PTHREAD_API) || defined (USE_WINDOWS_API) 00213 const int nth = 2; 00214 # if defined (USE_PTHREAD_API) 00215 pthread_t t[nth]; 00216 00217 for ( int i = 0; i < nth; ++i ) { 00218 pthread_create( &t[i], 0, f, 0 ); 00219 } 00220 00221 for ( int i = 0; i < nth; ++i ) { 00222 pthread_join( t[i], 0 ); 00223 } 00224 # endif // PTHREAD 00225 00226 # if defined (USE_WINDOWS_API) 00227 //DWORD start = GetTickCount(); 00228 00229 HANDLE t[nth]; 00230 00231 int i; // VC6 not support in-loop scope of cycle var 00232 for ( i = 0; i < nth; ++i ) { 00233 t[i] = CreateThread(NULL, 0, f, 0, 0, NULL); 00234 } 00235 00236 if (WaitForMultipleObjects(nth, t, TRUE, INFINITE) == WAIT_FAILED) { 00237 // On some platforms (evc3/evc4) WaitForMultipleObjects() with fWaitAll == TRUE 00238 // is not supported. We then wait with a loop on each thread: 00239 for ( i = 0; i < nth; ++i ) { 00240 WaitForSingleObject(t[i], INFINITE); 00241 } 00242 } 00243 00244 /* 00245 DWORD duration = GetTickCount() - start; 00246 ostringstream ostr; 00247 ostr << "Duration: " << duration << endl; 00248 CPPUNIT_MESSAGE(ostr.str().c_str()); 00249 */ 00250 # endif 00251 #endif 00252 } 00253 00254 void StringTest::short_string() 00255 { 00256 string const ref_short_str1("str1"), ref_short_str2("str2"); 00257 string short_str1(ref_short_str1), short_str2(ref_short_str2); 00258 string const ref_long_str1("str 1"); 00259 string const ref_long_str2("str 2"); 00260 string long_str1(ref_long_str1), long_str2(ref_long_str2); 00261 00262 CPPUNIT_ASSERT(short_str1 == ref_short_str1); 00263 CPPUNIT_ASSERT(long_str1 == ref_long_str1); 00264 00265 { 00266 string str1(short_str1); 00267 str1 = long_str1; 00268 CPPUNIT_ASSERT(str1 == ref_long_str1); 00269 } 00270 00271 { 00272 string str1(long_str1); 00273 str1 = short_str1; 00274 CPPUNIT_ASSERT(str1 == ref_short_str1); 00275 } 00276 00277 { 00278 short_str1.swap(short_str2); 00279 CPPUNIT_ASSERT((short_str1 == ref_short_str2) && (short_str2 == ref_short_str1)); 00280 short_str1.swap(short_str2); 00281 } 00282 00283 { 00284 long_str1.swap(long_str2); 00285 CPPUNIT_ASSERT((long_str1 == ref_long_str2) && (long_str2 == ref_long_str1)); 00286 long_str1.swap(long_str2); 00287 } 00288 00289 { 00290 short_str1.swap(long_str1); 00291 CPPUNIT_ASSERT((short_str1 == ref_long_str1) && (long_str1 == ref_short_str1)); 00292 short_str1.swap(long_str1); 00293 } 00294 00295 { 00296 long_str1.swap(short_str1); 00297 CPPUNIT_ASSERT((short_str1 == ref_long_str1) && (long_str1 == ref_short_str1)); 00298 long_str1.swap(short_str1); 00299 } 00300 00301 { 00302 string a(256, 'a'); 00303 string b(256, 'b'); 00304 const char* as = a.c_str(); 00305 const char* bs = b.c_str(); 00306 swap(a, b); 00307 CPPUNIT_ASSERT( a.c_str() == bs ); 00308 CPPUNIT_ASSERT( b.c_str() == as ); 00309 } 00310 00311 { 00312 //This is to test move constructor 00313 vector<string> str_vect; 00314 str_vect.push_back(short_str1); 00315 str_vect.push_back(long_str1); 00316 str_vect.push_back(short_str2); 00317 str_vect.push_back(long_str2); 00318 CPPUNIT_ASSERT((str_vect[0] == ref_short_str1) && 00319 (str_vect[1] == ref_long_str1) && 00320 (str_vect[2] == ref_short_str2) && 00321 (str_vect[3] == ref_long_str2)); 00322 } 00323 } 00324 00325 void StringTest::erase() 00326 { 00327 char const* c_str = "Hello, World!"; 00328 string str(c_str); 00329 CPPUNIT_ASSERT( str == c_str ); 00330 00331 str.erase(str.begin() + 1, str.end() - 1); // Erase all but first and last. 00332 00333 size_t i; 00334 for (i = 0; i < str.size(); ++i) { 00335 switch ( i ) { 00336 case 0: 00337 CPPUNIT_ASSERT( str[i] == 'H' ); 00338 break; 00339 case 1: 00340 CPPUNIT_ASSERT( str[i] == '!' ); 00341 break; 00342 default: 00343 CPPUNIT_FAIL; 00344 } 00345 } 00346 00347 str.insert(1, c_str); 00348 str.erase(str.begin()); // Erase first element. 00349 str.erase(str.end() - 1); // Erase last element. 00350 CPPUNIT_ASSERT( str == c_str ); 00351 str.clear(); // Erase all. 00352 CPPUNIT_ASSERT( str.empty() ); 00353 00354 str = c_str; 00355 CPPUNIT_ASSERT( str == c_str ); 00356 00357 str.erase(1, str.size() - 1); // Erase all but first and last. 00358 for (i = 0; i < str.size(); i++) { 00359 switch ( i ) { 00360 case 0: 00361 CPPUNIT_ASSERT( str[i] == 'H' ); 00362 break; 00363 case 1: 00364 CPPUNIT_ASSERT( str[i] == '!' ); 00365 break; 00366 default: 00367 CPPUNIT_FAIL; 00368 } 00369 } 00370 00371 str.erase(1); 00372 CPPUNIT_ASSERT( str == "H" ); 00373 } 00374 00375 void StringTest::data() 00376 { 00377 string xx; 00378 00379 CPPUNIT_ASSERT( xx.data() != 0 ); // ISO-IEC-14882:1998(E), 21.3.6, paragraph 3 00380 #if 0 00381 /* This test really not required: in ISO-IEC-14882:1998(E) paragraph 3 stated: 00382 * '... and can have zero added to it', again: 'CAN', but not 'MUST'. 00383 * That's why I am comment this test. But I don't remove it due to I had 00384 * unevident problem with misinterpretation of data() return (i.e. data() 00385 * and c_str() provide different functionality!) and expect that this is 00386 * more-or-less common pitfall. 00387 * - ptr 00388 */ 00389 string low( "2004-01-01" ); 00390 // Blocks A and B should follow each other. 00391 // Block A: 00392 xx = "123456"; 00393 xx += low; 00394 if ( strcmp( xx.data(), "1234562004-01-01" ) != 0 ) { 00395 return -1; 00396 } 00397 // End of block A 00398 00399 // Block B: 00400 xx = "1234"; 00401 xx += ";"; 00402 00403 if ( strcmp( xx.data(), "1234;" ) != 0 ) { 00404 return -1; 00405 } 00406 // End of block B 00407 #endif 00408 } 00409 00410 void StringTest::c_str() 00411 { 00412 string low( "2004-01-01" ); 00413 string xx; 00414 string yy; 00415 00416 CPPUNIT_ASSERT( *(yy.c_str()) == '\0' ); // ISO-IEC-14882:1998(E), 21.3.6, paragraph 1 00417 00418 // Blocks A and B should follow each other. 00419 // Block A: 00420 xx = "123456"; 00421 xx += low; 00422 CPPUNIT_ASSERT( strcmp( xx.c_str(), "1234562004-01-01" ) == 0 ); 00423 // End of block A 00424 00425 // Block B: 00426 xx = "1234"; 00427 xx += ";"; 00428 CPPUNIT_ASSERT( strcmp( xx.c_str(), "1234;" ) == 0 ); 00429 // End of block B 00430 } 00431 00432 void StringTest::null_char() 00433 { 00434 // ISO/IEC 14882:1998(E), ISO/IEC 14882:2003(E), 21.3.4 ('... the const version') 00435 const string s( "123456" ); 00436 00437 CPPUNIT_CHECK( s[s.size()] == '\0' ); 00438 00439 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 00440 try { 00441 //Check is only here to avoid warning about value of expression not used 00442 CPPUNIT_CHECK( s.at(s.size()) == '\0' ); 00443 CPPUNIT_FAIL; 00444 } 00445 catch (out_of_range const&) { 00446 CPPUNIT_ASSERT( true ); 00447 } 00448 catch ( ... ) { 00449 CPPUNIT_FAIL; 00450 } 00451 #endif 00452 } 00453 00454 void StringTest::insert() 00455 { 00456 string strorg = "This is test string for string calls"; 00457 string str; 00458 /* 00459 * In case of reallocation there is no auto reference problem 00460 * so we reserve a big enough string to be sure to test this 00461 * particular point. 00462 */ 00463 str.reserve(100); 00464 str = strorg; 00465 00466 //test self insertion: 00467 str.insert(10, str.c_str() + 5, 15); 00468 CPPUNIT_ASSERT( str == "This is teis test string st string for string calls" ); 00469 00470 str = strorg; 00471 str.insert(15, str.c_str() + 5, 25); 00472 CPPUNIT_ASSERT( str == "This is test stis test string for stringring for string calls" ); 00473 00474 str = strorg; 00475 str.insert(0, str.c_str() + str.size() - 4, 4); 00476 CPPUNIT_ASSERT( str == "allsThis is test string for string calls" ); 00477 00478 str = strorg; 00479 str.insert(0, str.c_str() + str.size() / 2 - 1, str.size() / 2 + 1); 00480 CPPUNIT_ASSERT( str == "ng for string callsThis is test string for string calls" ); 00481 00482 str = strorg; 00483 string::iterator b = str.begin(); 00484 string::const_iterator s = str.begin() + str.size() / 2 - 1; 00485 string::const_iterator e = str.end(); 00486 str.insert( b, s, e ); 00487 CPPUNIT_ASSERT( str == "ng for string callsThis is test string for string calls" ); 00488 00489 str = strorg; 00490 str.insert(str.begin(), str.begin() + str.size() / 2 - 1, str.end()); 00491 CPPUNIT_ASSERT( str == "ng for string callsThis is test string for string calls" ); 00492 00493 #ifdef _STLP_MEMBER_TEMPLATES 00494 vector<int> int_vect; 00495 //Just a compile time test: 00496 str.insert(str.end(), int_vect.begin(), int_vect.end()); 00497 #endif 00498 00499 string str0; 00500 str0.insert(str0.begin(), 5, '0'); 00501 CPPUNIT_ASSERT( str0 == "00000" ); 00502 00503 string str1; 00504 { 00505 string::size_type pos = 0, nb = 2; 00506 str1.insert(pos, nb, '1'); 00507 } 00508 CPPUNIT_ASSERT( str1 == "11" ); 00509 00510 str0.insert(0, str1); 00511 CPPUNIT_ASSERT( str0 == "1100000" ); 00512 00513 string str2("2345"); 00514 str0.insert(str0.size(), str2, 1, 2); 00515 CPPUNIT_ASSERT( str0 == "110000034" ); 00516 00517 str1.insert(str1.begin() + 1, 2, '2'); 00518 CPPUNIT_ASSERT( str1 == "1221" ); 00519 00520 str1.insert(2, "333333", 3); 00521 CPPUNIT_ASSERT( str1 == "1233321" ); 00522 00523 str1.insert(4, "4444"); 00524 CPPUNIT_ASSERT( str1 == "12334444321" ); 00525 00526 str1.insert(str1.begin() + 6, '5'); 00527 CPPUNIT_ASSERT( str1 == "123344544321" ); 00528 } 00529 00530 void StringTest::replace() 00531 { 00532 /* 00533 * This test case is for the non template basic_string::replace method, 00534 * this is why we play with the const iterators and reference to guaranty 00535 * that the right method is called. 00536 */ 00537 const string v( "78" ); 00538 string s( "123456" ); 00539 string const& cs = s; 00540 00541 string::iterator i = s.begin() + 1; 00542 s.replace(i, i + 3, v.begin(), v.end()); 00543 CPPUNIT_ASSERT( s == "17856" ); 00544 00545 s = "123456"; 00546 i = s.begin() + 1; 00547 s.replace(i, i + 1, v.begin(), v.end()); 00548 CPPUNIT_ASSERT( s == "1783456" ); 00549 00550 s = "123456"; 00551 i = s.begin() + 1; 00552 string::const_iterator ci = s.begin() + 1; 00553 s.replace(i, i + 3, ci + 3, cs.end()); 00554 CPPUNIT_ASSERT( s == "15656" ); 00555 00556 s = "123456"; 00557 i = s.begin() + 1; 00558 ci = s.begin() + 1; 00559 s.replace(i, i + 3, ci, ci + 2); 00560 CPPUNIT_ASSERT( s == "12356" ); 00561 00562 s = "123456"; 00563 i = s.begin() + 1; 00564 ci = s.begin() + 1; 00565 s.replace(i, i + 3, ci + 1, cs.end()); 00566 CPPUNIT_ASSERT( s == "1345656" ); 00567 00568 s = "123456"; 00569 i = s.begin(); 00570 ci = s.begin() + 1; 00571 s.replace(i, i, ci, ci + 1); 00572 CPPUNIT_CHECK( s == "2123456" ); 00573 00574 s = "123456"; 00575 s.replace(s.begin() + 4, s.end(), cs.begin(), cs.end()); 00576 CPPUNIT_ASSERT( s == "1234123456" ); 00577 00578 /* 00579 * This is the test for the template replace method. 00580 */ 00581 s = "123456"; 00582 string::iterator b = s.begin() + 4; 00583 string::iterator e = s.end(); 00584 string::const_iterator rb = s.begin(); 00585 string::const_iterator re = s.end(); 00586 s.replace(b, e, rb, re); 00587 CPPUNIT_ASSERT( s == "1234123456" ); 00588 00589 s = "123456"; 00590 s.replace(s.begin() + 4, s.end(), s.begin(), s.end()); 00591 CPPUNIT_ASSERT( s == "1234123456" ); 00592 00593 string strorg("This is test string for string calls"); 00594 string str = strorg; 00595 str.replace(5, 15, str.c_str(), 10); 00596 CPPUNIT_ASSERT( str == "This This is tefor string calls" ); 00597 00598 str = strorg; 00599 str.replace(5, 5, str.c_str(), 10); 00600 CPPUNIT_ASSERT( str == "This This is test string for string calls" ); 00601 00602 #if (defined (STLPORT) && defined(_STLP_MEMBER_TEMPLATES)) || ( !defined (STLPORT) && !defined(__GNUC__) ) 00603 deque<char> cdeque; 00604 cdeque.push_back('I'); 00605 str.replace(str.begin(), str.begin() + 11, cdeque.begin(), cdeque.end()); 00606 CPPUNIT_ASSERT( str == "Is test string for string calls" ); 00607 #endif 00608 } 00609 00610 void StringTest::resize() 00611 { 00612 string s; 00613 00614 s.resize(0); 00615 00616 CPPUNIT_ASSERT( *s.c_str() == 0 ); 00617 00618 s = "1234567"; 00619 00620 s.resize(0); 00621 CPPUNIT_ASSERT( *s.c_str() == 0 ); 00622 00623 s = "1234567"; 00624 s.resize(1); 00625 CPPUNIT_ASSERT( s.size() == 1 ); 00626 CPPUNIT_ASSERT( *s.c_str() == '1' ); 00627 CPPUNIT_ASSERT( *(s.c_str() + 1) == 0 ); 00628 00629 s = "1234567"; 00630 s.resize(10); 00631 CPPUNIT_ASSERT( s.size() == 10 ); 00632 CPPUNIT_ASSERT( s[6] == '7' ); 00633 CPPUNIT_ASSERT( s[7] == 0 ); 00634 CPPUNIT_ASSERT( s[8] == 0 ); 00635 CPPUNIT_ASSERT( s[9] == 0 ); 00636 } 00637 00638 void StringTest::find() 00639 { 00640 string s("one two three one two three"); 00641 CPPUNIT_ASSERT( s.find("one") == 0 ); 00642 CPPUNIT_ASSERT( s.find('t') == 4 ); 00643 CPPUNIT_ASSERT( s.find('t', 5) == 8 ); 00644 //We are trying to get a const reference to the npos string static member to 00645 //force the compiler to allocate memory for this variable. It is used to reveal 00646 //a bug of STLport which was simply declaring npos without instanciating it. 00647 #if defined (STLPORT) && defined (_STLP_STATIC_CONST_INIT_BUG) 00648 string::size_type const& npos_local = string::npos; 00649 #else 00650 # define npos_local string::npos 00651 #endif 00652 CPPUNIT_ASSERT( s.find("four") == npos_local ); 00653 CPPUNIT_ASSERT( s.find("one", string::npos) == npos_local ); 00654 00655 CPPUNIT_ASSERT( s.find_first_of("abcde") == 2 ); 00656 00657 CPPUNIT_ASSERT( s.find_first_not_of("enotw ") == 9 ); 00658 00659 string empty; 00660 CPPUNIT_ASSERT( s.substr(s.find(empty), empty.size()) == empty ); 00661 } 00662 00663 void StringTest::bogus_edge_find() 00664 { 00665 /* ISO/IEC 14882 2003, 21.3.6.1 basic_string::find [lib.string::find] 00666 * 00667 * size_type find(const basic_string<charT,traits,Allocator>& str, 00668 * size_type pos = 0) const; 00669 * Effects: Determines the lowest position xpos, if possible, such that 00670 * both of the following conditions obtain: 00671 * pos <= xpos and xpos + str.size() <= size(); 00672 * at(xpos+I) == str.at(I) for all elements I of the string controlled by str. 00673 * Returns: xpos if the function can determine such a value for xpos. Otherwise, 00674 * returns npos. 00675 * Notes: Uses traits::eq(). 00676 * 00677 * === 00678 * So, from formal point of view 00679 * string s; string::size_type p = s.find( "", 0, 0 ); 00680 * should return 0 in p, i.e. position out-of-bound of string, so 00681 * code like following is bad: 00682 * string s; 00683 * 00684 * string::size_type p = s.find( "", 0, 0 ); 00685 * 00686 * ... 00687 * 00688 * if ( p != string::npos ) { // normal 00689 * char ch = s[p]; // Arghhhhhhhhhh 00690 * } 00691 * 00692 * People near Standard commete has opinion opposite to my. Even if it looks 00693 * like bogus behaviour for me, it should be fixed. 00694 */ 00695 00696 { 00697 string s; 00698 string::size_type p = s.find( "", 0, 0 ); 00699 00700 /* CPPUNIT_CHECK( p == string::npos ); */ 00701 CPPUNIT_CHECK( p == 0 ); // bogus result, isn't it? 00702 } 00703 { 00704 string s( "123" ); 00705 string::size_type p = s.find( "", 0, 0 ); 00706 00707 CPPUNIT_CHECK( p == 0 ); 00708 } 00709 { 00710 string s( "123" ); 00711 string::size_type p = s.find( "", 1, 0 ); 00712 00713 CPPUNIT_CHECK( p == 1 ); 00714 } 00715 { 00716 string s( "" ); 00717 string::size_type p = s.find( "", 1, 0 ); 00718 00719 CPPUNIT_CHECK( p == string::npos ); 00720 } 00721 { 00722 string s( "123" ); 00723 string::size_type p = s.find( "", 3, 0 ); 00724 00725 CPPUNIT_CHECK( p == 3 ); // bogus result, isn't it? 00726 } 00727 { 00728 string s; 00729 string::size_type p = s.rfind( "", 0, 0 ); 00730 00731 /* CPPUNIT_CHECK( p == string::npos ); */ 00732 CPPUNIT_CHECK( p == 0 ); // bogus result, isn't it? 00733 } 00734 { 00735 string s( "123" ); 00736 string::size_type p = s.rfind( "", 0, 0 ); 00737 00738 CPPUNIT_CHECK( p == 0 ); 00739 } 00740 { 00741 string s( "123" ); 00742 string::size_type p = s.rfind( "", 1, 0 ); 00743 00744 CPPUNIT_CHECK( p == 1 ); 00745 } 00746 { 00747 string s( "" ); 00748 string::size_type p = s.rfind( "", 1, 0 ); 00749 00750 CPPUNIT_CHECK( p == 0 ); // bogus result, isn't it? 00751 } 00752 { 00753 string s( "123" ); 00754 string::size_type p = s.rfind( "", 3, 0 ); 00755 00756 CPPUNIT_CHECK( p == 3 ); // bogus result, isn't it? 00757 } 00758 } 00759 00760 void StringTest::rfind() 00761 { 00762 // 21.3.6.2 00763 string s("one two three one two three"); 00764 00765 CPPUNIT_ASSERT( s.rfind("two") == 18 ); 00766 CPPUNIT_ASSERT( s.rfind("two", 0) == string::npos ); 00767 CPPUNIT_ASSERT( s.rfind("two", 11) == 4 ); 00768 CPPUNIT_ASSERT( s.rfind('w') == 19 ); 00769 00770 string test( "aba" ); 00771 00772 CPPUNIT_CHECK( test.rfind( "a", 2, 1 ) == 2 ); 00773 CPPUNIT_CHECK( test.rfind( "a", 1, 1 ) == 0 ); 00774 CPPUNIT_CHECK( test.rfind( "a", 0, 1 ) == 0 ); 00775 00776 CPPUNIT_CHECK( test.rfind( 'a', 2 ) == 2 ); 00777 CPPUNIT_CHECK( test.rfind( 'a', 1 ) == 0 ); 00778 CPPUNIT_CHECK( test.rfind( 'a', 0 ) == 0 ); 00779 } 00780 00781 void StringTest::find_last_of() 00782 { 00783 // 21.3.6.4 00784 string s("one two three one two three"); 00785 00786 CPPUNIT_ASSERT( s.find_last_of("abcde") == 26 ); 00787 00788 string test( "aba" ); 00789 00790 CPPUNIT_CHECK( test.find_last_of( "a", 2, 1 ) == 2 ); 00791 CPPUNIT_CHECK( test.find_last_of( "a", 1, 1 ) == 0 ); 00792 CPPUNIT_CHECK( test.find_last_of( "a", 0, 1 ) == 0 ); 00793 00794 CPPUNIT_CHECK( test.find_last_of( 'a', 2 ) == 2 ); 00795 CPPUNIT_CHECK( test.find_last_of( 'a', 1 ) == 0 ); 00796 CPPUNIT_CHECK( test.find_last_of( 'a', 0 ) == 0 ); 00797 } 00798 00799 void StringTest::find_last_not_of() 00800 { 00801 // 21.3.6.6 00802 string s("one two three one two three"); 00803 00804 CPPUNIT_ASSERT( s.find_last_not_of("ehortw ") == 15 ); 00805 00806 string test( "aba" ); 00807 00808 CPPUNIT_CHECK( test.find_last_not_of( "a", 2, 1 ) == 1 ); 00809 CPPUNIT_CHECK( test.find_last_not_of( "b", 2, 1 ) == 2 ); 00810 CPPUNIT_CHECK( test.find_last_not_of( "a", 1, 1 ) == 1 ); 00811 CPPUNIT_CHECK( test.find_last_not_of( "b", 1, 1 ) == 0 ); 00812 CPPUNIT_CHECK( test.find_last_not_of( "a", 0, 1 ) == string::npos ); 00813 CPPUNIT_CHECK( test.find_last_not_of( "b", 0, 1 ) == 0 ); 00814 00815 CPPUNIT_CHECK( test.find_last_not_of( 'a', 2 ) == 1 ); 00816 CPPUNIT_CHECK( test.find_last_not_of( 'b', 2 ) == 2 ); 00817 CPPUNIT_CHECK( test.find_last_not_of( 'a', 1 ) == 1 ); 00818 CPPUNIT_CHECK( test.find_last_not_of( 'b', 1 ) == 0 ); 00819 CPPUNIT_CHECK( test.find_last_not_of( 'a', 0 ) == string::npos ); 00820 CPPUNIT_CHECK( test.find_last_not_of( 'b', 0 ) == 0 ); 00821 } 00822 00823 void StringTest::copy() 00824 { 00825 string s("foo"); 00826 char dest[4]; 00827 dest[0] = dest[1] = dest[2] = dest[3] = 1; 00828 s.copy(dest, 4); 00829 int pos = 0; 00830 CPPUNIT_ASSERT( dest[pos++] == 'f' ); 00831 CPPUNIT_ASSERT( dest[pos++] == 'o' ); 00832 CPPUNIT_ASSERT( dest[pos++] == 'o' ); 00833 CPPUNIT_ASSERT( dest[pos++] == 1 ); 00834 00835 dest[0] = dest[1] = dest[2] = dest[3] = 1; 00836 s.copy(dest, 4, 2); 00837 pos = 0; 00838 CPPUNIT_ASSERT( dest[pos++] == 'o' ); 00839 CPPUNIT_ASSERT( dest[pos++] == 1 ); 00840 00841 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 00842 try { 00843 s.copy(dest, 4, 5); 00844 CPPUNIT_FAIL; 00845 } 00846 catch (out_of_range const&) { 00847 } 00848 catch ( ... ) { 00849 CPPUNIT_FAIL; 00850 } 00851 #endif 00852 } 00853 00854 void StringTest::assign() 00855 { 00856 string s; 00857 char const* cstr = "test string for assign"; 00858 00859 s.assign(cstr, cstr + 22); 00860 CPPUNIT_ASSERT( s == "test string for assign" ); 00861 00862 string s2("other test string"); 00863 s.assign(s2); 00864 CPPUNIT_ASSERT( s == s2 ); 00865 00866 static string str1; 00867 static string str2; 00868 00869 // short string optim: 00870 str1 = "123456"; 00871 // longer than short string: 00872 str2 = "1234567890123456789012345678901234567890"; 00873 00874 CPPUNIT_ASSERT(str1[5] == '6'); 00875 CPPUNIT_ASSERT(str2[29] == '0'); 00876 } 00877 00878 /* This test is to check if string properly supports the short string 00879 * optimization. It has been found out that eMbedded Visual C++ 3.0 and .NET 00880 * compilers for the ARM platform fail to pass structs and classes of certain 00881 * size per value. This seems to be a known compiler bug. For other processors 00882 * (e.g. x86) the error doesn't occur. 00883 * (The ARM compiler creates a temporary object from teststr on the stack, to 00884 * pass it to the helper function. It uses the copy constructor for this. 00885 * After this the temporary object is copied to another place on the stack. 00886 * The result is that the _M_finish pointer then points to the wrong buffer 00887 * end and the size of the short string is incorrectly calculated.) 00888 */ 00889 void StringTest::short_string_optim_bug() 00890 { 00891 string teststr("shortest"); 00892 00893 bool short_string_optim_bug_helper(string teststr); 00894 00895 CPPUNIT_ASSERT(true == short_string_optim_bug_helper(teststr)); 00896 } 00897 00898 bool short_string_optim_bug_helper(string teststr) 00899 { 00900 size_t ss = teststr.size(); 00901 return (ss == 8); 00902 } 00903 00904 void StringTest::compare() 00905 { 00906 string str1("abcdef"); 00907 string str2; 00908 00909 str2 = "abcdef"; 00910 CPPUNIT_ASSERT( str1.compare(str2) == 0 ); 00911 str2 = "abcde"; 00912 CPPUNIT_ASSERT( str1.compare(str2) > 0 ); 00913 str2 = "abcdefg"; 00914 CPPUNIT_ASSERT( str1.compare(str2) < 0 ); 00915 00916 CPPUNIT_ASSERT( str1.compare("abcdef") == 0 ); 00917 CPPUNIT_ASSERT( str1.compare("abcde") > 0 ); 00918 CPPUNIT_ASSERT( str1.compare("abcdefg") < 0 ); 00919 00920 str2 = "cde"; 00921 CPPUNIT_ASSERT( str1.compare(2, 3, str2) == 0 ); 00922 str2 = "cd"; 00923 CPPUNIT_ASSERT( str1.compare(2, 3, str2) > 0 ); 00924 str2 = "cdef"; 00925 CPPUNIT_ASSERT( str1.compare(2, 3, str2) < 0 ); 00926 00927 str2 = "abcdef"; 00928 CPPUNIT_ASSERT( str1.compare(2, 3, str2, 2, 3) == 0 ); 00929 CPPUNIT_ASSERT( str1.compare(2, 3, str2, 2, 2) > 0 ); 00930 CPPUNIT_ASSERT( str1.compare(2, 3, str2, 2, 4) < 0 ); 00931 00932 CPPUNIT_ASSERT( str1.compare(2, 3, "cdefgh", 3) == 0 ); 00933 CPPUNIT_ASSERT( str1.compare(2, 3, "cdefgh", 2) > 0 ); 00934 CPPUNIT_ASSERT( str1.compare(2, 3, "cdefgh", 4) < 0 ); 00935 } 00936 00937 /* 00938 class mystring : public string { 00939 public: 00940 mystring() {} 00941 mystring(string const& s) : string(s) {} 00942 00943 mystring& operator = (string const& s) { 00944 string::operator = (s); 00945 return *this; 00946 }; 00947 }; 00948 */ 00949 00950 void StringTest::template_expression() 00951 { 00952 string one("one"), two("two"), three("three"); 00953 string space(1, ' '); 00954 00955 // check availability of [un]equality operators 00956 { 00957 // string-string 00958 one == two; 00959 one != two; 00960 // string-literal 00961 one == "two"; 00962 one != "two"; 00963 // literal-string 00964 "one" == two; 00965 "one" != two; 00966 // strsum-string 00967 (one + two) == three; 00968 (one + two) != three; 00969 // string-strsum 00970 one == (two + three); 00971 one != (two + three); 00972 // strsum-literal 00973 (one + two) == "three"; 00974 (one + two) != "three"; 00975 // literal-strsum 00976 "one" == (two + three); 00977 "one" != (two + three); 00978 // strsum-strsum 00979 (one + two) == (two + three); 00980 (one + two) != (two + three); 00981 } 00982 00983 { 00984 string result(one + ' ' + two + ' ' + three); 00985 CPPUNIT_CHECK( result == "one two three" ); 00986 } 00987 00988 { 00989 string result(one + ' ' + two + ' ' + three, 4); 00990 CPPUNIT_CHECK( result == "two three" ); 00991 } 00992 00993 { 00994 string result(one + ' ' + two + ' ' + three, 4, 3); 00995 CPPUNIT_CHECK( result == "two" ); 00996 } 00997 00998 //2 members expressions: 00999 CPPUNIT_CHECK( (' ' + one) == " one" ); 01000 CPPUNIT_CHECK( (one + ' ') == "one " ); 01001 CPPUNIT_CHECK( (one + " two") == "one two" ); 01002 CPPUNIT_CHECK( ("one " + two) == "one two" ); 01003 CPPUNIT_CHECK( (one + space) == "one " ); 01004 01005 //3 members expressions: 01006 CPPUNIT_CHECK( ((one + space) + "two") == "one two" ); 01007 CPPUNIT_CHECK( ("one" + (space + two)) == "one two" ); 01008 CPPUNIT_CHECK( ((one + space) + two) == "one two" ); 01009 CPPUNIT_CHECK( (one + (space + two)) == "one two" ); 01010 CPPUNIT_CHECK( ((one + space) + 't') == "one t" ); 01011 CPPUNIT_CHECK( ('o' + (space + two)) == "o two" ); 01012 01013 //4 members expressions: 01014 CPPUNIT_CHECK( ((one + space) + (two + space)) == "one two " ); 01015 01016 //special operators 01017 { 01018 string result; 01019 result = one + space + two; 01020 CPPUNIT_CHECK( result == "one two" ); 01021 01022 result += space + three; 01023 CPPUNIT_CHECK( result == "one two three" ); 01024 } 01025 01026 //special append method 01027 { 01028 string result; 01029 //Use reserve to avoid reallocation and really test auto-referencing problems: 01030 result.reserve(64); 01031 01032 result.append(one + space + two); 01033 CPPUNIT_CHECK( result == "one two" ); 01034 01035 result.append(space + result + space + three); 01036 CPPUNIT_CHECK( result == "one two one two three" ); 01037 01038 result = "one two"; 01039 result.append(space + three, 1, 2); 01040 CPPUNIT_ASSERT( result == "one twoth" ); 01041 01042 result.append(space + result); 01043 CPPUNIT_CHECK( result == "one twoth one twoth" ); 01044 } 01045 01046 //special assign method 01047 { 01048 string result; 01049 //Use reserve to avoid reallocation and really test auto-referencing problems: 01050 result.reserve(64); 01051 01052 result.assign(one + space + two + space + three); 01053 CPPUNIT_CHECK( result == "one two three" ); 01054 01055 result.assign(one + space + two + space + three, 3, 5); 01056 CPPUNIT_CHECK( result == " two " ); 01057 01058 result.assign(one + result + three); 01059 CPPUNIT_CHECK( result == "one two three" ); 01060 } 01061 01062 { 01063 CPPUNIT_CHECK( !(one + ' ' + two).empty() ); 01064 01065 char result = (one + ' ' + two)[3]; 01066 CPPUNIT_CHECK( result == ' ' ); 01067 01068 result = (one + ' ' + two).at(3); 01069 CPPUNIT_CHECK( result == ' ' ); 01070 01071 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 01072 try { 01073 result = (one + ' ' + two).at(10); 01074 CPPUNIT_FAIL; 01075 } 01076 catch (out_of_range const&) { 01077 CPPUNIT_ASSERT( result == ' ' ); 01078 } 01079 catch (...) { 01080 CPPUNIT_FAIL; 01081 } 01082 #endif 01083 } 01084 01085 /* 01086 mystring a("ing"); 01087 //gcc failed to compile following expression when template expressions are activated. 01088 //MSVC sees no problem. gcc limitation or MSVC is too cool ?? 01089 mystring b = "str" + a; 01090 */ 01091 } 01092 01093 #if !defined (TE_TMP_TEST_IGNORED) 01094 class superstring 01095 { 01096 public: 01097 superstring() : 01098 s("super") 01099 {} 01100 01101 superstring( const string& str ) : 01102 s( str ) 01103 {} 01104 01105 superstring operator / (const string& str ) 01106 { return superstring( s + "/" + str ); } 01107 01108 superstring operator / (const char* str ) 01109 { return superstring( s + "/" + str ); } 01110 01111 private: 01112 string s; 01113 }; 01114 #endif 01115 01116 void StringTest::te_tmp() 01117 { 01118 #if !defined (TE_TMP_TEST_IGNORED) 01119 superstring s; 01120 string more( "more" ); 01121 string less( "less" ); 01122 01123 superstring r = s / (more + less); 01124 #endif 01125 } 01126 01127 class mypath 01128 { 01129 public: 01130 mypath( const string& s ) : 01131 p( s ) 01132 { } 01133 01134 const mypath& operator / ( const string& ); 01135 const string& str() const 01136 { return p; } 01137 01138 private: 01139 string p; 01140 }; 01141 01142 const mypath& mypath::operator /( const string& s ) 01143 { 01144 p += '/'; 01145 p += s; 01146 return *this; 01147 } 01148 01149 void StringTest::oper_tmp() 01150 { 01151 string s1( "path1" ); 01152 string s2( ".ext" ); 01153 01154 string& rs1 = s1; 01155 string& rs2 = s2; 01156 01157 CPPUNIT_CHECK( (mypath( string( "/root" ) ) / (rs1 + rs2)).str() == "/root/path1.ext" ); 01158 } 01159 01160 void StringTest::template_wexpression() 01161 { 01162 #if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T) 01163 # if !defined (__CYGWIN__) || defined (STLPORT) 01164 wstring one(L"one"), two(L"two"), three(L"three"); 01165 wstring space(L" "); 01166 01167 { 01168 wstring result(one + L' ' + two + L' ' + three); 01169 CPPUNIT_CHECK( result == L"one two three" ); 01170 } 01171 01172 { 01173 wstring result(one + L' ' + two + L' ' + three, 4); 01174 CPPUNIT_CHECK( result == L"two three" ); 01175 } 01176 01177 { 01178 wstring result(one + L' ' + two + L' ' + three, 4, 3); 01179 CPPUNIT_CHECK( result == L"two" ); 01180 } 01181 01182 //2 members expressions: 01183 CPPUNIT_CHECK( (L' ' + one) == L" one" ); 01184 CPPUNIT_CHECK( (one + L' ') == L"one " ); 01185 CPPUNIT_CHECK( (one + L" two") == L"one two" ); 01186 CPPUNIT_CHECK( (L"one " + two) == L"one two" ); 01187 CPPUNIT_CHECK( (one + space) == L"one " ); 01188 01189 //3 members expressions: 01190 CPPUNIT_CHECK( ((one + space) + L"two") == L"one two" ); 01191 CPPUNIT_CHECK( (L"one" + (space + two)) == L"one two" ); 01192 CPPUNIT_CHECK( ((one + space) + two) == L"one two" ); 01193 CPPUNIT_CHECK( (one + (space + two)) == L"one two" ); 01194 CPPUNIT_CHECK( ((one + space) + L't') == L"one t" ); 01195 CPPUNIT_CHECK( (L'o' + (space + two)) == L"o two" ); 01196 01197 //4 members expressions: 01198 CPPUNIT_CHECK( ((one + space) + (two + space)) == L"one two " ); 01199 01200 //special operators 01201 { 01202 wstring result; 01203 result = one + space + two; 01204 CPPUNIT_CHECK( result == L"one two" ); 01205 01206 result += space + three; 01207 CPPUNIT_CHECK( result == L"one two three" ); 01208 } 01209 01210 //special append method 01211 { 01212 wstring result; 01213 //Use reserve to avoid reallocation and really test auto-referencing problems: 01214 result.reserve(64); 01215 01216 result.append(one + space + two); 01217 CPPUNIT_CHECK( result == L"one two" ); 01218 01219 result.append(space + result + space + three); 01220 CPPUNIT_CHECK( result == L"one two one two three" ); 01221 01222 result = L"one two"; 01223 result.append(space + three, 1, 2); 01224 CPPUNIT_ASSERT( result == L"one twoth" ); 01225 01226 result.append(space + result); 01227 CPPUNIT_CHECK( result == L"one twoth one twoth" ); 01228 } 01229 01230 //special assign method 01231 { 01232 wstring result; 01233 //Use reserve to avoid reallocation and really test auto-referencing problems: 01234 result.reserve(64); 01235 01236 result.assign(one + space + two + space + three); 01237 CPPUNIT_CHECK( result == L"one two three" ); 01238 01239 result.assign(one + space + two + space + three, 3, 5); 01240 CPPUNIT_CHECK( result == L" two " ); 01241 01242 result.assign(one + result + three); 01243 CPPUNIT_CHECK( result == L"one two three" ); 01244 } 01245 01246 { 01247 CPPUNIT_CHECK( !(one + L' ' + two).empty() ); 01248 01249 wchar_t result = (one + L' ' + two)[3]; 01250 CPPUNIT_CHECK( result == L' ' ); 01251 01252 result = (one + L' ' + two).at(3); 01253 CPPUNIT_CHECK( result == L' ' ); 01254 01255 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 01256 try { 01257 result = (one + L' ' + two).at(10); 01258 CPPUNIT_FAIL; 01259 } 01260 catch (out_of_range const&) { 01261 CPPUNIT_ASSERT( result == L' ' ); 01262 } 01263 catch (...) { 01264 CPPUNIT_FAIL; 01265 } 01266 # endif 01267 } 01268 # endif 01269 #endif 01270 } 01271 01272 void StringTest::io() 01273 { 01274 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS) 01275 string str("STLport"); 01276 { 01277 ostringstream ostr; 01278 ostr << str; 01279 CPPUNIT_ASSERT( ostr.good() ); 01280 CPPUNIT_ASSERT( ostr.str() == str ); 01281 } 01282 { 01283 istringstream istr(str); 01284 string istr_content; 01285 istr >> istr_content; 01286 CPPUNIT_ASSERT( !istr.fail() && istr.eof() ); 01287 CPPUNIT_ASSERT( istr_content == str ); 01288 } 01289 { 01290 istringstream istr(str); 01291 istr.width(3); 01292 string istr_content; 01293 istr >> istr_content; 01294 CPPUNIT_ASSERT( !istr.fail() && !istr.eof() ); 01295 CPPUNIT_ASSERT( istr_content == "STL" ); 01296 } 01297 #endif 01298 } 01299 01300 void StringTest::allocator_with_state() 01301 { 01302 #if !(defined (STLPORT) && defined (_STLP_NO_CUSTOM_IO)) 01303 01304 char buf1[1024]; 01305 StackAllocator<char> stack1(buf1, buf1 + sizeof(buf1)); 01306 01307 char buf2[1024]; 01308 StackAllocator<char> stack2(buf2, buf2 + sizeof(buf2)); 01309 01310 typedef basic_string<char, char_traits<char>, StackAllocator<char> > StackString; 01311 { 01312 StackString str1("string stack1", stack1); 01313 StackString str1Cpy(str1); 01314 01315 StackString str2("string stack2", stack2); 01316 StackString str2Cpy(str2); 01317 01318 str1.swap(str2); 01319 01320 CPPUNIT_ASSERT( str1.get_allocator().swaped() ); 01321 CPPUNIT_ASSERT( str2.get_allocator().swaped() ); 01322 01323 CPPUNIT_ASSERT( str1 == str2Cpy ); 01324 CPPUNIT_ASSERT( str2 == str1Cpy ); 01325 CPPUNIT_ASSERT( str1.get_allocator() == stack2 ); 01326 CPPUNIT_ASSERT( str2.get_allocator() == stack1 ); 01327 } 01328 CPPUNIT_ASSERT( stack1.ok() ); 01329 CPPUNIT_ASSERT( stack2.ok() ); 01330 stack1.reset(); stack2.reset(); 01331 01332 { 01333 StackString str1("longer string from stack1 allocator instance for dynamic allocation", stack1); 01334 StackString str1Cpy(str1); 01335 01336 StackString str2("longer string from stack2 allocator instance for dynamic allocation", stack2); 01337 StackString str2Cpy(str2); 01338 01339 str1.swap(str2); 01340 01341 CPPUNIT_ASSERT( str1.get_allocator().swaped() ); 01342 CPPUNIT_ASSERT( str2.get_allocator().swaped() ); 01343 01344 CPPUNIT_ASSERT( str1 == str2Cpy ); 01345 CPPUNIT_ASSERT( str2 == str1Cpy ); 01346 CPPUNIT_ASSERT( str1.get_allocator() == stack2 ); 01347 CPPUNIT_ASSERT( str2.get_allocator() == stack1 ); 01348 } 01349 CPPUNIT_ASSERT( stack1.ok() ); 01350 CPPUNIT_ASSERT( stack2.ok() ); 01351 stack1.reset(); stack2.reset(); 01352 01353 01354 { 01355 StackString str1("string stack1", stack1); 01356 StackString str1Cpy(str1); 01357 01358 StackString str2("longer string from stack2 allocator instance for dynamic allocation", stack2); 01359 StackString str2Cpy(str2); 01360 01361 str1.swap(str2); 01362 01363 CPPUNIT_ASSERT( str1.get_allocator().swaped() ); 01364 CPPUNIT_ASSERT( str2.get_allocator().swaped() ); 01365 01366 CPPUNIT_ASSERT( str1 == str2Cpy ); 01367 CPPUNIT_ASSERT( str2 == str1Cpy ); 01368 CPPUNIT_ASSERT( str1.get_allocator() == stack2 ); 01369 CPPUNIT_ASSERT( str2.get_allocator() == stack1 ); 01370 } 01371 CPPUNIT_ASSERT( stack1.ok() ); 01372 CPPUNIT_ASSERT( stack2.ok() ); 01373 stack1.reset(); stack2.reset(); 01374 01375 01376 { 01377 StackString str1("longer string from stack1 allocator instance for dynamic allocation", stack1); 01378 StackString str1Cpy(str1); 01379 01380 StackString str2("string stack2", stack2); 01381 StackString str2Cpy(str2); 01382 01383 str1.swap(str2); 01384 01385 CPPUNIT_ASSERT( str1.get_allocator().swaped() ); 01386 CPPUNIT_ASSERT( str2.get_allocator().swaped() ); 01387 01388 CPPUNIT_ASSERT( str1 == str2Cpy ); 01389 CPPUNIT_ASSERT( str2 == str1Cpy ); 01390 CPPUNIT_ASSERT( str1.get_allocator() == stack2 ); 01391 CPPUNIT_ASSERT( str2.get_allocator() == stack1 ); 01392 } 01393 CPPUNIT_ASSERT( stack1.ok() ); 01394 CPPUNIT_ASSERT( stack2.ok() ); 01395 stack1.reset(); stack2.reset(); 01396 #endif 01397 } 01398 01399 void StringTest::capacity() 01400 { 01401 string s; 01402 01403 CPPUNIT_CHECK( s.capacity() > 0 ); 01404 CPPUNIT_CHECK( s.capacity() < s.max_size() ); 01405 CPPUNIT_CHECK( s.capacity() >= s.size() ); 01406 01407 #ifndef _STLP_SHORT_STRING_SZ 01408 # define _STLP_SHORT_STRING_SZ 16 // see stlport/stl/_string_base.h 01409 #endif 01410 01411 for ( int i = 0; i < _STLP_SHORT_STRING_SZ + 2; ++i ) { 01412 s += ' '; 01413 CPPUNIT_CHECK( s.capacity() > 0 ); 01414 CPPUNIT_CHECK( s.capacity() < s.max_size() ); 01415 CPPUNIT_CHECK( s.capacity() >= s.size() ); 01416 } 01417 } 01418 01419 void StringTest::concat24() 01420 { 01421 string s = string( "123456789012345678901234" ) + string( "123456789012345678901234" ); 01422 01423 CPPUNIT_CHECK( s.length() == 48 ); 01424 CPPUNIT_CHECK( s[23] == '4' ); 01425 CPPUNIT_CHECK( s[24] == '1' ); 01426 CPPUNIT_CHECK( s[47] == '4' ); 01427 } Generated on Sat May 26 2012 04:34:47 for ReactOS by
1.7.6.1
|