📄 string_test.cpp
字号:
//To make GLib C++ closer to STLport behavior we need this macro://Only mandatory when building unit tests without STLport, do not change//anything when building with STLport#define _GLIBCXX_FULLY_DYNAMIC_STRING//Has to be first for StackAllocator swap overload to be taken//into account (at least using GCC 4.0.1)#include "stack_allocator.h"#include <vector>#include <deque>#include <string>#include <algorithm>#if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)# include <sstream>#endif#if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)# include <stdexcept>#endif#if !defined (STLPORT) || defined (_STLP_THREADS)# if defined (STLPORT) && defined (_STLP_PTHREADS) || \ defined (__GNUC__) && !defined (__MINGW32__)# define USE_PTHREAD_API# include <pthread.h># endif# if defined (STLPORT) && defined (_STLP_WIN32THREADS) || \ defined (__GNUC__) && defined (__MINGW32__) || \ defined (_MSC_VER)# define USE_WINDOWS_API# include <windows.h># endif#endif#include "stack_allocator.h"#include "cppunit/cppunit_proxy.h"#if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)using namespace std;#endif//// TestCase class//class StringTest : public CPPUNIT_NS::TestCase{ CPPUNIT_TEST_SUITE(StringTest); CPPUNIT_TEST(constructor); CPPUNIT_TEST(reserve); CPPUNIT_TEST(assign); CPPUNIT_TEST(erase); CPPUNIT_TEST(data); CPPUNIT_TEST(c_str); CPPUNIT_TEST(null_char); CPPUNIT_TEST(insert); CPPUNIT_TEST(replace); CPPUNIT_TEST(resize); CPPUNIT_TEST(short_string); CPPUNIT_TEST(find); CPPUNIT_TEST(rfind); CPPUNIT_TEST(find_last_of); CPPUNIT_TEST(find_last_not_of); CPPUNIT_TEST(copy);#if !defined (USE_PTHREAD_API) && !defined (USE_WINDOWS_API) CPPUNIT_IGNORE;#endif CPPUNIT_TEST(mt); CPPUNIT_STOP_IGNORE; CPPUNIT_TEST(short_string_optim_bug); CPPUNIT_TEST(compare);#if defined (__DMC__) CPPUNIT_IGNORE;#endif CPPUNIT_TEST(template_expression);#if defined (STLPORT) && defined (_STLP_MSVC) && (_STLP_MSVC < 1300)# define TE_TMP_TEST_IGNORED CPPUNIT_IGNORE;#endif CPPUNIT_TEST(te_tmp);#if defined (TE_TMP_TEST_IGNORED) CPPUNIT_STOP_IGNORE;#endif#if defined (STLPORT) && defined (_STLP_NO_WCHAR_T) CPPUNIT_IGNORE;#endif#if defined (__CYGWIN__) && !defined (STLPORT) CPPUNIT_IGNORE;#endif CPPUNIT_TEST(template_wexpression); CPPUNIT_STOP_IGNORE;#if defined (STLPORT) && defined (_STLP_USE_NO_IOSTREAMS) CPPUNIT_IGNORE;#endif CPPUNIT_TEST(io); CPPUNIT_STOP_IGNORE;#if defined (STLPORT) && defined (_STLP_NO_CUSTOM_IO) CPPUNIT_IGNORE;#endif CPPUNIT_TEST(allocator_with_state); CPPUNIT_STOP_IGNORE; CPPUNIT_TEST(capacity); CPPUNIT_TEST_SUITE_END();protected: void constructor(); void reserve(); void erase(); void data(); void c_str(); void null_char(); void insert(); void replace(); void resize(); void short_string(); void find(); void rfind(); void find_last_of(); void find_last_not_of(); void copy(); void assign(); void mt(); void short_string_optim_bug(); void compare(); void template_expression(); void te_tmp(); void template_wexpression(); void io(); void allocator_with_state(); void capacity(); static string func(const string& par) { string tmp( par ); return tmp; }#if defined (USE_PTHREAD_API) || defined (USE_WINDOWS_API)# if defined (USE_PTHREAD_API) static void* f(void*)# else static DWORD __stdcall f(void*)# endif { string s( "qyweyuewunfkHBUKGYUGL,wehbYGUW^(@T@H!BALWD:h^&@#*@(#:JKHWJ:CND" ); for ( int i = 0; i < 2000000; ++i ) { string sx = func( s ); } return 0; }#endif};CPPUNIT_TEST_SUITE_REGISTRATION(StringTest);//// tests implementation//void StringTest::constructor(){#if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) try { string s((size_t)-1, 'a'); CPPUNIT_ASSERT( false ); } catch (length_error const&) { } catch (...) { //Expected exception is length_error: CPPUNIT_ASSERT( false ); }#endif}void StringTest::reserve(){ string s;#if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) try { s.reserve(s.max_size() + 1); CPPUNIT_ASSERT( false ); } catch (length_error const&) { } catch (...) { //Expected exception is length_error: CPPUNIT_ASSERT( false ); }#endif}void StringTest::mt(){#if defined (USE_PTHREAD_API) || defined (USE_WINDOWS_API) const int nth = 2;# if defined (USE_PTHREAD_API) pthread_t t[nth]; for ( int i = 0; i < nth; ++i ) { pthread_create( &t[i], 0, f, 0 ); } for ( int i = 0; i < nth; ++i ) { pthread_join( t[i], 0 ); }# endif // PTHREAD# if defined (USE_WINDOWS_API) //DWORD start = GetTickCount(); HANDLE t[nth]; int i; // VC6 not support in-loop scope of cycle var for ( i = 0; i < nth; ++i ) { t[i] = CreateThread(NULL, 0, f, 0, 0, NULL); } if (WaitForMultipleObjects(nth, t, TRUE, INFINITE) == WAIT_FAILED) { // On some platforms (evc3/evc4) WaitForMultipleObjects() with fWaitAll == TRUE // is not supported. We then wait with a loop on each thread: for ( i = 0; i < nth; ++i ) { WaitForSingleObject(t[i], INFINITE); } } /* DWORD duration = GetTickCount() - start; ostringstream ostr; ostr << "Duration: " << duration << endl; CPPUNIT_MESSAGE(ostr.str().c_str()); */# endif#endif}void StringTest::short_string(){ string const ref_short_str1("str1"), ref_short_str2("str2"); string short_str1(ref_short_str1), short_str2(ref_short_str2); string const ref_long_str1("str 1"); string const ref_long_str2("str 2"); string long_str1(ref_long_str1), long_str2(ref_long_str2); CPPUNIT_ASSERT(short_str1 == ref_short_str1); CPPUNIT_ASSERT(long_str1 == ref_long_str1); { string str1(short_str1); str1 = long_str1; CPPUNIT_ASSERT(str1 == ref_long_str1); } { string str1(long_str1); str1 = short_str1; CPPUNIT_ASSERT(str1 == ref_short_str1); } { short_str1.swap(short_str2); CPPUNIT_ASSERT((short_str1 == ref_short_str2) && (short_str2 == ref_short_str1)); short_str1.swap(short_str2); } { long_str1.swap(long_str2); CPPUNIT_ASSERT((long_str1 == ref_long_str2) && (long_str2 == ref_long_str1)); long_str1.swap(long_str2); } { short_str1.swap(long_str1); CPPUNIT_ASSERT((short_str1 == ref_long_str1) && (long_str1 == ref_short_str1)); short_str1.swap(long_str1); } { long_str1.swap(short_str1); CPPUNIT_ASSERT((short_str1 == ref_long_str1) && (long_str1 == ref_short_str1)); long_str1.swap(short_str1); } { //This is to test move constructor vector<string> str_vect; str_vect.push_back(short_str1); str_vect.push_back(long_str1); str_vect.push_back(short_str2); str_vect.push_back(long_str2); CPPUNIT_ASSERT((str_vect[0] == ref_short_str1) && (str_vect[1] == ref_long_str1) && (str_vect[2] == ref_short_str2) && (str_vect[3] == ref_long_str2)); }}void StringTest::erase(){ char const* c_str = "Hello, World!"; string str(c_str); CPPUNIT_ASSERT( str == c_str ); str.erase(str.begin() + 1, str.end() - 1); // Erase all but first and last. size_t i; for (i = 0; i < str.size(); ++i) { switch ( i ) { case 0: CPPUNIT_ASSERT( str[i] == 'H' ); break; case 1: CPPUNIT_ASSERT( str[i] == '!' ); break; default: CPPUNIT_ASSERT( false ); } } str.insert(1, c_str); str.erase(str.begin()); // Erase first element. str.erase(str.end() - 1); // Erase last element. CPPUNIT_ASSERT( str == c_str ); str.clear(); // Erase all. CPPUNIT_ASSERT( str.empty() ); str = c_str; CPPUNIT_ASSERT( str == c_str ); str.erase(1, str.size() - 1); // Erase all but first and last. for (i = 0; i < str.size(); i++) { switch ( i ) { case 0: CPPUNIT_ASSERT( str[i] == 'H' ); break; case 1: CPPUNIT_ASSERT( str[i] == '!' ); break; default: CPPUNIT_ASSERT( false ); } } str.erase(1); CPPUNIT_ASSERT( str == "H" );}void StringTest::data(){ string xx; CPPUNIT_ASSERT( xx.data() != 0 ); // ISO-IEC-14882:1998(E), 21.3.6, paragraph 3#if 0 /* This test really not required: in ISO-IEC-14882:1998(E) paragraph 3 stated: * '... and can have zero added to it', again: 'CAN', but not 'MUST'. * That's why I am comment this test. But I don't remove it due to I had * unevident problem with misinterpretation of data() return (i.e. data() * and c_str() provide different functionality!) and expect that this is * more-or-less common pitfall. * - ptr */ string low( "2004-01-01" ); // Blocks A and B should follow each other. // Block A: xx = "123456"; xx += low; if ( strcmp( xx.data(), "1234562004-01-01" ) != 0 ) { return -1; } // End of block A // Block B: xx = "1234"; xx += ";"; if ( strcmp( xx.data(), "1234;" ) != 0 ) { return -1; } // End of block B#endif}void StringTest::c_str(){ string low( "2004-01-01" ); string xx; string yy; CPPUNIT_ASSERT( *(yy.c_str()) == '\0' ); // ISO-IEC-14882:1998(E), 21.3.6, paragraph 1 // Blocks A and B should follow each other. // Block A: xx = "123456"; xx += low; CPPUNIT_ASSERT( strcmp( xx.c_str(), "1234562004-01-01" ) == 0 ); // End of block A // Block B: xx = "1234"; xx += ";"; CPPUNIT_ASSERT( strcmp( xx.c_str(), "1234;" ) == 0 ); // End of block B}void StringTest::null_char(){ // ISO/IEC 14882:1998(E), ISO/IEC 14882:2003(E), 21.3.4 ('... the const version') const string s( "123456" ); CPPUNIT_CHECK( s[s.size()] == '\0' );#if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) try { //Check is only here to avoid warning about value of expression not used CPPUNIT_CHECK( s.at(s.size()) == '\0' ); CPPUNIT_ASSERT( false ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -