string01.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 776 行 · 第 1/2 页
CPP
776 行
/****************************************************************************
*
* Open Watcom Project
*
* Copyright (c) 2004-2006 The Open Watcom Contributors. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: This file contains functional tests for std::string.
* Ideally it should carefully exercise every method.
* Although currently most methods are checked for basic
* operation, many more tests could (and should) be added.
*
****************************************************************************/
#include <iostream>
#include <string>
#include "sanity.cpp"
// The size at when a std::string first has to reallocate. Many of the
// tests below "hard code" this value in the sense that test string
// literals are used that are just smaller or just larger than this
// size. It would be better to generate those test strings at run time
// after looking up the target string's capacity. That way changes to
// std::string's memory allocation policy would not require changes to
// this test program (at least, that would be the hope).
//
const std::string::size_type base_size = 8;
bool construct_test( )
{
bool rc = true;
std::string s1;
std::string s2( "Hello, World" );
std::string s3( "Hello, World", 3 );
std::string s4( s2 );
std::string s5( s2, 7, 2 );
std::string s6( s2, 7, 1024 );
std::string s7( s2, 1 );
std::string s8( 16, 'x' );
if( s1.size( ) != 0 || s1 != "" || INSANE( s1 ) ) FAIL
if( s2.size( ) != 12 || s2 != "Hello, World" || INSANE( s2 ) ) FAIL
if( s3.size( ) != 3 || s3 != "Hel" || INSANE( s3 ) ) FAIL
if( s4.size( ) != 12 || s4 != "Hello, World" || INSANE( s4 ) ) FAIL
if( s5.size( ) != 2 || s5 != "Wo" || INSANE( s5 ) ) FAIL
if( s6.size( ) != 5 || s6 != "World" || INSANE( s6 ) ) FAIL
if( s7.size( ) != 11 || s7 != "ello, World" || INSANE( s7 ) ) FAIL
if( s8.size( ) != 16 || s8 != "xxxxxxxxxxxxxxxx" || INSANE( s8 ) ) FAIL
return( rc );
}
bool assign_test( )
{
bool rc = true;
std::string s1( 5, 'x' );
const char *shrt_string = "Shorty";
const char *long_string = "This string is longer than 8 characters";
const std::string s2( shrt_string );
const std::string s3( long_string );
std::string s4( 5, 'x' );
std::string s5( 5, 'x' );
std::string s6( 5, 'x' );
std::string s7( 5, 'x' );
std::string s8( 5, 'x' );
std::string s9( 5, 'x' );
const char *raw = "This is a very, very long string";
s1 = s2;
if( s1.size( ) != 6 || s1 != shrt_string || INSANE( s1 ) ) FAIL
s1 = s3;
if( s1.size( ) != 39 || s1 != long_string || INSANE( s1 ) ) FAIL
s4 = shrt_string;
if( s4.size( ) != 6 || s4 != shrt_string || INSANE( s4 ) ) FAIL
s4 = long_string;
if( s4.size( ) != 39 || s4 != long_string || INSANE( s4 ) ) FAIL
s5 = 'y';
if( s5.size( ) != 1 || s5 != "y" || INSANE( s5 ) ) FAIL
s6.assign( s3, 35, 5 );
if( s6.size( ) != 4 || s6 != "ters" || INSANE( s6 ) ) FAIL
s6.assign( s3, 5, 16 );
if( s6.size( ) != 16 || s6 != "string is longer" || INSANE( s6 ) ) FAIL
s7.assign( raw, 4 );
if( s7.size( ) != 4 || s7 != "This" || INSANE( s7 ) ) FAIL
s7.assign( raw, 10 );
if( s7.size( ) != 10 || s7 != "This is a " || INSANE( s7 ) ) FAIL
s8.assign( "Shorty" );
if( s8.size( ) != 6 || s8 != "Shorty" || INSANE( s8 ) ) FAIL
s8.assign( long_string );
if( s8.size( ) != 39 || s8 != long_string || INSANE( s8 ) ) FAIL
s9.assign( 7, 'x' );
if( s9.size( ) != 7 || s9 != "xxxxxxx" || INSANE( s9 ) ) FAIL
s9.assign( 8, 'y' );
if( s9.size( ) != 8 || s9 != "yyyyyyyy" || INSANE( s9 ) ) FAIL
return( rc );
}
bool access_test( )
{
bool rc = true;
std::string s1( "Hello, World" );
std::string s2( "Hello, World" );
if( s1[ 0] != 'H' ) FAIL
if( s1[11] != 'd' ) FAIL
s1[ 0] = 'x';
s1[11] = 'y';
if( s1 != "xello, Worly" ) FAIL
if( s2.at( 0 ) != 'H' ) FAIL
if( s2.at( 11 ) != 'd' ) FAIL
s2.at( 0 ) = '-';
s2.at( 11 ) = '+';
if( s2 != "-ello, Worl+" ) FAIL
try {
char ch = s2.at( 12 );
FAIL
}
catch( std::out_of_range ) {
// Okay
}
return( rc );
}
bool relational_test( )
{
bool rc = true;
std::string s1( "abcd" );
std::string s2( "abcd" );
std::string s3( "abcc" );
std::string s4( "abce" );
std::string s5( "abc" );
std::string s6( "abcde" );
// Operator==
if( !( s1 == s2 ) ) FAIL
if( ( s1 == s5 ) ) FAIL
// Operator !=
if( ( s1 != s2 ) ) FAIL
if( !( s5 != s1 ) ) FAIL
// Operator<
if( ( s1 < s2 ) ) FAIL
if( !( s3 < s1 ) ) FAIL
if( ( s4 < s1 ) ) FAIL
if( !( s5 < s1 ) ) FAIL
if( ( s4 < s6 ) ) FAIL
// Operator>
if( !( s4 > s3 ) ) FAIL
if( ( s1 > s6 ) ) FAIL
// Operator <=
if( !( s1 <= s2 && s3 <= s2 ) ) FAIL
if( ( s2 <= s3 || s6 <= s5 ) ) FAIL
// Operator>=
if( !( s2 >= s1 && s6 >= s5 ) ) FAIL
if( ( s3 >= s4 || s5 >= s4 ) ) FAIL
return( rc );
}
bool capacity_test( )
{
bool rc = true;
std::string s1;
std::string s2("Hello, World!");
if( s1.capacity( ) == 0) FAIL
if( s2.size( ) > s2.capacity( ) ) FAIL
if( s1.empty( ) == false ) FAIL
if( s2.empty( ) == true ) FAIL
s2.clear( );
if( s2.empty( ) == false ) FAIL
std::string s3("Hello");
s3.resize( 2 );
if( s3.size( ) != 2 || s3 != "He" ) FAIL
s3.resize( 5, 'x' );
if( s3.size( ) != 5 || s3 != "Hexxx" ) FAIL
s3.resize( 40, 'y' );
if( s3.size( ) != 40 ||
s3 != "Hexxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" ) FAIL
std::string s4("Hello");
std::string::size_type new_s4capacity = ( 7 * s4.capacity( ) ) / 2;
s4.reserve( new_s4capacity );
if( s4.capacity( ) < new_s4capacity || s4.size( ) != 5 || s4 != "Hello" ) {
FAIL
}
return( rc );
}
// This function should probably be some kind of template so it can be
// readily used to check iterators from any kind of sequence container.
//
bool iterator_test( )
{
bool rc = true;
std::string s1( "Hello, World" );
std::string::iterator p1;
std::string::iterator p2;
p1 = s1.begin( );
if( *p1 != 'H' ) FAIL
++p1;
if( *p1 != 'e' ) FAIL
--p1;
if( *p1 != 'H' ) FAIL
p1++;
if( *p1 != 'e' ) FAIL
p1--;
if( *p1 != 'H' ) FAIL
p2 = s1.end( );
--p2;
if( *p2 != 'd' ) FAIL
++p2;
if( p2 != s1.end( ) ) FAIL
if ( p2 < p1 ) FAIL
const std::string s2( "Hello, World" );
std::string::const_iterator p3;
std::string::const_iterator p4;
p3 = s2.begin( );
if( *p3 != 'H' ) FAIL
++p3;
if( *p3 != 'e' ) FAIL
--p3;
if( *p3 != 'H' ) FAIL
p3++;
if( *p3 != 'e' ) FAIL
p3--;
if( *p3 != 'H' ) FAIL
p4 = s2.end( );
--p4;
if( *p4 != 'd' ) FAIL
++p4;
if( p4 != s2.end( ) ) FAIL
if ( p4 < p3 ) FAIL
return( rc );
}
bool append_test( )
{
bool rc = true;
// The sizes of the test strings used here are intended to explore
// both appending without reallocation and appending with re-
// allocation. A string can not be reused between tests because
// an enlarged capacity is never reduced.
std::string s1( "123456" );
std::string s2( "x" );
s1 += s2;
if( s1 != "123456x" || s1.size( ) != 7 || INSANE( s1 ) ) FAIL
s1 += s2;
if( s1 != "123456xx" || s1.size( ) != 8 || INSANE( s1 ) ) FAIL
std::string s3( "123456" );
s3 += "x";
if( s3 != "123456x" || s3.size( ) != 7 || INSANE( s3 ) ) FAIL
s3 += "y";
if( s3 != "123456xy" || s3.size( ) != 8 || INSANE( s3 ) ) FAIL
std::string s4( "123456" );
s4 += 'x';
if( s4 != "123456x" || s4.size( ) != 7 || INSANE( s4 ) ) FAIL
s4 += 'z';
if( s4 != "123456xz" || s4.size( ) != 8 || INSANE( s4 ) ) FAIL
std::string s5( "123456" );
std::string s6( "Hello, World!" );
s5.append( s6, 12, 1 );
if( s5 != "123456!" || s5.size( ) != 7 || INSANE( s5 ) ) FAIL
s5.append( s6, 0, 3 );
if( s5 != "123456!Hel" || s5.size( ) != 10 || INSANE( s5 ) ) FAIL
std::string s7( "123456" );
s7.append( "fizzle", 1 );
if( s7 != "123456f" || s7.size( ) != 7 || INSANE( s7 ) ) FAIL
s7.append( "fizzle", 3 );
if( s7 != "123456ffiz" || s7.size( ) != 10 || INSANE( s7 ) ) FAIL
std::string s8( "123456" );
s8.append( "x" );
if( s8 != "123456x" || s8.size( ) != 7 || INSANE( s8 ) ) FAIL
s8.append( "abc" );
if( s8 != "123456xabc" || s8.size( ) != 10 || INSANE( s8 ) ) FAIL
std::string s9( "123456" );
s9.append( 1, 'x' );
if( s9 != "123456x" || s9.size( ) != 7 || INSANE( s9 ) ) FAIL
s9.append( 3, 'y' );
if( s9 != "123456xyyy" || s9.size( ) != 10 || INSANE( s9 ) ) FAIL
std::string s10( "123456" );
s10.push_back( 'z' );
if( s10 != "123456z" || s10.size( ) != 7 || INSANE( s10 ) ) FAIL
s10.push_back( 'a' );
if( s10 != "123456za" || s10.size( ) != 8 || INSANE( s10 ) ) FAIL
return( rc );
}
bool insert_test( )
{
bool rc = true;
std::string s0( "INSERTED" );
std::string s1( "Hello, World!" );
s1.insert( 2, s0 );
if( s1 != "HeINSERTEDllo, World!" || s1.size( ) != 21 || INSANE( s1 ) ) {
FAIL
}
std::string s2( "Hello, World!" );
s2.insert( 0, s0 );
if( s2 != "INSERTEDHello, World!" || s2.size( ) != 21 || INSANE( s2 ) ) {
FAIL
}
std::string s3( "Hello, World!" );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?