ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

string_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.