os/ossrv/genericopenlibs/cppstdlib/stl/test/unit/string_test.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // To make GLib C++ closer to STLport behavior we need this macro:
    15 // Only mandatory when building unit tests without STLport, do not change
    16 // anything when building with STLport
    17 // 
    18 //
    19 
    20 #define _GLIBCXX_FULLY_DYNAMIC_STRING
    21 
    22 //Has to be first for StackAllocator swap overload to be taken
    23 //into account (at least using GCC 4.0.1)
    24 #include "stack_allocator.h"
    25 
    26 #include <vector>
    27 #include <deque>
    28 #include <string>
    29 #include <algorithm>
    30 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
    31 #  include <sstream>
    32 #endif
    33 
    34 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    35 #  include <stdexcept>
    36 #endif
    37 
    38 #if !defined (STLPORT) || defined (_STLP_THREADS)
    39 #  if defined (STLPORT) && defined (_STLP_PTHREADS) || \
    40       defined (__GNUC__) && !defined (__MINGW32__)
    41 #    define USE_PTHREAD_API
    42 #    include <pthread.h>
    43 #  endif
    44 
    45 #  if defined (STLPORT) && defined (_STLP_WIN32THREADS) || \
    46       defined (__GNUC__) && defined (__MINGW32__) || \
    47       defined (_MSC_VER)
    48 #    define USE_WINDOWS_API
    49 #    include <windows.h>
    50 #  endif
    51 #endif
    52 
    53 #include "stack_allocator.h"
    54 #include "cppunit/cppunit_proxy.h"
    55 
    56 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
    57 using namespace std;
    58 #endif
    59 
    60 //
    61 // TestCase class
    62 //
    63 class StringTest : public CPPUNIT_NS::TestCase
    64 {
    65   CPPUNIT_TEST_SUITE(StringTest);
    66   CPPUNIT_TEST(constructor);
    67   CPPUNIT_TEST(reserve);
    68   CPPUNIT_TEST(assign);
    69   CPPUNIT_TEST(erase);
    70   CPPUNIT_TEST(data);
    71   CPPUNIT_TEST(c_str);
    72   CPPUNIT_TEST(null_char);
    73   CPPUNIT_TEST(insert);
    74   CPPUNIT_TEST(replace);
    75   CPPUNIT_TEST(resize);
    76   CPPUNIT_TEST(short_string);
    77   CPPUNIT_TEST(find);
    78   CPPUNIT_TEST(rfind);
    79   CPPUNIT_TEST(find_last_of);
    80   CPPUNIT_TEST(find_last_not_of);
    81   CPPUNIT_TEST(copy);
    82 #if !defined (USE_PTHREAD_API) && !defined (USE_WINDOWS_API)
    83   CPPUNIT_IGNORE;
    84 #endif
    85   CPPUNIT_TEST(mt);
    86   CPPUNIT_STOP_IGNORE;
    87   CPPUNIT_TEST(short_string_optim_bug);
    88   CPPUNIT_TEST(compare);
    89 #if defined (__DMC__)
    90   CPPUNIT_IGNORE;
    91 #endif
    92   CPPUNIT_TEST(template_expression);
    93 #if defined (STLPORT) && defined (_STLP_MSVC) && (_STLP_MSVC < 1300)
    94 #  define TE_TMP_TEST_IGNORED
    95   CPPUNIT_IGNORE;
    96 #endif
    97   CPPUNIT_TEST(te_tmp);
    98 #if defined (TE_TMP_TEST_IGNORED)
    99   CPPUNIT_STOP_IGNORE;
   100 #endif
   101 #if defined (STLPORT) && defined (_STLP_NO_WCHAR_T)
   102   CPPUNIT_IGNORE;
   103 #endif
   104 #if defined (__CYGWIN__) && !defined (STLPORT)
   105   CPPUNIT_IGNORE;
   106 #endif
   107   CPPUNIT_TEST(template_wexpression);
   108   CPPUNIT_STOP_IGNORE;
   109 #if defined (STLPORT) && defined (_STLP_USE_NO_IOSTREAMS)
   110   CPPUNIT_IGNORE;
   111 #endif
   112   CPPUNIT_TEST(io);
   113   CPPUNIT_STOP_IGNORE;
   114 #if defined (STLPORT) && defined (_STLP_NO_CUSTOM_IO) 
   115   CPPUNIT_IGNORE;
   116 #endif
   117   CPPUNIT_TEST(allocator_with_state);
   118   CPPUNIT_STOP_IGNORE;
   119   CPPUNIT_TEST(capacity);
   120   CPPUNIT_TEST(str_cov1);
   121   CPPUNIT_TEST(str_cov2);
   122   CPPUNIT_TEST(str_cov3);
   123   CPPUNIT_TEST(str_cov4);
   124   CPPUNIT_TEST(str_cov5);
   125   CPPUNIT_TEST(str_cov6);
   126   CPPUNIT_TEST_SUITE_END();
   127 
   128 protected:
   129   void constructor();
   130   void reserve();
   131   void erase();
   132   void data();
   133   void c_str();
   134   void null_char();
   135   void insert();
   136   void replace();
   137   void resize();
   138   void short_string();
   139   void find();
   140   void rfind();
   141   void find_last_of();
   142   void find_last_not_of();
   143   void copy();
   144   void assign();
   145   void mt();
   146   void short_string_optim_bug();
   147   void compare();
   148   void template_expression();
   149   void te_tmp();
   150   void template_wexpression();
   151   void io();
   152   void allocator_with_state();
   153   void capacity();
   154   void str_cov1();
   155   void str_cov2();
   156   void str_cov3();
   157   void str_cov4();
   158   void str_cov5();
   159   void str_cov6();
   160   static string func(const string& par) {
   161     string tmp( par );
   162     return tmp;
   163   }
   164 
   165 #if defined (USE_PTHREAD_API) || defined (USE_WINDOWS_API)
   166 #  if defined (USE_PTHREAD_API)
   167   static void* f(void*)
   168 #  else
   169   static DWORD __stdcall f(void*)
   170 #  endif
   171   {
   172     string s( "qyweyuewunfkHBUKGYUGL,wehbYGUW^(@T@H!BALWD:h^&@#*@(#:JKHWJ:CND" );
   173 
   174     for ( int i = 0; i < 2000000; ++i ) {
   175       string sx = func( s );
   176     }
   177 
   178     return 0;
   179   }
   180 #endif
   181 
   182 };
   183 
   184 CPPUNIT_TEST_SUITE_REGISTRATION(StringTest);
   185 
   186 //
   187 // tests implementation
   188 //
   189 void StringTest::constructor()
   190 {
   191 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
   192   try {
   193     string s((size_t)-1, 'a');
   194     CPPUNIT_ASSERT( false );
   195   }
   196   catch (length_error const&) {
   197   }
   198   catch (...) {
   199     //Expected exception is length_error:
   200     CPPUNIT_ASSERT( false );
   201   }
   202 #endif
   203 }
   204 
   205 void StringTest::reserve()
   206 {
   207   string s;
   208 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
   209   try {
   210     s.reserve(s.max_size() + 1);
   211     CPPUNIT_ASSERT( false );
   212   }
   213   catch (length_error const&) {
   214   }
   215   catch (...) {
   216     //Expected exception is length_error:
   217     CPPUNIT_ASSERT( false );
   218   }
   219 #endif
   220 }
   221 
   222 void StringTest::mt()
   223 {
   224 #if defined (USE_PTHREAD_API) || defined (USE_WINDOWS_API)
   225   const int nth = 2;
   226 #  if defined (USE_PTHREAD_API)
   227   pthread_t t[nth];
   228 
   229   for ( int i = 0; i < nth; ++i ) {
   230     pthread_create( &t[i], 0, f, 0 );
   231   }
   232 
   233   for ( int i = 0; i < nth; ++i ) {
   234     pthread_join( t[i], 0 );
   235   }
   236 #  endif // PTHREAD
   237 
   238 #  if defined (USE_WINDOWS_API)
   239   //DWORD start = GetTickCount();
   240 
   241   HANDLE t[nth];
   242 
   243   int i; // VC6 not support in-loop scope of cycle var
   244   for ( i = 0; i < nth; ++i ) {
   245     t[i] = CreateThread(NULL, 0, f, 0, 0, NULL);
   246   }
   247 
   248   if (WaitForMultipleObjects(nth, t, TRUE, INFINITE) == WAIT_FAILED) {
   249     // On some platforms (evc3/evc4) WaitForMultipleObjects() with fWaitAll == TRUE
   250     // is not supported. We then wait with a loop on each thread:
   251     for ( i = 0; i < nth; ++i ) {
   252       WaitForSingleObject(t[i], INFINITE);
   253     }
   254   }
   255 
   256   /*
   257   DWORD duration = GetTickCount() - start;
   258   ostringstream ostr;
   259   ostr << "Duration: " << duration << endl;
   260   CPPUNIT_MESSAGE(ostr.str().c_str());
   261   */
   262 #  endif
   263 #endif
   264 }
   265 
   266 void StringTest::short_string()
   267 {
   268   string const ref_short_str1("str1"), ref_short_str2("str2");
   269   string short_str1(ref_short_str1), short_str2(ref_short_str2);
   270   string const ref_long_str1("str                                                  1");
   271   string const ref_long_str2("str                                                  2");
   272   string long_str1(ref_long_str1), long_str2(ref_long_str2);
   273 
   274   CPPUNIT_ASSERT(short_str1 == ref_short_str1);
   275   CPPUNIT_ASSERT(long_str1 == ref_long_str1);
   276 
   277   {
   278     string str1(short_str1);
   279     str1 = long_str1;
   280     CPPUNIT_ASSERT(str1 == ref_long_str1);
   281   }
   282 
   283   {
   284     string str1(long_str1);
   285     str1 = short_str1;
   286     CPPUNIT_ASSERT(str1 == ref_short_str1);
   287   }
   288 
   289   {
   290     short_str1.swap(short_str2);
   291     CPPUNIT_ASSERT((short_str1 == ref_short_str2) && (short_str2 == ref_short_str1));
   292     short_str1.swap(short_str2);
   293   }
   294 
   295   {
   296     long_str1.swap(long_str2);
   297     CPPUNIT_ASSERT((long_str1 == ref_long_str2) && (long_str2 == ref_long_str1));
   298     long_str1.swap(long_str2);
   299   }
   300 
   301   {
   302     short_str1.swap(long_str1);
   303     CPPUNIT_ASSERT((short_str1 == ref_long_str1) && (long_str1 == ref_short_str1));
   304     short_str1.swap(long_str1);
   305   }
   306 
   307   {
   308     long_str1.swap(short_str1);
   309     CPPUNIT_ASSERT((short_str1 == ref_long_str1) && (long_str1 == ref_short_str1));
   310     long_str1.swap(short_str1);
   311   }
   312 
   313   {
   314     //This is to test move constructor
   315     vector<string> str_vect;
   316     str_vect.push_back(short_str1);
   317     str_vect.push_back(long_str1);
   318     str_vect.push_back(short_str2);
   319     str_vect.push_back(long_str2);
   320     CPPUNIT_ASSERT((str_vect[0] == ref_short_str1) &&
   321                    (str_vect[1] == ref_long_str1) &&
   322                    (str_vect[2] == ref_short_str2) &&
   323                    (str_vect[3] == ref_long_str2));
   324   }
   325 }
   326 
   327 void StringTest::erase()
   328 {
   329   char const* c_str = "Hello, World!";
   330   string str(c_str);
   331   CPPUNIT_ASSERT( str == c_str );
   332 
   333   str.erase(str.begin() + 1, str.end() - 1); // Erase all but first and last.
   334 
   335   size_t i;
   336   for (i = 0; i < str.size(); ++i) {
   337     switch ( i ) {
   338       case 0:
   339         CPPUNIT_ASSERT( str[i] == 'H' );
   340         break;
   341       case 1:
   342         CPPUNIT_ASSERT( str[i] == '!' );
   343         break;
   344       default:
   345         CPPUNIT_ASSERT( false );
   346     }
   347   }
   348 
   349   str.insert(1, c_str);
   350   str.erase(str.begin()); // Erase first element.
   351   str.erase(str.end() - 1); // Erase last element.
   352   CPPUNIT_ASSERT( str == c_str );
   353   str.clear(); // Erase all.
   354   CPPUNIT_ASSERT( str.empty() );
   355 
   356   str = c_str;
   357   CPPUNIT_ASSERT( str == c_str );
   358 
   359   str.erase(1, str.size() - 1); // Erase all but first and last.
   360   for (i = 0; i < str.size(); i++) {
   361     switch ( i ) {
   362       case 0:
   363         CPPUNIT_ASSERT( str[i] == 'H' );
   364         break;
   365       case 1:
   366         CPPUNIT_ASSERT( str[i] == '!' );
   367         break;
   368       default:
   369         CPPUNIT_ASSERT( false );
   370     }
   371   }
   372 
   373   str.erase(1);
   374   CPPUNIT_ASSERT( str == "H" );
   375 }
   376 
   377 void StringTest::data()
   378 {
   379   string xx;
   380 
   381   CPPUNIT_ASSERT( xx.data() != 0 );  // ISO-IEC-14882:1998(E), 21.3.6, paragraph 3
   382 #if 0
   383   /* This test really not required: in ISO-IEC-14882:1998(E) paragraph 3 stated:
   384    * '... and can have zero added to it', again: 'CAN', but not 'MUST'.
   385    * That's why I am comment this test. But I don't remove it due to I had
   386    * unevident problem with misinterpretation of data() return (i.e. data()
   387    * and c_str() provide different functionality!) and expect that this is
   388    * more-or-less common pitfall.
   389    *    - ptr
   390    */
   391   string low( "2004-01-01" );
   392   // Blocks A and B should follow each other.
   393   // Block A:
   394   xx = "123456";
   395   xx += low;
   396   if ( strcmp( xx.data(), "1234562004-01-01" ) != 0 ) {
   397     return -1;
   398   }
   399   // End of block A
   400 
   401   // Block B:
   402   xx = "1234";
   403   xx += ";";
   404 
   405   if ( strcmp( xx.data(), "1234;" ) != 0 ) {
   406     return -1;
   407   }
   408   // End of block B
   409 #endif
   410 }
   411 
   412 void StringTest::c_str()
   413 {
   414   string low( "2004-01-01" );
   415   string xx;
   416   string yy;
   417 
   418   CPPUNIT_ASSERT( *(yy.c_str()) == '\0' ); // ISO-IEC-14882:1998(E), 21.3.6, paragraph 1
   419 
   420   // Blocks A and B should follow each other.
   421   // Block A:
   422   xx = "123456";
   423   xx += low;
   424   CPPUNIT_ASSERT( strcmp( xx.c_str(), "1234562004-01-01" ) == 0 );
   425   // End of block A
   426 
   427   // Block B:
   428   xx = "1234";
   429   xx += ";";
   430   CPPUNIT_ASSERT( strcmp( xx.c_str(), "1234;" ) == 0 );
   431   // End of block B
   432 }
   433 
   434 void StringTest::null_char()
   435 {
   436   // ISO/IEC 14882:1998(E), ISO/IEC 14882:2003(E), 21.3.4 ('... the const version')
   437   const string s( "123456" );
   438 
   439   CPPUNIT_CHECK( s[s.size()] == '\0' );
   440 
   441 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
   442   try {
   443     //Check is only here to avoid warning about value of expression not used
   444     CPPUNIT_CHECK( s.at(s.size()) == '\0' );
   445     CPPUNIT_ASSERT( false );
   446   }
   447   catch (out_of_range const&) {
   448     CPPUNIT_ASSERT( true );
   449   }
   450   catch ( ... ) {
   451     CPPUNIT_ASSERT( false );
   452   }
   453 #endif
   454 }
   455 
   456 void StringTest::insert()
   457 {
   458   string strorg = "This is test string for string calls";
   459   string str;
   460   /*
   461    * In case of reallocation there is no auto reference problem
   462    * so we reserve a big enough string to be sure to test this
   463    * particular point.
   464    */
   465   str.reserve(100);
   466   str = strorg;
   467 
   468   //test self insertion:
   469   str.insert(10, str.c_str() + 5, 15);
   470   CPPUNIT_ASSERT( str == "This is teis test string st string for string calls" );
   471 
   472   str = strorg;
   473   str.insert(15, str.c_str() + 5, 25);
   474   CPPUNIT_ASSERT( str == "This is test stis test string for stringring for string calls" );
   475 
   476   str = strorg;
   477   str.insert(0, str.c_str() + str.size() - 4, 4);
   478   CPPUNIT_ASSERT( str == "allsThis is test string for string calls" );
   479 
   480   str = strorg;
   481   str.insert(0, str.c_str() + str.size() / 2 - 1, str.size() / 2 + 1);
   482   CPPUNIT_ASSERT( str == "ng for string callsThis is test string for string calls" );
   483 
   484   str = strorg;
   485   string::iterator b = str.begin();
   486   string::const_iterator s = str.begin() + str.size() / 2 - 1;
   487   string::const_iterator e = str.end();
   488   str.insert( b, s, e );
   489   CPPUNIT_ASSERT( str == "ng for string callsThis is test string for string calls" );
   490 
   491   str = strorg;
   492   str.insert(str.begin(), str.begin() + str.size() / 2 - 1, str.end());
   493   CPPUNIT_ASSERT( str == "ng for string callsThis is test string for string calls" );
   494 
   495 #ifdef _STLP_MEMBER_TEMPLATES
   496   vector<int> int_vect;
   497   //Just a compile time test:
   498   str.insert(str.end(), int_vect.begin(), int_vect.end());
   499 #endif
   500 
   501   string str0;
   502   str0.insert(str0.begin(), 5, '0');
   503   CPPUNIT_ASSERT( str0 == "00000" );
   504 
   505   string str1;
   506   {
   507     string::size_type pos = 0, nb = 2;
   508     str1.insert(pos, nb, '1');
   509   }
   510   CPPUNIT_ASSERT( str1 == "11" );
   511 
   512   str0.insert(0, str1);
   513   CPPUNIT_ASSERT( str0 == "1100000" );
   514 
   515   string str2("2345");
   516   str0.insert(str0.size(), str2, 1, 2);
   517   CPPUNIT_ASSERT( str0 == "110000034" );
   518 
   519   str1.insert(str1.begin() + 1, 2, '2');
   520   CPPUNIT_ASSERT( str1 == "1221" );
   521 
   522   str1.insert(2, "333333", 3);
   523   CPPUNIT_ASSERT( str1 == "1233321" );
   524 
   525   str1.insert(4, "4444");
   526   CPPUNIT_ASSERT( str1 == "12334444321" );
   527 
   528   str1.insert(str1.begin() + 6, '5');
   529   CPPUNIT_ASSERT( str1 == "123344544321" );
   530 }
   531 
   532 void StringTest::replace()
   533 {
   534   /*
   535    * This test case is for the non template basic_string::replace method,
   536    * this is why we play with the const iterators and reference to guaranty
   537    * that the right method is called.
   538    */
   539   const string v( "78" );
   540   string s( "123456" );
   541   string const& cs = s;
   542 
   543   string::iterator i = s.begin() + 1;
   544   s.replace(i, i + 3, v.begin(), v.end());
   545   CPPUNIT_ASSERT( s == "17856" );
   546 
   547   s = "123456";
   548   i = s.begin() + 1;
   549   s.replace(i, i + 1, v.begin(), v.end());
   550   CPPUNIT_ASSERT( s == "1783456" );
   551 
   552   s = "123456";
   553   i = s.begin() + 1;
   554   string::const_iterator ci = s.begin() + 1;
   555   s.replace(i, i + 3, ci + 3, cs.end());
   556   CPPUNIT_ASSERT( s == "15656" );
   557 
   558   s = "123456";
   559   i = s.begin() + 1;
   560   ci = s.begin() + 1;
   561   s.replace(i, i + 3, ci, ci + 2);
   562   CPPUNIT_ASSERT( s == "12356" );
   563 
   564   s = "123456";
   565   i = s.begin() + 1;
   566   ci = s.begin() + 1;
   567   s.replace(i, i + 3, ci + 1, cs.end());
   568   CPPUNIT_ASSERT( s == "1345656" );
   569 
   570   s = "123456";
   571   s.replace(s.begin() + 4, s.end(), cs.begin(), cs.end());
   572   CPPUNIT_ASSERT( s == "1234123456" );
   573 
   574   /*
   575    * This is the test for the template replace method.
   576    */
   577   s = "123456";
   578   string::iterator b = s.begin() + 4;
   579   string::iterator e = s.end();
   580   string::const_iterator rb = s.begin();
   581   string::const_iterator re = s.end();
   582   s.replace(b, e, rb, re);
   583   CPPUNIT_ASSERT( s == "1234123456" );
   584 
   585   s = "123456";
   586   s.replace(s.begin() + 4, s.end(), s.begin(), s.end());
   587   CPPUNIT_ASSERT( s == "1234123456" );
   588 
   589   string strorg("This is test string for string calls");
   590   string str = strorg;
   591   str.replace(5, 15, str.c_str(), 10);
   592   CPPUNIT_ASSERT( str == "This This is tefor string calls" );
   593 
   594   str = strorg;
   595   str.replace(5, 5, str.c_str(), 10);
   596   CPPUNIT_ASSERT( str == "This This is test string for string calls" );
   597 
   598 #if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATES)
   599   deque<char> cdeque;
   600   cdeque.push_back('I');
   601   str.replace(str.begin(), str.begin() + 11, cdeque.begin(), cdeque.end());
   602   CPPUNIT_ASSERT( str == "Is test string for string calls" );
   603 #endif
   604 }
   605 
   606 void StringTest::resize()
   607 {
   608   string s;
   609 
   610   s.resize(0);
   611 
   612   CPPUNIT_ASSERT( *s.c_str() == 0 );
   613 
   614   s = "1234567";
   615 
   616   s.resize(0);
   617   CPPUNIT_ASSERT( *s.c_str() == 0 );
   618 
   619   s = "1234567";
   620   s.resize(1);
   621   CPPUNIT_ASSERT( s.size() == 1 );
   622   CPPUNIT_ASSERT( *s.c_str() == '1' );
   623   CPPUNIT_ASSERT( *(s.c_str() + 1) == 0 );
   624 
   625   s = "1234567";
   626   s.resize(10);
   627   CPPUNIT_ASSERT( s.size() == 10 );
   628   CPPUNIT_ASSERT( s[6] == '7' );
   629   CPPUNIT_ASSERT( s[7] == 0 );
   630   CPPUNIT_ASSERT( s[8] == 0 );
   631   CPPUNIT_ASSERT( s[9] == 0 );
   632 }
   633 
   634 void StringTest::find()
   635 {
   636   string s("one two three one two three");
   637   CPPUNIT_ASSERT( s.find("one") == 0 );
   638   CPPUNIT_ASSERT( s.find('t') == 4 );
   639   CPPUNIT_ASSERT( s.find('t', 5) == 8 );
   640   //We are trying to get a const reference to the npos string static member to
   641   //force the compiler to allocate memory for this variable. It used to reveal
   642   //a bug of STLport which was simply declaring npos without instanciating it.
   643 #if !defined (STLPORT) || !defined (_STLP_STATIC_CONST_INIT_BUG)
   644   string::size_type const& npos_local = string::npos;
   645 #else
   646 #  define npos_local string::npos
   647 #endif
   648   CPPUNIT_ASSERT( s.find("four") == npos_local );
   649   CPPUNIT_ASSERT( s.find("one", string::npos) == npos_local );
   650 
   651   CPPUNIT_ASSERT( s.find_first_of("abcde") == 2 );
   652 
   653   CPPUNIT_ASSERT( s.find_first_not_of("enotw ") == 9 );
   654 }
   655 
   656 void StringTest::rfind()
   657 {
   658   // 21.3.6.2
   659   string s("one two three one two three");
   660 
   661   CPPUNIT_ASSERT( s.rfind("two") == 18 );
   662   CPPUNIT_ASSERT( s.rfind("two", 0) == string::npos );
   663   CPPUNIT_ASSERT( s.rfind("two", 11) == 4 );
   664   CPPUNIT_ASSERT( s.rfind('w') == 19 );
   665 
   666   string test( "aba" );
   667 
   668   CPPUNIT_CHECK( test.rfind( "a", 2, 1 ) == 2 );
   669   CPPUNIT_CHECK( test.rfind( "a", 1, 1 ) == 0 );
   670   CPPUNIT_CHECK( test.rfind( "a", 0, 1 ) == 0 );
   671 
   672   CPPUNIT_CHECK( test.rfind( 'a', 2 ) == 2 );
   673   CPPUNIT_CHECK( test.rfind( 'a', 1 ) == 0 );
   674   CPPUNIT_CHECK( test.rfind( 'a', 0 ) == 0 );
   675 }
   676 
   677 void StringTest::find_last_of()
   678 {
   679   // 21.3.6.4
   680   string s("one two three one two three");
   681 
   682   CPPUNIT_ASSERT( s.find_last_of("abcde") == 26 );
   683 
   684   string test( "aba" );
   685 
   686   CPPUNIT_CHECK( test.find_last_of( "a", 2, 1 ) == 2 );
   687   CPPUNIT_CHECK( test.find_last_of( "a", 1, 1 ) == 0 );
   688   CPPUNIT_CHECK( test.find_last_of( "a", 0, 1 ) == 0 );
   689 
   690   CPPUNIT_CHECK( test.find_last_of( 'a', 2 ) == 2 );
   691   CPPUNIT_CHECK( test.find_last_of( 'a', 1 ) == 0 );
   692   CPPUNIT_CHECK( test.find_last_of( 'a', 0 ) == 0 );
   693 }
   694 
   695 void StringTest::find_last_not_of()
   696 {
   697   // 21.3.6.6
   698   string s("one two three one two three");
   699 
   700   CPPUNIT_ASSERT( s.find_last_not_of("ehortw ") == 15 );
   701 
   702   string test( "aba" );
   703 
   704   CPPUNIT_CHECK( test.find_last_not_of( "a", 2, 1 ) == 1 );
   705   CPPUNIT_CHECK( test.find_last_not_of( "b", 2, 1 ) == 2 );
   706   CPPUNIT_CHECK( test.find_last_not_of( "a", 1, 1 ) == 1 );
   707   CPPUNIT_CHECK( test.find_last_not_of( "b", 1, 1 ) == 0 );
   708   CPPUNIT_CHECK( test.find_last_not_of( "a", 0, 1 ) == string::npos );
   709   CPPUNIT_CHECK( test.find_last_not_of( "b", 0, 1 ) == 0 );
   710 
   711   CPPUNIT_CHECK( test.find_last_not_of( 'a', 2 ) == 1 );
   712   CPPUNIT_CHECK( test.find_last_not_of( 'b', 2 ) == 2 );
   713   CPPUNIT_CHECK( test.find_last_not_of( 'a', 1 ) == 1 );
   714   CPPUNIT_CHECK( test.find_last_not_of( 'b', 1 ) == 0 );
   715   CPPUNIT_CHECK( test.find_last_not_of( 'a', 0 ) == string::npos );
   716   CPPUNIT_CHECK( test.find_last_not_of( 'b', 0 ) == 0 );
   717 }
   718 
   719 void StringTest::copy()
   720 {
   721   string s("foo");
   722   char dest[4];
   723   dest[0] = dest[1] = dest[2] = dest[3] = 1;
   724   s.copy(dest, 4);
   725   int pos = 0;
   726   CPPUNIT_ASSERT( dest[pos++] == 'f' );
   727   CPPUNIT_ASSERT( dest[pos++] == 'o' );
   728   CPPUNIT_ASSERT( dest[pos++] == 'o' );
   729   CPPUNIT_ASSERT( dest[pos++] == 1 );
   730 
   731   dest[0] = dest[1] = dest[2] = dest[3] = 1;
   732   s.copy(dest, 4, 2);
   733   pos = 0;
   734   CPPUNIT_ASSERT( dest[pos++] == 'o' );
   735   CPPUNIT_ASSERT( dest[pos++] == 1 );
   736 
   737 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
   738   try {
   739     s.copy(dest, 4, 5);
   740     CPPUNIT_ASSERT( false );
   741   }
   742   catch (out_of_range const&) {
   743     CPPUNIT_ASSERT( true );
   744   }
   745   catch ( ... ) {
   746     CPPUNIT_ASSERT( false );
   747   }
   748 #endif
   749 }
   750 
   751 void StringTest::assign()
   752 {
   753   string s;
   754   char const* cstr = "test string for assign";
   755 
   756   s.assign(cstr, cstr + 22);
   757   CPPUNIT_ASSERT( s == "test string for assign" );
   758 
   759   string s2("other test string");
   760   s.assign(s2);
   761   CPPUNIT_ASSERT( s == s2 );
   762 
   763   static string str1;
   764   static string str2;
   765 
   766   // short string optim:
   767   str1 = "123456";
   768   // longer than short string:
   769   str2 = "1234567890123456789012345678901234567890";
   770 
   771   CPPUNIT_ASSERT(str1[5] == '6');
   772   CPPUNIT_ASSERT(str2[29] == '0');
   773 }
   774 
   775 /* This test is to check if std::string properly supports the short string
   776  * optimization. It has been found out that eMbedded Visual C++ 3.0 and .NET
   777  * compilers for the ARM platform fail to pass structs and classes of certain
   778  * size per value. This seems to be a known compiler bug. For other processors
   779  * (e.g. x86) the error doesn't occur.
   780  * (The ARM compiler creates a temporary object from teststr on the stack, to
   781  * pass it to the helper function. It uses the copy constructor for this.
   782  * After this the temporary object is copied to another place on the stack.
   783  * The result is that the _M_finish pointer then points to the wrong buffer
   784  * end and the size of the short string is incorrectly calculated.)
   785  */
   786 void StringTest::short_string_optim_bug()
   787 {
   788    string teststr("shortest");
   789 
   790    bool short_string_optim_bug_helper(string teststr);
   791 
   792    CPPUNIT_ASSERT(true == short_string_optim_bug_helper(teststr));
   793 }
   794 
   795 bool short_string_optim_bug_helper(string teststr)
   796 {
   797    size_t ss = teststr.size();
   798    return (ss == 8);
   799 }
   800 
   801 void StringTest::compare()
   802 {
   803   string str1("abcdef");
   804   string str2;
   805 
   806   str2 = "abcdef";
   807   CPPUNIT_ASSERT( str1.compare(str2) == 0 );
   808   str2 = "abcde";
   809   CPPUNIT_ASSERT( str1.compare(str2) > 0 );
   810   str2 = "abcdefg";
   811   CPPUNIT_ASSERT( str1.compare(str2) < 0 );
   812 
   813   CPPUNIT_ASSERT( str1.compare("abcdef") == 0 );
   814   CPPUNIT_ASSERT( str1.compare("abcde") > 0 );
   815   CPPUNIT_ASSERT( str1.compare("abcdefg") < 0 );
   816 
   817   str2 = "cde";
   818   CPPUNIT_ASSERT( str1.compare(2, 3, str2) == 0 );
   819   str2 = "cd";
   820   CPPUNIT_ASSERT( str1.compare(2, 3, str2) > 0 );
   821   str2 = "cdef";
   822   CPPUNIT_ASSERT( str1.compare(2, 3, str2) < 0 );
   823 
   824   str2 = "abcdef";
   825   CPPUNIT_ASSERT( str1.compare(2, 3, str2, 2, 3) == 0 );
   826   CPPUNIT_ASSERT( str1.compare(2, 3, str2, 2, 2) > 0 );
   827   CPPUNIT_ASSERT( str1.compare(2, 3, str2, 2, 4) < 0 );
   828 
   829   CPPUNIT_ASSERT( str1.compare(2, 3, "cdefgh", 3) == 0 );
   830   CPPUNIT_ASSERT( str1.compare(2, 3, "cdefgh", 2) > 0 );
   831   CPPUNIT_ASSERT( str1.compare(2, 3, "cdefgh", 4) < 0 );
   832 }
   833 
   834 /*
   835 class mystring : public string {
   836 public:
   837   mystring() {}
   838   mystring(string const& s) : string(s) {}
   839 
   840   mystring& operator = (string const& s) {
   841     string::operator = (s);
   842     return *this;
   843   };
   844 };
   845 */
   846 
   847 void StringTest::template_expression()
   848 {
   849   string one("one"), two("two"), three("three");
   850   string space(1, ' ');
   851 
   852   // check availability of [un]equality operators
   853   {
   854       // string-string
   855       one == two;
   856       one != two;
   857       // string-literal
   858       one == "two";
   859       one != "two";
   860       // literal-string
   861       "one" == two;
   862       "one" != two;
   863       // strsum-string
   864       (one + two) == three;
   865       (one + two) != three;
   866       // string-strsum
   867       one == (two + three);
   868       one != (two + three);
   869       // strsum-literal
   870       (one + two) == "three";
   871       (one + two) != "three";
   872       // literal-strsum
   873       "one" == (two + three);
   874       "one" != (two + three);
   875       // strsum-strsum
   876       (one + two) == (two + three);
   877       (one + two) != (two + three);
   878   }
   879 
   880   {
   881     string result(one + ' ' + two + ' ' + three);
   882     CPPUNIT_CHECK( result == "one two three" );
   883   }
   884 
   885   {
   886     string result(one + ' ' + two + ' ' + three, 4);
   887     CPPUNIT_CHECK( result == "two three" );
   888   }
   889 
   890   {
   891     string result(one + ' ' + two + ' ' + three, 4, 3);
   892     CPPUNIT_CHECK( result == "two" );
   893   }
   894 
   895   //2 members expressions:
   896   CPPUNIT_CHECK( (' ' + one) == " one" );
   897   CPPUNIT_CHECK( (one + ' ') == "one " );
   898   CPPUNIT_CHECK( (one + " two") == "one two" );
   899   CPPUNIT_CHECK( ("one " + two) == "one two" );
   900   CPPUNIT_CHECK( (one + space) == "one " );
   901 
   902   //3 members expressions:
   903   CPPUNIT_CHECK( ((one + space) + "two") == "one two" );
   904   CPPUNIT_CHECK( ("one" + (space + two)) == "one two" );
   905   CPPUNIT_CHECK( ((one + space) + two) == "one two" );
   906   CPPUNIT_CHECK( (one + (space + two)) == "one two" );
   907   CPPUNIT_CHECK( ((one + space) + 't') == "one t" );
   908   CPPUNIT_CHECK( ('o' + (space + two)) == "o two" );
   909 
   910   //4 members expressions:
   911   CPPUNIT_CHECK( ((one + space) + (two + space)) == "one two " );
   912 
   913   //special operators
   914   {
   915     string result;
   916     result = one + space + two;
   917     CPPUNIT_CHECK( result == "one two" );
   918 
   919     result += space + three;
   920     CPPUNIT_CHECK( result == "one two three" );
   921   }
   922 
   923   //special append method
   924   {
   925     string result;
   926     //Use reserve to avoid reallocation and really test auto-referencing problems:
   927     result.reserve(64);
   928 
   929     result.append(one + space + two);
   930     CPPUNIT_CHECK( result == "one two" );
   931 
   932     result.append(space + result + space + three);
   933     CPPUNIT_CHECK( result == "one two one two three" );
   934 
   935     result = "one two";
   936     result.append(space + three, 1, 2);
   937     CPPUNIT_ASSERT( result == "one twoth" );
   938 
   939     result.append(space + result);
   940     CPPUNIT_CHECK( result == "one twoth one twoth" );
   941   }
   942 
   943   //special assign method
   944   {
   945     string result;
   946     //Use reserve to avoid reallocation and really test auto-referencing problems:
   947     result.reserve(64);
   948 
   949     result.assign(one + space + two + space + three);
   950     CPPUNIT_CHECK( result == "one two three" );
   951 
   952     result.assign(one + space + two + space + three, 3, 5);
   953     CPPUNIT_CHECK( result == " two " );
   954 
   955     result.assign(one + result + three);
   956     CPPUNIT_CHECK( result == "one two three" );
   957   }
   958 
   959   {
   960     CPPUNIT_CHECK( !(one + ' ' + two).empty() );
   961 
   962     char result = (one + ' ' + two)[3];
   963     CPPUNIT_CHECK( result == ' ' );
   964 
   965     result = (one + ' ' + two).at(3);
   966     CPPUNIT_CHECK( result == ' ' );
   967 
   968 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
   969     try {
   970       result = (one + ' ' + two).at(10);
   971       CPPUNIT_ASSERT(false);
   972     }
   973     catch (out_of_range const&) {
   974       CPPUNIT_ASSERT( result == ' ' );
   975     }
   976     catch (...) {
   977       CPPUNIT_ASSERT(false);
   978     }
   979 #endif
   980   }
   981 
   982   /*
   983   mystring a("ing");
   984   //gcc failed to compile following expression when template expressions are activated.
   985   //MSVC sees no problem. gcc limitation or MSVC is too cool ??
   986   mystring b = "str" + a;
   987   */
   988 }
   989 
   990 #if !defined (TE_TMP_TEST_IGNORED)
   991 class superstring
   992 {
   993   public:
   994     superstring() :
   995       s("super")
   996     {}
   997 
   998     superstring( const string& str ) :
   999       s( str )
  1000     {}
  1001 
  1002   superstring operator / (const string& str )
  1003     { return superstring( s + "/" + str ); }
  1004 
  1005   superstring operator / (const char* str )
  1006     { return superstring( s + "/" + str ); }
  1007 
  1008   private:
  1009     string s;
  1010 };
  1011 #endif
  1012 
  1013 void StringTest::te_tmp()
  1014 {
  1015 #if !defined (TE_TMP_TEST_IGNORED)
  1016   superstring s;
  1017   string more( "more" );
  1018   string less( "less" );
  1019 
  1020   superstring r = s / (more + less);
  1021 #endif
  1022 }
  1023 
  1024 void StringTest::template_wexpression()
  1025 {
  1026 #if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
  1027 #  if !defined (__CYGWIN__) || defined (STLPORT)
  1028   wstring one(L"one"), two(L"two"), three(L"three");
  1029   wstring space(1, L' ');
  1030 
  1031   {
  1032     wstring result(one + L' ' + two + L' ' + three);
  1033     CPPUNIT_CHECK( result == L"one two three" );
  1034   }
  1035 
  1036   {
  1037     wstring result(one + L' ' + two + L' ' + three, 4);
  1038     CPPUNIT_CHECK( result == L"two three" );
  1039   }
  1040 
  1041   {
  1042     wstring result(one + L' ' + two + L' ' + three, 4, 3);
  1043     CPPUNIT_CHECK( result == L"two" );
  1044   }
  1045 
  1046   //2 members expressions:
  1047   CPPUNIT_CHECK( (L' ' + one) == L" one" );
  1048   CPPUNIT_CHECK( (one + L' ') == L"one " );
  1049   CPPUNIT_CHECK( (one + L" two") == L"one two" );
  1050   CPPUNIT_CHECK( (L"one " + two) == L"one two" );
  1051   CPPUNIT_CHECK( (one + space) == L"one " );
  1052 
  1053   //3 members expressions:
  1054   CPPUNIT_CHECK( ((one + space) + L"two") == L"one two" );
  1055   CPPUNIT_CHECK( (L"one" + (space + two)) == L"one two" );
  1056   CPPUNIT_CHECK( ((one + space) + two) == L"one two" );
  1057   CPPUNIT_CHECK( (one + (space + two)) == L"one two" );
  1058   CPPUNIT_CHECK( ((one + space) + L't') == L"one t" );
  1059   CPPUNIT_CHECK( (L'o' + (space + two)) == L"o two" );
  1060 
  1061   //4 members expressions:
  1062   CPPUNIT_CHECK( ((one + space) + (two + space)) == L"one two " );
  1063 
  1064   //special operators
  1065   {
  1066     wstring result;
  1067     result = one + space + two;
  1068     CPPUNIT_CHECK( result == L"one two" );
  1069 
  1070     result += space + three;
  1071     CPPUNIT_CHECK( result == L"one two three" );
  1072   }
  1073 
  1074   //special append method
  1075   {
  1076     wstring result;
  1077     //Use reserve to avoid reallocation and really test auto-referencing problems:
  1078     result.reserve(64);
  1079 
  1080     result.append(one + space + two);
  1081     CPPUNIT_CHECK( result == L"one two" );
  1082 
  1083     result.append(space + result + space + three);
  1084     CPPUNIT_CHECK( result == L"one two one two three" );
  1085 
  1086     result = L"one two";
  1087     result.append(space + three, 1, 2);
  1088     CPPUNIT_ASSERT( result == L"one twoth" );
  1089 
  1090     result.append(space + result);
  1091     CPPUNIT_CHECK( result == L"one twoth one twoth" );
  1092   }
  1093 
  1094   //special assign method
  1095   {
  1096     wstring result;
  1097     //Use reserve to avoid reallocation and really test auto-referencing problems:
  1098     result.reserve(64);
  1099 
  1100     result.assign(one + space + two + space + three);
  1101     CPPUNIT_CHECK( result == L"one two three" );
  1102 
  1103     result.assign(one + space + two + space + three, 3, 5);
  1104     CPPUNIT_CHECK( result == L" two " );
  1105 
  1106     result.assign(one + result + three);
  1107     CPPUNIT_CHECK( result == L"one two three" );
  1108   }
  1109 
  1110   {
  1111     CPPUNIT_CHECK( !(one + L' ' + two).empty() );
  1112 
  1113     wchar_t result = (one + L' ' + two)[3];
  1114     CPPUNIT_CHECK( result == L' ' );
  1115 
  1116     result = (one + L' ' + two).at(3);
  1117     CPPUNIT_CHECK( result == L' ' );
  1118 
  1119 #    if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
  1120     try {
  1121       result = (one + L' ' + two).at(10);
  1122       CPPUNIT_ASSERT(false);
  1123     }
  1124     catch (out_of_range const&) {
  1125       CPPUNIT_ASSERT( result == L' ' );
  1126     }
  1127     catch (...) {
  1128       CPPUNIT_ASSERT(false);
  1129     }
  1130 #    endif
  1131   }
  1132 #  endif
  1133 #endif
  1134 }
  1135 
  1136 void StringTest::io()
  1137 {
  1138 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
  1139   string str("STLport");
  1140   {
  1141     ostringstream ostr;
  1142     ostr << str;
  1143     CPPUNIT_ASSERT( ostr.good() );
  1144     CPPUNIT_ASSERT( ostr.str() == str );
  1145   }
  1146   {
  1147     istringstream istr(str);
  1148     string istr_content;
  1149     istr >> istr_content;
  1150     CPPUNIT_ASSERT( !istr.fail() && istr.eof() );
  1151     CPPUNIT_ASSERT( istr_content == str );
  1152   }
  1153   {
  1154     istringstream istr(str);
  1155     istr.width(3);
  1156     string istr_content;
  1157     istr >> istr_content;
  1158     CPPUNIT_ASSERT( !istr.fail() && !istr.eof() );
  1159     CPPUNIT_ASSERT( istr_content == "STL" );
  1160   }
  1161 #endif
  1162 }
  1163 
  1164 void StringTest::allocator_with_state()
  1165 {
  1166 #if !(defined (STLPORT) && defined (_STLP_NO_CUSTOM_IO)) 
  1167 
  1168   char buf1[1024];
  1169   StackAllocator<char> stack1(buf1, buf1 + sizeof(buf1));
  1170 
  1171   char buf2[1024];
  1172   StackAllocator<char> stack2(buf2, buf2 + sizeof(buf2));
  1173 
  1174   typedef basic_string<char, char_traits<char>, StackAllocator<char> > StackString;
  1175   {
  1176     StackString str1("string stack1", stack1);
  1177     StackString str1Cpy(str1);
  1178 
  1179     StackString str2("string stack2", stack2);
  1180     StackString str2Cpy(str2);
  1181 
  1182     str1.swap(str2);
  1183 
  1184     CPPUNIT_ASSERT( str1.get_allocator().swaped() );
  1185     CPPUNIT_ASSERT( str2.get_allocator().swaped() );
  1186 
  1187     CPPUNIT_ASSERT( str1 == str2Cpy );
  1188     CPPUNIT_ASSERT( str2 == str1Cpy );
  1189     CPPUNIT_ASSERT( str1.get_allocator() == stack2 );
  1190     CPPUNIT_ASSERT( str2.get_allocator() == stack1 );
  1191   }
  1192   CPPUNIT_ASSERT( stack1.ok() );
  1193   CPPUNIT_ASSERT( stack2.ok() );
  1194   stack1.reset(); stack2.reset();
  1195 
  1196   {
  1197     StackString str1("longer string from stack1 allocator instance for dynamic allocation", stack1);
  1198     StackString str1Cpy(str1);
  1199 
  1200     StackString str2("longer string from stack2 allocator instance for dynamic allocation", stack2);
  1201     StackString str2Cpy(str2);
  1202 
  1203     str1.swap(str2);
  1204 
  1205     CPPUNIT_ASSERT( str1.get_allocator().swaped() );
  1206     CPPUNIT_ASSERT( str2.get_allocator().swaped() );
  1207 
  1208     CPPUNIT_ASSERT( str1 == str2Cpy );
  1209     CPPUNIT_ASSERT( str2 == str1Cpy );
  1210     CPPUNIT_ASSERT( str1.get_allocator() == stack2 );
  1211     CPPUNIT_ASSERT( str2.get_allocator() == stack1 );
  1212   }
  1213   CPPUNIT_ASSERT( stack1.ok() );
  1214   CPPUNIT_ASSERT( stack2.ok() );
  1215   stack1.reset(); stack2.reset();
  1216 
  1217 
  1218   {
  1219     StackString str1("string stack1", stack1);
  1220     StackString str1Cpy(str1);
  1221 
  1222     StackString str2("longer string from stack2 allocator instance for dynamic allocation", stack2);
  1223     StackString str2Cpy(str2);
  1224 
  1225     str1.swap(str2);
  1226 
  1227     CPPUNIT_ASSERT( str1.get_allocator().swaped() );
  1228     CPPUNIT_ASSERT( str2.get_allocator().swaped() );
  1229 
  1230     CPPUNIT_ASSERT( str1 == str2Cpy );
  1231     CPPUNIT_ASSERT( str2 == str1Cpy );
  1232     CPPUNIT_ASSERT( str1.get_allocator() == stack2 );
  1233     CPPUNIT_ASSERT( str2.get_allocator() == stack1 );
  1234   }
  1235   CPPUNIT_ASSERT( stack1.ok() );
  1236   CPPUNIT_ASSERT( stack2.ok() );
  1237   stack1.reset(); stack2.reset();
  1238 
  1239 
  1240   {
  1241     StackString str1("longer string from stack1 allocator instance for dynamic allocation", stack1);
  1242     StackString str1Cpy(str1);
  1243 
  1244     StackString str2("string stack2", stack2);
  1245     StackString str2Cpy(str2);
  1246 
  1247     str1.swap(str2);
  1248 
  1249     CPPUNIT_ASSERT( str1.get_allocator().swaped() );
  1250     CPPUNIT_ASSERT( str2.get_allocator().swaped() );
  1251 
  1252     CPPUNIT_ASSERT( str1 == str2Cpy );
  1253     CPPUNIT_ASSERT( str2 == str1Cpy );
  1254     CPPUNIT_ASSERT( str1.get_allocator() == stack2 );
  1255     CPPUNIT_ASSERT( str2.get_allocator() == stack1 );
  1256   }
  1257   CPPUNIT_ASSERT( stack1.ok() );
  1258   CPPUNIT_ASSERT( stack2.ok() );
  1259   stack1.reset(); stack2.reset();
  1260 #endif
  1261 }
  1262 
  1263 void StringTest::capacity()
  1264 {
  1265   string s;
  1266 
  1267   CPPUNIT_CHECK( s.capacity() > 0 );
  1268   CPPUNIT_CHECK( s.capacity() < s.max_size() );
  1269   CPPUNIT_CHECK( s.capacity() >= s.size() );
  1270 
  1271 #ifndef _STLP_SHORT_STRING_SZ
  1272 #  define _STLP_SHORT_STRING_SZ 16 // see stlport/stl/_string_base.h
  1273 #endif
  1274 
  1275   for ( int i = 0; i < _STLP_SHORT_STRING_SZ + 2; ++i ) {
  1276     s += ' ';
  1277     CPPUNIT_CHECK( s.capacity() > 0 );
  1278     CPPUNIT_CHECK( s.capacity() < s.max_size() );
  1279     CPPUNIT_CHECK( s.capacity() >= s.size() );
  1280   }
  1281 }
  1282 void StringTest::str_cov1()
  1283 	{
  1284 		{
  1285 		string example( "this is an example string" );
  1286 		string::iterator it = example.begin();   
  1287 		example.replace(it+4,example.end()-4,4,'o'); 
  1288 		CPPUNIT_CHECK(example == "thisooooring"  );
  1289 		}
  1290 		{
  1291 		string str4 ( "This perfectly unclear." );
  1292 		basic_string <char>::size_type indexCh4a;
  1293 		string str4a ( "clear" );
  1294 		indexCh4a = str4.rfind ( str4a , 15 );
  1295 		CPPUNIT_CHECK(indexCh4a == -1  );
  1296 		}
  1297 		{
  1298 		string str1f ( "Hello " ), str2f ( "Wide World " );
  1299 		swap(str1f,str2f);
  1300 		CPPUNIT_CHECK(str1f == "Wide World ");	
  1301 		CPPUNIT_CHECK(str2f == "Hello ");	
  1302 		}
  1303 
  1304 	}
  1305 void StringTest::str_cov2()
  1306 	{
  1307 		{
  1308 		string result1a, result1b;
  1309 		string s1o ( "AAAAAAAA" );
  1310 		string s1p ( "BBB" );
  1311 		const char* cs1p = "CCC";
  1312 		result1a = s1o.replace ( 1 , 3 , s1p );
  1313 		CPPUNIT_CHECK(result1a == "ABBBAAAA");
  1314 		result1b = s1o.replace ( 5 , 3 , cs1p );
  1315 		CPPUNIT_CHECK(result1b == "ABBBACCC");
  1316 		string result2a, result2b;
  1317 		string s2o ( "AAAAAAAA" );
  1318 		string s2p ( "BBB" );
  1319 		result2a = s2o.replace ( 1 , 3 , s2p , 1 , 2 );
  1320 		CPPUNIT_CHECK(result2a == "ABBAAAA");
  1321 		string result3a;
  1322 		string s3o ( "AAAAAAAA" );
  1323 		char ch3p = 'C';
  1324 		result3a = s3o.replace ( 1 , 3 , 4 , ch3p );
  1325 		CPPUNIT_CHECK(result3a == "ACCCCAAAA");
  1326 		string s4o ( "AAAAAAAA" );
  1327 		string s4p ( "BBB" );
  1328 		const char* cs4p = "CCC";
  1329 		basic_string<char>::iterator IterF0, IterL0;
  1330 		IterF0 = s4o.begin ( );
  1331 		IterL0 = s4o.begin ( ) + 3;
  1332 		string result4a, result4b;
  1333 		result4a = s4o.replace ( IterF0 , IterL0 , s4p );
  1334 		CPPUNIT_CHECK(result4a == "BBBAAAAA");
  1335 		result4b = s4o.replace ( IterF0 , IterL0 , cs4p );
  1336 		CPPUNIT_CHECK(result4b == "CCCAAAAA");
  1337 		string s5o ( "AAAAAAAF" );
  1338 		const char* cs5p = "CCCBB";
  1339 		basic_string<char>::iterator IterF1, IterL1;
  1340 		IterF1 = s5o.begin ( );
  1341 		IterL1 = s5o.begin ( ) + 4;
  1342 		string result5a;
  1343 		result5a = s5o.replace ( IterF1 , IterL1 , cs5p , 4 );
  1344 		CPPUNIT_CHECK(result5a == "CCCBAAAF");
  1345 		string s6o ( "AAAAAAAG" );
  1346 		char ch6p = 'q';
  1347 		basic_string<char>::iterator IterF2, IterL2;
  1348 		IterF2 = s6o.begin ( );
  1349 		IterL2 = s6o.begin ( ) + 3;
  1350 		string result6a;
  1351 		result6a = s6o.replace ( IterF2 , IterL2 , 4 , ch6p );
  1352 		CPPUNIT_CHECK(result6a == "qqqqAAAAG");
  1353 		}
  1354 	}
  1355 void StringTest::str_cov3()
  1356 	{
  1357 		{
  1358 		string str1 ("This is the sample test string"), str2;
  1359 		basic_string <char>::reverse_iterator str_rIter, str1_rIter, str2_rIter;
  1360 		basic_string <char>::const_reverse_iterator str1_rcIter;
  1361 		str1_rIter = str1.rend ( );
  1362 		str1_rIter--;
  1363 		CPPUNIT_CHECK(*str1_rIter == 'T');
  1364 		str_rIter = str1.rbegin( ); 
  1365 		CPPUNIT_CHECK(*str_rIter == 'g');
  1366 		str1_rcIter = str1.rbegin( );
  1367 		CPPUNIT_CHECK(*str1_rcIter == 'g');
  1368 		str1_rcIter = str1.rend ( );
  1369 		str1_rcIter--;
  1370 		CPPUNIT_CHECK(*str1_rcIter == 'T');
  1371 		}
  1372 		{
  1373 		string str1a ( "Hello " );
  1374 		str1a = "0";
  1375 		CPPUNIT_CHECK(str1a == "0");
  1376 		}
  1377 		{
  1378 		string str1 ("Hello world");
  1379 		CPPUNIT_CHECK(str1.length ( ) == 11);
  1380 		}
  1381 		{
  1382 		int comp5a;
  1383 		string s5o ( "AACAB" );
  1384 		const char* cs5p = "CAB";
  1385 		comp5a = s5o.compare (  2 , 3 , cs5p );
  1386 		CPPUNIT_CHECK(comp5a == 0);		
  1387 		}
  1388 
  1389 	}
  1390 void StringTest::str_cov4()
  1391 	{
  1392 		{
  1393 		string str4 ( "12-ab-12-ab" );
  1394 		basic_string <char>::size_type indexCh4a;
  1395 		string str4a ( "ba3" );
  1396 		indexCh4a = str4.find_last_of  ( str4a , 8 );
  1397 		CPPUNIT_CHECK(indexCh4a == 4);
  1398 		}
  1399 		{
  1400 		string str4 ( "12-ab-12-ab" );
  1401 		basic_string <char>::size_type indexCh4a;
  1402 		string str4a ( "b-a" );
  1403 		indexCh4a = str4.find_last_not_of  ( str4a , 5 );
  1404 		CPPUNIT_CHECK(indexCh4a == 1);
  1405 		}
  1406 		{
  1407 		string str1 ( "abcd-1234-abcd-1234" );
  1408 		basic_string <char>::size_type indexCh1a;
  1409 
  1410 		indexCh1a = str1.find_first_of ( "d" , 5 );
  1411 		CPPUNIT_CHECK(indexCh1a == 13);
  1412 		string str2 ( "12-ab-12-ab" );
  1413 		basic_string <char>::size_type indexCh2a;
  1414 
  1415 		string str2a ( "ba3" );
  1416 		indexCh2a = str2.find_first_of ( str2a , 5 );
  1417 		CPPUNIT_CHECK( indexCh2a == 9 );
  1418 		}
  1419 		{
  1420 		string str4 ( "12-ab-12-ab" );
  1421  	    basic_string <char>::size_type indexCh4a;
  1422 
  1423 		string str4a ( "ba3" );
  1424 		indexCh4a = str4.find_first_not_of ( str4a , 5 );
  1425 		CPPUNIT_CHECK(indexCh4a == 5 );
  1426 		}
  1427 	}
  1428 void StringTest::str_cov5()
  1429 	{
  1430 		{
  1431 		string str4 ( "clearly this perfectly unclear." );
  1432 		basic_string <char>::size_type indexCh4a;
  1433 
  1434 		string str4a ( "clear" );
  1435 		indexCh4a = str4.find ( str4a , 5 );
  1436 		CPPUNIT_CHECK( indexCh4a != string::npos );
  1437 		}
  1438 		{
  1439 		const char *cstr1a = "Hello Out There.";
  1440 		basic_string <char> str1a ( cstr1a , 5);
  1441 		CPPUNIT_CHECK( str1a == "Hello" );	
  1442 		}
  1443 		{
  1444 		string str1a,str1b;
  1445 		const char *cstr1a = "Out There";
  1446 		str1a.assign ( cstr1a );
  1447 		CPPUNIT_CHECK(str1a == "Out There");	
  1448 		
  1449 		str1b.assign ( cstr1a , 3 );
  1450 		CPPUNIT_CHECK(str1b == "Out");	
  1451 		
  1452 		string str1f ( "Hello " ), str2f ( "Wide World " );
  1453 		str1f.assign ( str2f.begin ( ) + 5 , str2f.end ( ) - 1 );
  1454 		CPPUNIT_CHECK(str1f == "World");	
  1455 		}
  1456 		{
  1457 		string str1f ( "Hello " ), str2f ( "Wide World " );
  1458 		str1f.append ( str2f.begin ( ) + 5 , str2f.end ( ) - 1 );
  1459 		CPPUNIT_CHECK(str1f == "Hello World");	
  1460 		
  1461 		string str1b ( "Hello " );
  1462 		const char *cstr1b = "Out There ";
  1463 		str1b.append ( cstr1b , 3 );
  1464 		CPPUNIT_CHECK(str1b == "Hello Out");	
  1465 		}
  1466 	}
  1467 void StringTest::str_cov6()
  1468 	{
  1469 		{
  1470 		string s1 ( "AACAB" );
  1471 		string s2 ( "BACAB" );
  1472 		const char* s3 = "CAB";
  1473 		
  1474 		bool flag;
  1475 		
  1476 		flag = s2 >= s1;
  1477 		CPPUNIT_CHECK(flag == true);		
  1478 		
  1479 		flag = s3 >= s1;
  1480 		CPPUNIT_CHECK(flag == true);		
  1481 		
  1482 		flag = s1 >= s3;
  1483 		CPPUNIT_CHECK(flag == false);
  1484 		
  1485 		flag = s2 > s1;
  1486 		CPPUNIT_CHECK(flag == true);		
  1487 		
  1488 		flag = s3 > s1;
  1489 		CPPUNIT_CHECK(flag == true);		
  1490 		
  1491 		flag = s1 > s3;
  1492 		CPPUNIT_CHECK(flag == false);
  1493 		
  1494 		flag = s2 <= s1;
  1495 		CPPUNIT_CHECK(flag == false);		
  1496 		
  1497 		flag = s3 <= s1;
  1498 		CPPUNIT_CHECK(flag == false);		
  1499 		
  1500 		flag = s1 <= s3;
  1501 		CPPUNIT_CHECK(flag == true);
  1502 		
  1503 		flag = s3 < s1;
  1504 		CPPUNIT_CHECK(flag == false);		
  1505 		
  1506 		flag = s1 < s3;
  1507 		CPPUNIT_CHECK(flag == true);
  1508 		}
  1509 		{
  1510 		string str1 ( "xddd-1234-abcd" );
  1511 		basic_string <char>::size_type indexCh1a;
  1512 
  1513 		indexCh1a = str1.find_first_not_of ( "d" , 2 );
  1514 		CPPUNIT_CHECK(indexCh1a == 4);	
  1515 		}
  1516 	}
  1517