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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
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
20 #define _GLIBCXX_FULLY_DYNAMIC_STRING
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"
30 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
34 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
38 #if !defined (STLPORT) || defined (_STLP_THREADS)
39 # if defined (STLPORT) && defined (_STLP_PTHREADS) || \
40 defined (__GNUC__) && !defined (__MINGW32__)
41 # define USE_PTHREAD_API
45 # if defined (STLPORT) && defined (_STLP_WIN32THREADS) || \
46 defined (__GNUC__) && defined (__MINGW32__) || \
48 # define USE_WINDOWS_API
53 #include "stack_allocator.h"
54 #include "cppunit/cppunit_proxy.h"
56 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
63 class StringTest : public CPPUNIT_NS::TestCase
65 CPPUNIT_TEST_SUITE(StringTest);
66 CPPUNIT_TEST(constructor);
67 CPPUNIT_TEST(reserve);
72 CPPUNIT_TEST(null_char);
74 CPPUNIT_TEST(replace);
76 CPPUNIT_TEST(short_string);
79 CPPUNIT_TEST(find_last_of);
80 CPPUNIT_TEST(find_last_not_of);
82 #if !defined (USE_PTHREAD_API) && !defined (USE_WINDOWS_API)
87 CPPUNIT_TEST(short_string_optim_bug);
88 CPPUNIT_TEST(compare);
92 CPPUNIT_TEST(template_expression);
93 #if defined (STLPORT) && defined (_STLP_MSVC) && (_STLP_MSVC < 1300)
94 # define TE_TMP_TEST_IGNORED
98 #if defined (TE_TMP_TEST_IGNORED)
101 #if defined (STLPORT) && defined (_STLP_NO_WCHAR_T)
104 #if defined (__CYGWIN__) && !defined (STLPORT)
107 CPPUNIT_TEST(template_wexpression);
109 #if defined (STLPORT) && defined (_STLP_USE_NO_IOSTREAMS)
114 #if defined (STLPORT) && defined (_STLP_NO_CUSTOM_IO)
117 CPPUNIT_TEST(allocator_with_state);
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();
142 void find_last_not_of();
146 void short_string_optim_bug();
148 void template_expression();
150 void template_wexpression();
152 void allocator_with_state();
160 static string func(const string& par) {
165 #if defined (USE_PTHREAD_API) || defined (USE_WINDOWS_API)
166 # if defined (USE_PTHREAD_API)
167 static void* f(void*)
169 static DWORD __stdcall f(void*)
172 string s( "qyweyuewunfkHBUKGYUGL,wehbYGUW^(@T@H!BALWD:h^&@#*@(#:JKHWJ:CND" );
174 for ( int i = 0; i < 2000000; ++i ) {
175 string sx = func( s );
184 CPPUNIT_TEST_SUITE_REGISTRATION(StringTest);
187 // tests implementation
189 void StringTest::constructor()
191 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
193 string s((size_t)-1, 'a');
194 CPPUNIT_ASSERT( false );
196 catch (length_error const&) {
199 //Expected exception is length_error:
200 CPPUNIT_ASSERT( false );
205 void StringTest::reserve()
208 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
210 s.reserve(s.max_size() + 1);
211 CPPUNIT_ASSERT( false );
213 catch (length_error const&) {
216 //Expected exception is length_error:
217 CPPUNIT_ASSERT( false );
222 void StringTest::mt()
224 #if defined (USE_PTHREAD_API) || defined (USE_WINDOWS_API)
226 # if defined (USE_PTHREAD_API)
229 for ( int i = 0; i < nth; ++i ) {
230 pthread_create( &t[i], 0, f, 0 );
233 for ( int i = 0; i < nth; ++i ) {
234 pthread_join( t[i], 0 );
238 # if defined (USE_WINDOWS_API)
239 //DWORD start = GetTickCount();
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);
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);
257 DWORD duration = GetTickCount() - start;
259 ostr << "Duration: " << duration << endl;
260 CPPUNIT_MESSAGE(ostr.str().c_str());
266 void StringTest::short_string()
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);
274 CPPUNIT_ASSERT(short_str1 == ref_short_str1);
275 CPPUNIT_ASSERT(long_str1 == ref_long_str1);
278 string str1(short_str1);
280 CPPUNIT_ASSERT(str1 == ref_long_str1);
284 string str1(long_str1);
286 CPPUNIT_ASSERT(str1 == ref_short_str1);
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);
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);
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);
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);
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));
327 void StringTest::erase()
329 char const* c_str = "Hello, World!";
331 CPPUNIT_ASSERT( str == c_str );
333 str.erase(str.begin() + 1, str.end() - 1); // Erase all but first and last.
336 for (i = 0; i < str.size(); ++i) {
339 CPPUNIT_ASSERT( str[i] == 'H' );
342 CPPUNIT_ASSERT( str[i] == '!' );
345 CPPUNIT_ASSERT( false );
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() );
357 CPPUNIT_ASSERT( str == c_str );
359 str.erase(1, str.size() - 1); // Erase all but first and last.
360 for (i = 0; i < str.size(); i++) {
363 CPPUNIT_ASSERT( str[i] == 'H' );
366 CPPUNIT_ASSERT( str[i] == '!' );
369 CPPUNIT_ASSERT( false );
374 CPPUNIT_ASSERT( str == "H" );
377 void StringTest::data()
381 CPPUNIT_ASSERT( xx.data() != 0 ); // ISO-IEC-14882:1998(E), 21.3.6, paragraph 3
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.
391 string low( "2004-01-01" );
392 // Blocks A and B should follow each other.
396 if ( strcmp( xx.data(), "1234562004-01-01" ) != 0 ) {
405 if ( strcmp( xx.data(), "1234;" ) != 0 ) {
412 void StringTest::c_str()
414 string low( "2004-01-01" );
418 CPPUNIT_ASSERT( *(yy.c_str()) == '\0' ); // ISO-IEC-14882:1998(E), 21.3.6, paragraph 1
420 // Blocks A and B should follow each other.
424 CPPUNIT_ASSERT( strcmp( xx.c_str(), "1234562004-01-01" ) == 0 );
430 CPPUNIT_ASSERT( strcmp( xx.c_str(), "1234;" ) == 0 );
434 void StringTest::null_char()
436 // ISO/IEC 14882:1998(E), ISO/IEC 14882:2003(E), 21.3.4 ('... the const version')
437 const string s( "123456" );
439 CPPUNIT_CHECK( s[s.size()] == '\0' );
441 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
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 );
447 catch (out_of_range const&) {
448 CPPUNIT_ASSERT( true );
451 CPPUNIT_ASSERT( false );
456 void StringTest::insert()
458 string strorg = "This is test string for string calls";
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
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" );
473 str.insert(15, str.c_str() + 5, 25);
474 CPPUNIT_ASSERT( str == "This is test stis test string for stringring for string calls" );
477 str.insert(0, str.c_str() + str.size() - 4, 4);
478 CPPUNIT_ASSERT( str == "allsThis is test string for string calls" );
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" );
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" );
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" );
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());
502 str0.insert(str0.begin(), 5, '0');
503 CPPUNIT_ASSERT( str0 == "00000" );
507 string::size_type pos = 0, nb = 2;
508 str1.insert(pos, nb, '1');
510 CPPUNIT_ASSERT( str1 == "11" );
512 str0.insert(0, str1);
513 CPPUNIT_ASSERT( str0 == "1100000" );
516 str0.insert(str0.size(), str2, 1, 2);
517 CPPUNIT_ASSERT( str0 == "110000034" );
519 str1.insert(str1.begin() + 1, 2, '2');
520 CPPUNIT_ASSERT( str1 == "1221" );
522 str1.insert(2, "333333", 3);
523 CPPUNIT_ASSERT( str1 == "1233321" );
525 str1.insert(4, "4444");
526 CPPUNIT_ASSERT( str1 == "12334444321" );
528 str1.insert(str1.begin() + 6, '5');
529 CPPUNIT_ASSERT( str1 == "123344544321" );
532 void StringTest::replace()
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.
539 const string v( "78" );
540 string s( "123456" );
541 string const& cs = s;
543 string::iterator i = s.begin() + 1;
544 s.replace(i, i + 3, v.begin(), v.end());
545 CPPUNIT_ASSERT( s == "17856" );
549 s.replace(i, i + 1, v.begin(), v.end());
550 CPPUNIT_ASSERT( s == "1783456" );
554 string::const_iterator ci = s.begin() + 1;
555 s.replace(i, i + 3, ci + 3, cs.end());
556 CPPUNIT_ASSERT( s == "15656" );
561 s.replace(i, i + 3, ci, ci + 2);
562 CPPUNIT_ASSERT( s == "12356" );
567 s.replace(i, i + 3, ci + 1, cs.end());
568 CPPUNIT_ASSERT( s == "1345656" );
571 s.replace(s.begin() + 4, s.end(), cs.begin(), cs.end());
572 CPPUNIT_ASSERT( s == "1234123456" );
575 * This is the test for the template replace method.
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" );
586 s.replace(s.begin() + 4, s.end(), s.begin(), s.end());
587 CPPUNIT_ASSERT( s == "1234123456" );
589 string strorg("This is test string for string calls");
591 str.replace(5, 15, str.c_str(), 10);
592 CPPUNIT_ASSERT( str == "This This is tefor string calls" );
595 str.replace(5, 5, str.c_str(), 10);
596 CPPUNIT_ASSERT( str == "This This is test string for string calls" );
598 #if !defined (STLPORT) || defined (_STLP_MEMBER_TEMPLATES)
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" );
606 void StringTest::resize()
612 CPPUNIT_ASSERT( *s.c_str() == 0 );
617 CPPUNIT_ASSERT( *s.c_str() == 0 );
621 CPPUNIT_ASSERT( s.size() == 1 );
622 CPPUNIT_ASSERT( *s.c_str() == '1' );
623 CPPUNIT_ASSERT( *(s.c_str() + 1) == 0 );
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 );
634 void StringTest::find()
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;
646 # define npos_local string::npos
648 CPPUNIT_ASSERT( s.find("four") == npos_local );
649 CPPUNIT_ASSERT( s.find("one", string::npos) == npos_local );
651 CPPUNIT_ASSERT( s.find_first_of("abcde") == 2 );
653 CPPUNIT_ASSERT( s.find_first_not_of("enotw ") == 9 );
656 void StringTest::rfind()
659 string s("one two three one two three");
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 );
666 string test( "aba" );
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 );
672 CPPUNIT_CHECK( test.rfind( 'a', 2 ) == 2 );
673 CPPUNIT_CHECK( test.rfind( 'a', 1 ) == 0 );
674 CPPUNIT_CHECK( test.rfind( 'a', 0 ) == 0 );
677 void StringTest::find_last_of()
680 string s("one two three one two three");
682 CPPUNIT_ASSERT( s.find_last_of("abcde") == 26 );
684 string test( "aba" );
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 );
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 );
695 void StringTest::find_last_not_of()
698 string s("one two three one two three");
700 CPPUNIT_ASSERT( s.find_last_not_of("ehortw ") == 15 );
702 string test( "aba" );
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 );
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 );
719 void StringTest::copy()
723 dest[0] = dest[1] = dest[2] = dest[3] = 1;
726 CPPUNIT_ASSERT( dest[pos++] == 'f' );
727 CPPUNIT_ASSERT( dest[pos++] == 'o' );
728 CPPUNIT_ASSERT( dest[pos++] == 'o' );
729 CPPUNIT_ASSERT( dest[pos++] == 1 );
731 dest[0] = dest[1] = dest[2] = dest[3] = 1;
734 CPPUNIT_ASSERT( dest[pos++] == 'o' );
735 CPPUNIT_ASSERT( dest[pos++] == 1 );
737 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
740 CPPUNIT_ASSERT( false );
742 catch (out_of_range const&) {
743 CPPUNIT_ASSERT( true );
746 CPPUNIT_ASSERT( false );
751 void StringTest::assign()
754 char const* cstr = "test string for assign";
756 s.assign(cstr, cstr + 22);
757 CPPUNIT_ASSERT( s == "test string for assign" );
759 string s2("other test string");
761 CPPUNIT_ASSERT( s == s2 );
766 // short string optim:
768 // longer than short string:
769 str2 = "1234567890123456789012345678901234567890";
771 CPPUNIT_ASSERT(str1[5] == '6');
772 CPPUNIT_ASSERT(str2[29] == '0');
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.)
786 void StringTest::short_string_optim_bug()
788 string teststr("shortest");
790 bool short_string_optim_bug_helper(string teststr);
792 CPPUNIT_ASSERT(true == short_string_optim_bug_helper(teststr));
795 bool short_string_optim_bug_helper(string teststr)
797 size_t ss = teststr.size();
801 void StringTest::compare()
803 string str1("abcdef");
807 CPPUNIT_ASSERT( str1.compare(str2) == 0 );
809 CPPUNIT_ASSERT( str1.compare(str2) > 0 );
811 CPPUNIT_ASSERT( str1.compare(str2) < 0 );
813 CPPUNIT_ASSERT( str1.compare("abcdef") == 0 );
814 CPPUNIT_ASSERT( str1.compare("abcde") > 0 );
815 CPPUNIT_ASSERT( str1.compare("abcdefg") < 0 );
818 CPPUNIT_ASSERT( str1.compare(2, 3, str2) == 0 );
820 CPPUNIT_ASSERT( str1.compare(2, 3, str2) > 0 );
822 CPPUNIT_ASSERT( str1.compare(2, 3, str2) < 0 );
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 );
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 );
835 class mystring : public string {
838 mystring(string const& s) : string(s) {}
840 mystring& operator = (string const& s) {
841 string::operator = (s);
847 void StringTest::template_expression()
849 string one("one"), two("two"), three("three");
850 string space(1, ' ');
852 // check availability of [un]equality operators
864 (one + two) == three;
865 (one + two) != three;
867 one == (two + three);
868 one != (two + three);
870 (one + two) == "three";
871 (one + two) != "three";
873 "one" == (two + three);
874 "one" != (two + three);
876 (one + two) == (two + three);
877 (one + two) != (two + three);
881 string result(one + ' ' + two + ' ' + three);
882 CPPUNIT_CHECK( result == "one two three" );
886 string result(one + ' ' + two + ' ' + three, 4);
887 CPPUNIT_CHECK( result == "two three" );
891 string result(one + ' ' + two + ' ' + three, 4, 3);
892 CPPUNIT_CHECK( result == "two" );
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 " );
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" );
910 //4 members expressions:
911 CPPUNIT_CHECK( ((one + space) + (two + space)) == "one two " );
916 result = one + space + two;
917 CPPUNIT_CHECK( result == "one two" );
919 result += space + three;
920 CPPUNIT_CHECK( result == "one two three" );
923 //special append method
926 //Use reserve to avoid reallocation and really test auto-referencing problems:
929 result.append(one + space + two);
930 CPPUNIT_CHECK( result == "one two" );
932 result.append(space + result + space + three);
933 CPPUNIT_CHECK( result == "one two one two three" );
936 result.append(space + three, 1, 2);
937 CPPUNIT_ASSERT( result == "one twoth" );
939 result.append(space + result);
940 CPPUNIT_CHECK( result == "one twoth one twoth" );
943 //special assign method
946 //Use reserve to avoid reallocation and really test auto-referencing problems:
949 result.assign(one + space + two + space + three);
950 CPPUNIT_CHECK( result == "one two three" );
952 result.assign(one + space + two + space + three, 3, 5);
953 CPPUNIT_CHECK( result == " two " );
955 result.assign(one + result + three);
956 CPPUNIT_CHECK( result == "one two three" );
960 CPPUNIT_CHECK( !(one + ' ' + two).empty() );
962 char result = (one + ' ' + two)[3];
963 CPPUNIT_CHECK( result == ' ' );
965 result = (one + ' ' + two).at(3);
966 CPPUNIT_CHECK( result == ' ' );
968 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
970 result = (one + ' ' + two).at(10);
971 CPPUNIT_ASSERT(false);
973 catch (out_of_range const&) {
974 CPPUNIT_ASSERT( result == ' ' );
977 CPPUNIT_ASSERT(false);
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;
990 #if !defined (TE_TMP_TEST_IGNORED)
998 superstring( const string& str ) :
1002 superstring operator / (const string& str )
1003 { return superstring( s + "/" + str ); }
1005 superstring operator / (const char* str )
1006 { return superstring( s + "/" + str ); }
1013 void StringTest::te_tmp()
1015 #if !defined (TE_TMP_TEST_IGNORED)
1017 string more( "more" );
1018 string less( "less" );
1020 superstring r = s / (more + less);
1024 void StringTest::template_wexpression()
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' ');
1032 wstring result(one + L' ' + two + L' ' + three);
1033 CPPUNIT_CHECK( result == L"one two three" );
1037 wstring result(one + L' ' + two + L' ' + three, 4);
1038 CPPUNIT_CHECK( result == L"two three" );
1042 wstring result(one + L' ' + two + L' ' + three, 4, 3);
1043 CPPUNIT_CHECK( result == L"two" );
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 " );
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" );
1061 //4 members expressions:
1062 CPPUNIT_CHECK( ((one + space) + (two + space)) == L"one two " );
1067 result = one + space + two;
1068 CPPUNIT_CHECK( result == L"one two" );
1070 result += space + three;
1071 CPPUNIT_CHECK( result == L"one two three" );
1074 //special append method
1077 //Use reserve to avoid reallocation and really test auto-referencing problems:
1080 result.append(one + space + two);
1081 CPPUNIT_CHECK( result == L"one two" );
1083 result.append(space + result + space + three);
1084 CPPUNIT_CHECK( result == L"one two one two three" );
1086 result = L"one two";
1087 result.append(space + three, 1, 2);
1088 CPPUNIT_ASSERT( result == L"one twoth" );
1090 result.append(space + result);
1091 CPPUNIT_CHECK( result == L"one twoth one twoth" );
1094 //special assign method
1097 //Use reserve to avoid reallocation and really test auto-referencing problems:
1100 result.assign(one + space + two + space + three);
1101 CPPUNIT_CHECK( result == L"one two three" );
1103 result.assign(one + space + two + space + three, 3, 5);
1104 CPPUNIT_CHECK( result == L" two " );
1106 result.assign(one + result + three);
1107 CPPUNIT_CHECK( result == L"one two three" );
1111 CPPUNIT_CHECK( !(one + L' ' + two).empty() );
1113 wchar_t result = (one + L' ' + two)[3];
1114 CPPUNIT_CHECK( result == L' ' );
1116 result = (one + L' ' + two).at(3);
1117 CPPUNIT_CHECK( result == L' ' );
1119 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
1121 result = (one + L' ' + two).at(10);
1122 CPPUNIT_ASSERT(false);
1124 catch (out_of_range const&) {
1125 CPPUNIT_ASSERT( result == L' ' );
1128 CPPUNIT_ASSERT(false);
1136 void StringTest::io()
1138 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
1139 string str("STLport");
1143 CPPUNIT_ASSERT( ostr.good() );
1144 CPPUNIT_ASSERT( ostr.str() == str );
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 );
1154 istringstream istr(str);
1156 string istr_content;
1157 istr >> istr_content;
1158 CPPUNIT_ASSERT( !istr.fail() && !istr.eof() );
1159 CPPUNIT_ASSERT( istr_content == "STL" );
1164 void StringTest::allocator_with_state()
1166 #if !(defined (STLPORT) && defined (_STLP_NO_CUSTOM_IO))
1169 StackAllocator<char> stack1(buf1, buf1 + sizeof(buf1));
1172 StackAllocator<char> stack2(buf2, buf2 + sizeof(buf2));
1174 typedef basic_string<char, char_traits<char>, StackAllocator<char> > StackString;
1176 StackString str1("string stack1", stack1);
1177 StackString str1Cpy(str1);
1179 StackString str2("string stack2", stack2);
1180 StackString str2Cpy(str2);
1184 CPPUNIT_ASSERT( str1.get_allocator().swaped() );
1185 CPPUNIT_ASSERT( str2.get_allocator().swaped() );
1187 CPPUNIT_ASSERT( str1 == str2Cpy );
1188 CPPUNIT_ASSERT( str2 == str1Cpy );
1189 CPPUNIT_ASSERT( str1.get_allocator() == stack2 );
1190 CPPUNIT_ASSERT( str2.get_allocator() == stack1 );
1192 CPPUNIT_ASSERT( stack1.ok() );
1193 CPPUNIT_ASSERT( stack2.ok() );
1194 stack1.reset(); stack2.reset();
1197 StackString str1("longer string from stack1 allocator instance for dynamic allocation", stack1);
1198 StackString str1Cpy(str1);
1200 StackString str2("longer string from stack2 allocator instance for dynamic allocation", stack2);
1201 StackString str2Cpy(str2);
1205 CPPUNIT_ASSERT( str1.get_allocator().swaped() );
1206 CPPUNIT_ASSERT( str2.get_allocator().swaped() );
1208 CPPUNIT_ASSERT( str1 == str2Cpy );
1209 CPPUNIT_ASSERT( str2 == str1Cpy );
1210 CPPUNIT_ASSERT( str1.get_allocator() == stack2 );
1211 CPPUNIT_ASSERT( str2.get_allocator() == stack1 );
1213 CPPUNIT_ASSERT( stack1.ok() );
1214 CPPUNIT_ASSERT( stack2.ok() );
1215 stack1.reset(); stack2.reset();
1219 StackString str1("string stack1", stack1);
1220 StackString str1Cpy(str1);
1222 StackString str2("longer string from stack2 allocator instance for dynamic allocation", stack2);
1223 StackString str2Cpy(str2);
1227 CPPUNIT_ASSERT( str1.get_allocator().swaped() );
1228 CPPUNIT_ASSERT( str2.get_allocator().swaped() );
1230 CPPUNIT_ASSERT( str1 == str2Cpy );
1231 CPPUNIT_ASSERT( str2 == str1Cpy );
1232 CPPUNIT_ASSERT( str1.get_allocator() == stack2 );
1233 CPPUNIT_ASSERT( str2.get_allocator() == stack1 );
1235 CPPUNIT_ASSERT( stack1.ok() );
1236 CPPUNIT_ASSERT( stack2.ok() );
1237 stack1.reset(); stack2.reset();
1241 StackString str1("longer string from stack1 allocator instance for dynamic allocation", stack1);
1242 StackString str1Cpy(str1);
1244 StackString str2("string stack2", stack2);
1245 StackString str2Cpy(str2);
1249 CPPUNIT_ASSERT( str1.get_allocator().swaped() );
1250 CPPUNIT_ASSERT( str2.get_allocator().swaped() );
1252 CPPUNIT_ASSERT( str1 == str2Cpy );
1253 CPPUNIT_ASSERT( str2 == str1Cpy );
1254 CPPUNIT_ASSERT( str1.get_allocator() == stack2 );
1255 CPPUNIT_ASSERT( str2.get_allocator() == stack1 );
1257 CPPUNIT_ASSERT( stack1.ok() );
1258 CPPUNIT_ASSERT( stack2.ok() );
1259 stack1.reset(); stack2.reset();
1263 void StringTest::capacity()
1267 CPPUNIT_CHECK( s.capacity() > 0 );
1268 CPPUNIT_CHECK( s.capacity() < s.max_size() );
1269 CPPUNIT_CHECK( s.capacity() >= s.size() );
1271 #ifndef _STLP_SHORT_STRING_SZ
1272 # define _STLP_SHORT_STRING_SZ 16 // see stlport/stl/_string_base.h
1275 for ( int i = 0; i < _STLP_SHORT_STRING_SZ + 2; ++i ) {
1277 CPPUNIT_CHECK( s.capacity() > 0 );
1278 CPPUNIT_CHECK( s.capacity() < s.max_size() );
1279 CPPUNIT_CHECK( s.capacity() >= s.size() );
1282 void StringTest::str_cov1()
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" );
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 );
1298 string str1f ( "Hello " ), str2f ( "Wide World " );
1300 CPPUNIT_CHECK(str1f == "Wide World ");
1301 CPPUNIT_CHECK(str2f == "Hello ");
1305 void StringTest::str_cov2()
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");
1322 string s3o ( "AAAAAAAA" );
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;
1343 result5a = s5o.replace ( IterF1 , IterL1 , cs5p , 4 );
1344 CPPUNIT_CHECK(result5a == "CCCBAAAF");
1345 string s6o ( "AAAAAAAG" );
1347 basic_string<char>::iterator IterF2, IterL2;
1348 IterF2 = s6o.begin ( );
1349 IterL2 = s6o.begin ( ) + 3;
1351 result6a = s6o.replace ( IterF2 , IterL2 , 4 , ch6p );
1352 CPPUNIT_CHECK(result6a == "qqqqAAAAG");
1355 void StringTest::str_cov3()
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 ( );
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 ( );
1370 CPPUNIT_CHECK(*str1_rcIter == 'T');
1373 string str1a ( "Hello " );
1375 CPPUNIT_CHECK(str1a == "0");
1378 string str1 ("Hello world");
1379 CPPUNIT_CHECK(str1.length ( ) == 11);
1383 string s5o ( "AACAB" );
1384 const char* cs5p = "CAB";
1385 comp5a = s5o.compare ( 2 , 3 , cs5p );
1386 CPPUNIT_CHECK(comp5a == 0);
1390 void StringTest::str_cov4()
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);
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);
1407 string str1 ( "abcd-1234-abcd-1234" );
1408 basic_string <char>::size_type indexCh1a;
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;
1415 string str2a ( "ba3" );
1416 indexCh2a = str2.find_first_of ( str2a , 5 );
1417 CPPUNIT_CHECK( indexCh2a == 9 );
1420 string str4 ( "12-ab-12-ab" );
1421 basic_string <char>::size_type indexCh4a;
1423 string str4a ( "ba3" );
1424 indexCh4a = str4.find_first_not_of ( str4a , 5 );
1425 CPPUNIT_CHECK(indexCh4a == 5 );
1428 void StringTest::str_cov5()
1431 string str4 ( "clearly this perfectly unclear." );
1432 basic_string <char>::size_type indexCh4a;
1434 string str4a ( "clear" );
1435 indexCh4a = str4.find ( str4a , 5 );
1436 CPPUNIT_CHECK( indexCh4a != string::npos );
1439 const char *cstr1a = "Hello Out There.";
1440 basic_string <char> str1a ( cstr1a , 5);
1441 CPPUNIT_CHECK( str1a == "Hello" );
1445 const char *cstr1a = "Out There";
1446 str1a.assign ( cstr1a );
1447 CPPUNIT_CHECK(str1a == "Out There");
1449 str1b.assign ( cstr1a , 3 );
1450 CPPUNIT_CHECK(str1b == "Out");
1452 string str1f ( "Hello " ), str2f ( "Wide World " );
1453 str1f.assign ( str2f.begin ( ) + 5 , str2f.end ( ) - 1 );
1454 CPPUNIT_CHECK(str1f == "World");
1457 string str1f ( "Hello " ), str2f ( "Wide World " );
1458 str1f.append ( str2f.begin ( ) + 5 , str2f.end ( ) - 1 );
1459 CPPUNIT_CHECK(str1f == "Hello World");
1461 string str1b ( "Hello " );
1462 const char *cstr1b = "Out There ";
1463 str1b.append ( cstr1b , 3 );
1464 CPPUNIT_CHECK(str1b == "Hello Out");
1467 void StringTest::str_cov6()
1470 string s1 ( "AACAB" );
1471 string s2 ( "BACAB" );
1472 const char* s3 = "CAB";
1477 CPPUNIT_CHECK(flag == true);
1480 CPPUNIT_CHECK(flag == true);
1483 CPPUNIT_CHECK(flag == false);
1486 CPPUNIT_CHECK(flag == true);
1489 CPPUNIT_CHECK(flag == true);
1492 CPPUNIT_CHECK(flag == false);
1495 CPPUNIT_CHECK(flag == false);
1498 CPPUNIT_CHECK(flag == false);
1501 CPPUNIT_CHECK(flag == true);
1504 CPPUNIT_CHECK(flag == false);
1507 CPPUNIT_CHECK(flag == true);
1510 string str1 ( "xddd-1234-abcd" );
1511 basic_string <char>::size_type indexCh1a;
1513 indexCh1a = str1.find_first_not_of ( "d" , 2 );
1514 CPPUNIT_CHECK(indexCh1a == 4);