list01.cpp

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 702 行 · 第 1/2 页

CPP
702
字号
/****************************************************************************
*
*                            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 the functional tests for std::list.
*
****************************************************************************/

#include <algorithm>
#include <iostream>
#include <list>
#include "sanity.cpp"
#include "allocxtr.hpp"

/* ------------------------------------------------------------------
 * construct_test()
 * test different constructors
 */
bool construct_test( )
{
    using namespace std;
    // test ctor( size_t, value )
    list< char > lst1( 99, 'd' );
    int i;
    
    if( INSANE(lst1) || lst1.size() != 99 || lst1.empty() ) FAIL
    for( i = 0; i < 99; i++ ){
        if( lst1.back() != 'd' ) FAIL
        lst1.pop_back();
    }
    if( INSANE(lst1) || lst1.size() || !lst1.empty() ) FAIL
    
    // test type dependent ctor
    // first when it template param is iterator
    int x[] = { 1,2,3,4,5,6 };
    list< int > lst2( x, x+6, allocator< int >() );
    if( INSANE(lst2) || lst2.size() != 6 || lst2.empty() ) FAIL
    for( i = 0; i < 6; i++ ){
        if( lst2.front() != i+1 ) FAIL
        lst2.pop_front();
    }
    if( INSANE(lst2) || lst2.size() || !lst2.empty() ) FAIL
    
    // now when template param is integer
    // hmmm, need to think of example when this version of template constructor
    // will get called, currently just converts params and calls explicit ctor
    // is this right? do we not need int version of templated ctor?
    list< int > lst3( 77L, 88L, allocator< int >() );
    if( INSANE(lst3) || lst3.size() != 77 || lst3.empty() ) FAIL
    for( i = 0; i < 77; i++ ){
        if( lst3.front() != 88 ) FAIL
        lst3.pop_front();
    }
    if( INSANE(lst3) || lst1.size() || !lst3.empty() ) FAIL
    
    return( true );
}

/* ------------------------------------------------------------------
 * access_test
 * test insert, push_front, push_back, erase, pop_front, pop_back 
 */
bool access_test( )
{
    typedef std::list< int > list_t;
    list_t lst;
    list_t::iterator it;
    int i;
    //test insert
    for( i = 0; i < 10 ; i++ ){
        lst.insert( lst.begin(), i );
    }//now contains 9...0
    for( it = lst.begin(), i = 9; i >= 0; --i, ++it ){
        //std::cout<<*it<<",";
        if( INSANE(lst) || *it != i ) FAIL
    }
    //test push_front
    for( i = 10; i < 20 ; i++ ){
        lst.push_front( i );
    }//now contains 19...0
    for( it = lst.begin(), i = 19; i >= 0; --i, ++it ){
        if( INSANE(lst) || *it != i ) FAIL
    }
    //test push_back
    for( i = -1; i > -11; i-- ){
        lst.push_back( i );
    }//now contains 19...-10
    for( it = lst.begin(), i = 19; i >= -10; --i, ++it ){
        if( INSANE(lst) || *it != i ) FAIL
    }
    //test erase
    it = lst.begin();
    for( i = 0; i < 30; i+=2 ){
        lst.erase( it++ );
        ++it;
    }//now contains evens 18...-10
    for( it = lst.begin(), i = 18; i >= -10; i-=2, ++it ){
        if( INSANE(lst) || *it != i ) FAIL
    }
    //test pop_front
    for( i = 18; i > 8; i-=2 ){
        if( lst.front() != i ) FAIL
        lst.pop_front( );
    }//now contains evens 8...-10
    for( it = lst.begin(), i = 8; i >= -10; i-=2, ++it ){
        if( INSANE(lst) || *it != i ) FAIL
    }
    //test pop_back
    for( i = -10; i < 4; i+=2 ){
        if( lst.back() != i ) FAIL
        lst.pop_back( );
    }//now contains 8,6,4
    for( it = lst.begin(), i = 8; i >= 4; i-=2, ++it ){
        if( INSANE(lst) || *it != i ) FAIL
    }
    lst.front() = 5;
    lst.back() = 7;
    for( it = lst.begin(), i = 5; i <= 7; ++i, ++it ){
        if( INSANE(lst) || *it != i ) FAIL
    }
    // insert( it, size_type, value )
    lst.clear();
    lst.insert( lst.begin(), (list_t::size_type)4, (list_t::value_type)9 );
    for( it = lst.begin(), i = 0; it != lst.end(); ++it ){
        if( INSANE(lst) || *it != 9 ) FAIL
        i++;
    }
    if( INSANE(lst) || i != 4 ) FAIL
    // template insert, int params
    lst.insert( lst.begin(), 5, 8 ); // now contains 4 9s and 5 8s
    for( it = lst.begin(), i = 0; it != lst.end(); ++it ){
        i += *it;
    }
    if( INSANE(lst) || i != 4*9+5*8 ) FAIL
    
    // template insert, iterator params
    int v[] = { 0,1,4,9,16 };
    lst.clear();
    lst.insert( lst.begin(), v, v+sizeof(v)/sizeof(v[0]) );
    if( INSANE(lst) || lst.size() != 5 ) FAIL
    for( it = lst.begin(), i = 0; it != lst.end(); ++it, ++i ){
        if( INSANE(lst) || *it != i*i ) FAIL
    }
    
    return( true );
}

/* ------------------------------------------------------------------
 * assign_test
 * test list assignment methods
 */
bool assign_test( )
{
    std::list< int > lst1, lst2;
    
    // check operator=
    for( int i =  1; i <= 10; ++i ) lst1.push_back( i );
    for( int i = 11; i <= 15; ++i ) lst2.push_back( i );
    lst1 = lst2;
    if( INSANE( lst1 ) || INSANE( lst2 ) ) FAIL
    if( lst1.size( ) != 5 || lst2.size( ) != 5 ) FAIL
    int i = 11;
    std::list< int >::iterator it = lst1.begin( );
    while( it != lst1.end( ) ) {
        if( *it != i ) FAIL
        ++i; ++it;
    }

    // check assign method (cast types so matches fn, not template fn)
    lst1.assign( (std::list<int>::size_type)10, -1 );
    if( INSANE( lst1 ) || lst1.size( ) != 10 ) FAIL
    for( it = lst1.begin( ); it != lst1.end( ); ++it ) {
        if( *it != -1 ) FAIL
    }
    
    // template assign, non integer types
    int x[] = { 50,51,52,53,54 };
    lst2.assign( x, x+5 );
    if( INSANE(lst2) || lst2.size() != 5 ) FAIL
    for( i = 0; i < 5; i++){
        if( lst2.front() != i+50 ) FAIL
        lst2.pop_front();
    }
    if( INSANE(lst2) || !lst2.empty() ) FAIL
    
    // template assign, integer types
    lst2.assign( 20, 50 );
    if( INSANE(lst2) || lst2.size() != 20 ) FAIL
    for( i = 0; i < 20; i++){
        if( lst2.front() != 50 ) FAIL
        lst2.pop_front();
    }
    if( INSANE(lst2) || !lst2.empty() ) FAIL
    
    return( true );
}

/* ------------------------------------------------------------------
 * clear_test
 * test removal of elements, clear and destructor
 */
bool clear_test()
{
    std::list< int > lst, lst2, lst3;
    typedef std::list< int > list_t;
    list_t* lstp = new list_t;
    
    for( int i = 0; i < 10; i++ ){
        lst.push_front( i );
        lst2.push_front( i );
        lst3.push_front( i );
        lstp->push_front( i );
        if( INSANE( lst ) || lst.front() != i || lst.size() != i+1 ) FAIL
        if( INSANE( lst2 ) || lst.front() != i || lst.size() != i+1 ) FAIL
        if( INSANE( lst3 ) || lst.front() != i || lst.size() != i+1 ) FAIL
        if( INSANE( *lstp ) || lstp->front() != i || lst.size() != i+1 ) FAIL
    }
    //test clear
    lst.clear();
    if( INSANE( lst ) || lst.size() || !lst.empty() ) FAIL
    lst.clear();
    if( INSANE( lst ) || lst.size() || !lst.empty() ) FAIL
    //test removal
    for( int i = 0; i < 10; i++ ) lst2.pop_front();
    if( INSANE( lst2 ) || lst2.size() || !lst2.empty() ) FAIL
    //test destructor call
    delete lstp;
    //lst3 is cleared automatically 
    //(leak detect will fire if destructor is wrong)
    return( true );
}

/* ------------------------------------------------------------------
 * erase_test
 * test two argument form of erase
 */
bool erase_test( )
{
    using namespace std;  //try this for something different.
    //build a list.
    list< int > lst;
    for( int i = 1; i <= 20; ++i ) lst.push_back( i );
    list< int >::iterator it = find( lst.begin( ), lst.end( ), 11 );
    //do the deed
    lst.erase( lst.begin( ), it );
    if( INSANE( lst ) || lst.size( ) != 10 ) FAIL
    it = lst.begin( );
    for( int i = 1; i <= 10; ++i ) {
        if( *it != i + 10 ) FAIL
        ++it;
    }
    //erase everything
    lst.erase( lst.begin( ), lst.end( ) );
    if( INSANE( lst ) || lst.size( ) != 0 ) FAIL
    return( true );
}

/* ------------------------------------------------------------------
 * swap_test
 * test list swapping method
 */
bool swap_test( )
{
    std::list< int > lst_1, lst_2;
    lst_1.push_back( 1 );
    //try a swap and then check the result
    lst_1.swap( lst_2 );
    if( INSANE( lst_1 )    || INSANE( lst_2 ) ||
        lst_1.size( ) != 0 || lst_2.size( ) != 1) FAIL
    if( lst_2.front( ) != 1 ) FAIL
    //add some things to lst_1 and swap again
    lst_1.push_back( 10 );
    lst_1.push_back( 11 );
    lst_1.swap( lst_2 );
    if( INSANE( lst_1 )    || INSANE( lst_2 ) ||
        lst_1.size( ) != 1 || lst_2.size( ) != 2) FAIL
    if( lst_1.front( ) != 1 ) FAIL
    if( lst_2.front( ) != 10 ) FAIL
    lst_2.pop_front( );
    if( lst_2.front( ) != 11 ) FAIL
    return( true );
}

/* ------------------------------------------------------------------
 * remove_test( )
 * test the remove methods
 */
bool remove_test( )
{
    typedef std::list< int > l_t;
    l_t l;
    //prepare the list
    l.push_back( 0 );
    for( int i = 1; i <= 10; i++ ) {
        l.push_back( i );
    }
    l.push_back( 0 );
    l.push_back( 0 );
    for( int i = 11; i <= 20; i++ ) {
        l.push_back( i );
    }
    l.push_back( 0 );
    //do the deed
    l.remove( 0 );
    //did it work?
    if( INSANE( l ) || l.size( ) != 20 ) FAIL
    l_t::iterator it( l.begin( ) );
    for( int i = 1; i <= 20; i++ ) {
        if( *it != i ) FAIL
        ++it;
    }
    return( true );
}

/* ------------------------------------------------------------------
 * iterator_test( )
 * Test the iterator functionality
 */
bool iterator_test( )
{
    typedef std::list< int > l_t;
    l_t l;
    l_t::iterator it;
    l_t::const_iterator cit;
    for( int i = 0; i < 20; i++ ){
        l.push_back( i );
    }
    //test increment and dereferencing
    it = l.begin();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?