deque01.cpp

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

CPP
707
字号
/****************************************************************************
*
*                            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::deque.
*
****************************************************************************/

#include <algorithm>
#include <iostream>
#include <stdexcept>
#include <string>
#include <deque>

#include "sanity.cpp"

bool construction_test( )
{
  bool rc = true;
  std::deque< int > d1;
  std::deque< int > d2(10);
  std::deque< int > d3(d1);
  std::deque< int > d4(d2);
  std::deque< int > d5(10, 1);

  if( d1.size( ) !=  0 || !d1.empty( ) || INSANE( d1 ) ) FAIL
  if( d2.size( ) != 10 ||  d2.empty( ) || INSANE( d2 ) ) FAIL
  if( d3.size( ) !=  0 || !d3.empty( ) || INSANE( d3 ) ) FAIL
  if( d4.size( ) != 10 ||  d4.empty( ) || INSANE( d4 ) ) FAIL
  if( d5.size( ) != 10 ||  d5.empty( ) || INSANE( d5 ) ) FAIL

  // Use checked access so that we get an exception if something's wrong.
  for( std::deque< int >::size_type i = 0; i < d5.size( ); ++i ) {
    if( d5.at( i ) != 1 ) FAIL
  }

  // Try a non-contiguous copy construction. The test deque has size 10
  // which is less than the size where a reallocation is done (15).
  //
  std::deque< int > d6;
  for( std::deque< int >::size_type i = 6; i <= 10; ++i ) {
    d6.push_back( static_cast< int >( i ) );
  }
  for( std::deque< int >::size_type i = 5; i >= 1; --i ) {
    d6.push_front( static_cast< int >( i ) );
  }
  std::deque< int > d7( d6 );
  if( d7.size( ) != 10 || INSANE( d7 ) ) FAIL;
  for( std::deque< int >::size_type i = 0; i < 10; ++i ) {
    if( d6[i] != i + 1 ) FAIL;
  }

  return( rc );
}

bool access_test( )
{
  using std::out_of_range;

  bool rc = true;
  std::deque< int > d(10);

  for (int i = 0; i < 10; ++i )     d[i]  = i;
  for (int i = 0; i < 10; ++i ) if( d[i] != i ) FAIL
  for (int i = 0; i < 10; ++i )     d.at( i )  = i;
  for (int i = 0; i < 10; ++i ) if( d.at( i ) != i ) FAIL

  try {
    d.at( 10 ) = 0;
    FAIL
  }
  catch( out_of_range ) {
    // Okay
  }

  return( rc );
}

#ifdef __NEVER

bool assign_test( )
{
  bool rc = true;
  std::deque< int > d1(10, 1);
  std::deque< int > d2( 5, 2);
  std::deque< int > d3(15, 3);

  d1 = d2;
  if( d1.size( ) != 5  || INSANE( d1 ) ) FAIL;

  for( std::deque< int >::size_type i = 0; i < d1.size( ); ++i ) {
    if( d1.at( i ) != 2 ) FAIL;
  }

  d1 = d3;
  if( d1.size( ) != 15 || INSANE( d1 ) ) FAIL;

  for( std::deque< int >::size_type i = 0; i < d1.size( ); ++i ) {
    if( d1.at( i ) != 3 ) FAIL;
  }

  d1.assign( 10, 4 );
  if( d1.size( ) != 10 || INSANE( d1 ) ) FAIL;

  for( std::deque< int >::size_type i = 0; i < d1.size( ); ++i ) {
    if( d1.at( i ) != 4 ) FAIL;
  }

  d1.assign( 20, 5 );
  if( d1.size( ) != 20 || INSANE( d1 ) ) FAIL;

  for( std::deque< int >::size_type i = 0; i < d1.size( ); ++i ) {
    if( d1.at( i ) != 5 ) FAIL;
  }

  return( rc );
}

#endif

template< class Type >
bool pushfront_test(const Type *check, std::size_t check_size )
{
  using std::deque;  // Make sure this works.

  bool rc = true;
  deque< Type > deq;

  for( typename deque< Type >::size_type i = 0; i < check_size; ++i ) {
    deq.push_front( check[i] );
    if( deq.back( )  != check[0] ) FAIL;
    if( deq.front( ) != check[i] ) FAIL;
  }
  if( deq.size( ) != check_size || INSANE( deq ) ) FAIL;

  std::reverse( deq.begin( ), deq.end( ) );
  for( typename deque< Type >::size_type i = 0; i < check_size; ++i ) {
    if( deq.back( )  != check[check_size - 1 - i] ) FAIL;
    if( deq.front( ) != check[0] ) FAIL;
    deq.pop_back( );
  }
  if( deq.size( ) != 0 || INSANE( deq ) ) FAIL;

  return( rc );
}

template< class Type >
bool pushback_test(const Type *check, std::size_t check_size )
{
  using std::deque;  // Make sure this works.

  bool rc = true;
  deque< Type > deq;

  for( typename deque< Type >::size_type i = 0; i < check_size; ++i ) {
    deq.push_back( check[i] );
    if( deq.back( )  != check[i] ) FAIL;
    if( deq.front( ) != check[0] ) FAIL;
  }
  if( deq.size( ) != check_size || INSANE( deq ) ) FAIL;

  std::reverse( deq.begin( ), deq.end( ) );
  for( typename deque< Type >::size_type i = 0; i < check_size; ++i ) {
    if( deq.back( )  != check[i] ) FAIL;
    if( deq.front( ) != check[check_size - 1] ) FAIL;
    deq.pop_back( );
  }
  if( deq.size( ) != 0 || INSANE( deq ) ) FAIL;

  return( rc );
}

static bool midscan_iterator_comp(
  std::deque< int >::iterator p, std::deque< int > &deq )
{
  if(    p <  deq.begin( )   ) FAIL;
  if( !( p >= deq.begin( ) ) ) FAIL;
  if(    p >  deq.end( )   ) FAIL;
  if(    p >= deq.end( )   ) FAIL;
  if( !( p <= deq.end( ) ) ) FAIL;
  if( !( p <  deq.end( ) ) ) FAIL;
  if(    deq.end( ) <  p   ) FAIL;
  if(    deq.end( ) <= p   ) FAIL;
  if( !( deq.end( ) >= p ) ) FAIL;
  if( !( deq.end( ) >  p ) ) FAIL;
  return true;
}

static bool endscan_iterator_comp(
  std::deque< int >::iterator p, std::deque< int > &deq )
{
  if(    p == deq.begin( )   ) FAIL;
  if(    p <  deq.begin( )   ) FAIL;
  if(    p <= deq.begin( )   ) FAIL;
  if( !( p >  deq.begin( ) ) ) FAIL;
  if( !( p >= deq.begin( ) ) ) FAIL;
  if(    p <  deq.end( )   ) FAIL;
  if(    p >  deq.end( )   ) FAIL;
  if( !( p == deq.end( ) ) ) FAIL;
  return true;
}

bool iterator_test( )
{
  // These tests consider that the initial size of a deque is 16.

  bool rc = true;
  int  counter;
  std::deque< int > deq1(15);  // Choose maximum size with no reallocation.
  std::deque< int > deq2;
  std::deque< int >::iterator p;

  // Set up deq1 as a contiguous block.
  for( std::deque< int >::size_type i = 0; i < 15; ++i ) {
    deq1[i] = i;
  }
  // Set up deq2 as non-contiguous with one wrap-around value.
  for( std::deque< int >::size_type i = 1; i <= 14; ++i ) {
    deq2.push_back( static_cast< int >( i ) );
  }
  deq2.push_front( 0 );

  // Use ++p
  counter = 0;
  for( p = deq1.begin( ); p != deq1.end( ); ++p ) {
    if( *p != counter ) FAIL;
    if( !midscan_iterator_comp( p, deq1 ) ) return false;
    ++counter;
  }
  if( !endscan_iterator_comp( p, deq1 ) ) return false;

  counter = 0;
  for( p = deq2.begin( ); p != deq2.end( ); ++p ) {
    if( *p != counter ) FAIL;
    if( !midscan_iterator_comp( p, deq2 ) ) return false;
    ++counter;
  }
  if( !endscan_iterator_comp( p, deq2 ) ) return false;

  // Use p++
  counter = 0;
  for( p = deq1.begin( ); p != deq1.end( ); p++ ) {
    if( *p != counter ) FAIL;
    if( !midscan_iterator_comp( p, deq1 ) ) return false;
    ++counter;
  }
  if( !endscan_iterator_comp( p, deq1 ) ) return false;

  counter = 0;
  for( p = deq2.begin( ); p != deq2.end( ); p++ ) {
    if( *p != counter ) FAIL;
    if( !midscan_iterator_comp( p, deq2 ) ) return false;
    ++counter;
  }
  if( !endscan_iterator_comp( p, deq2 ) ) return false;

  // Build a non-contiguous deque (should have a function for this).
  std::deque< int > deq3;
  for( std::deque< int >::size_type i = 6; i <= 10; ++i ) {
    deq3.push_back( static_cast< int >( i ) );
  }
  for( std::deque< int >::size_type i = 5; i >= 1; --i ) {
    deq3.push_front( static_cast< int >( i ) );
  }
  p = deq3.begin( );
  p += 4; if( *p !=  5 ) FAIL;
  p -= 4; if( *p !=  1 ) FAIL;
  p += 5; if( *p !=  6 ) FAIL;
  p += 4; if( *p != 10 ) FAIL;
  p -= 9; if( *p !=  1 ) FAIL;

  p = deq3.begin( );
  if( *( p + 4 ) !=  5 ) FAIL;
  if( *( 5 + p ) !=  6 ) FAIL;
  if( *( p + 9 ) != 10 ) FAIL;
  p = p + 9;
  if( *( p - 4 ) !=  6 ) FAIL;
  if( *( p - 5 ) !=  5 ) FAIL;
  if( *( p - 9 ) !=  1 ) FAIL;

  return( rc );
}

#ifdef __NEVER

bool insert_single_test( )
{
  bool rc = true;
  typedef std::deque< int >::size_type size_type;
  typedef std::deque< int >::iterator iterator;

  // Try inserting repeatedly at the beginning.
  std::deque< int > v1;
  size_type cap = v1.capacity( );
  int       lim = 4 * cap;
  iterator   it = v1.end( );

  for( int i = 0; i < lim; ++i ) {
    it = v1.insert( it, i );
    if( INSANE( v1 ) ) {
      std::cout << "insert_single FAIL 0001\n"; rc = false;
    }
  }
  int expected_value = lim - 1;
  for( size_type i = 0; i < lim; ++i ) {
    if( v1[i] != expected_value ) {
      std::cout << "insert_single FAIL 0002\n"; rc = false;
    }
    --expected_value;
  }

  // Try inserting repeatedly at the end.
  std::deque< int > v2;
  cap = v2.capacity( );
  lim = 4 * cap;
  it  = v2.end( );

  for( int i = 0; i < lim; ++i ) {
    it = v2.insert( it, i );
    ++it;
    if( INSANE( v2 ) ) {
      std::cout << "insert_single FAIL 0003\n"; rc = false;
    }
  }
  expected_value = 0;
  for( size_type i = 0; i < lim; ++i ) {
    if( v2[i] != expected_value ) {
      std::cout << "insert_single FAIL 0004\n"; rc = false;
    }
    ++expected_value;
  }

⌨️ 快捷键说明

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