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 + -
显示快捷键?