list01.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 702 行 · 第 1/2 页
CPP
702 行
int ans = *it;
for( int i = 0; i < 20 ; i++ ){
if( INSANE( l ) || ans != i || *it != i ) FAIL
if( i%2 ) ans = (*(it++)) + 1;
else ans = *(++it);
}
//and again with const iterator
cit = l.begin();
ans = *cit;
for( int i = 0; i < 20 ; i++ ){
if( INSANE( l ) || ans != i || *cit != i ) FAIL
if( i%2 ) ans = *(cit++) + 1;
else ans = *(++cit);
}
//test decrement
it = l.end();
for( int i = 19; i > 0 ; i-- ){
int ans;
if( i%2 ) ans = *(--it);
else ans = *(it--) - 1;
if( INSANE( l ) || ans != i || *it != i ) FAIL
}
//and again with const iterator
cit = l.end();
for( int i = 19; i > 0 ; i-- ){
int ans;
if( i%2 ) ans = *(--cit);
else ans = *(cit--) - 1;
if( INSANE( l ) || ans != i || *cit != i ) FAIL
}
return( true );
}
/* ------------------------------------------------------------------
* reverse_iterator_test
* make sure reverse iterators do something reasonable
*/
bool reverse_iterator_test( )
{
std::list< int > lst;
for( int i = 1; i <= 10; ++i ) lst.push_back( i );
std::list< int >::reverse_iterator rit = lst.rbegin( );
for( int i = 10; i >= 1; --i ) {
if( *rit != i ) FAIL
++rit;
}
if( rit != lst.rend( ) ) FAIL
return( true );
}
/* ------------------------------------------------------------------
* copy_test
* test copy constructor
*/
bool copy_test()
{
std::list<int> lst1;
for( int i = 0; i < 20; i++ ){
lst1.push_front( -i );
}
std::list<int> lst2(lst1);
if( INSANE( lst1 ) || lst1.size() != 20 ) FAIL
if( INSANE( lst2 ) || lst2.size() != 20 ) FAIL
for( int i = 0; i < 20; i++ ){
if( lst2.back() != -i ) FAIL
lst2.pop_back();
}
return( true );
}
/* ------------------------------------------------------------------
* splice_test
* test list splicing operations
*/
bool splice_test( )
{
std::list< int > lst1, lst2;
//two trivial (empty) lists
lst1.splice( lst1.begin( ), lst2 );
if( INSANE( lst1 ) || INSANE( lst2 ) ||
lst1.size( ) != 0 || lst2.size( ) != 0 ) FAIL
//non-trival list spliced into empty list
for( int i = 1; i <= 10; ++i ) lst2.push_back( i );
lst1.splice( lst1.begin( ), lst2 );
if( INSANE( lst1 ) || INSANE( lst2 ) ||
lst1.size( ) != 10 || lst2.size( ) != 0 ) FAIL
//two non-trivial lists
for( int i = 11; i <= 20; ++i ) lst2.push_back( i );
std::list< int >::iterator it = lst1.begin( );
++it; ++it; ++it; ++it; ++it;
lst1.splice( it, lst2 );
if( INSANE( lst1 ) || INSANE( lst2 ) ||
lst1.size( ) != 20 || lst2.size( ) != 0 ) FAIL
it = lst1.begin( );
//check final list contents
for( int i = 1; i <= 5; ++i ) {
if( *it != i ) FAIL
++it;
}
for( int i = 11; i <= 20; ++i ) {
if( *it != i ) FAIL
++it;
}
for( int i = 6; i <= 10; ++i ) {
if( *it != i ) FAIL
++it;
}
std::list< int > lst3, lst4;
for( int i = 1; i <= 5; ++i ) lst4.push_back( i );
it = lst4.begin( ); ++it; ++it;
lst3.splice( lst3.begin( ), lst4, it );
if( INSANE( lst3 ) || INSANE( lst4 ) ||
lst3.size( ) != 1 || lst4.size( ) != 4 ) FAIL
lst3.splice( lst3.end( ), lst4, lst4.begin( ) );
if( INSANE( lst3 ) || INSANE( lst4 ) ||
lst3.size( ) != 2 || lst4.size( ) != 3 ) FAIL
it = lst4.end( ); --it;
lst3.splice( ++lst3.begin( ), lst4, it );
if( INSANE( lst3 ) || INSANE( lst4 ) ||
lst3.size( ) != 3 || lst4.size( ) != 2 ) FAIL
lst3.splice( lst3.begin( ), lst3, --lst3.end( ) );
if( INSANE( lst3 ) || lst3.size( ) != 3 ) FAIL
//check final list contents
it = lst3.begin( );
if( *it != 1 ) FAIL; ++it;
if( *it != 3 ) FAIL; ++it;
if( *it != 5 ) FAIL;
std::list< int > lst5, lst6;
for( int i = 1; i <= 10; ++i ) lst6.push_back( i );
lst5.splice( lst5.begin( ), lst6, lst6.begin( ), lst6.end( ) );
if( INSANE( lst5 ) || INSANE( lst6 ) ||
lst5.size( ) != 10 || lst6.size( ) != 0 ) FAIL
//check final list contents
it = lst5.begin( );
for( int i = 1; i <= 10; ++i ) {
if( *it != i ) FAIL
++it;
}
return( true );
}
/* ------------------------------------------------------------------
* reverse_test
* test list reverse method
*/
bool reverse_test( )
{
std::list< int > lst;
//try a zero sized list
lst.reverse( );
if( INSANE( lst ) || lst.size( ) != 0 ) FAIL
//try a non-trivial list
for( int i = 1; i <= 10; ++i ) lst.push_back( i );
lst.reverse( );
if( INSANE( lst ) || lst.size( ) != 10 ) FAIL
//check final list contents
std::list< int >::iterator it( lst.begin( ) );
for( int i = 10; i >= 1; --i ) {
if( *it != i ) FAIL
++it;
}
//let's try a reverse iteration too to check out the reverse links
std::list< int >::reverse_iterator rit( lst.rbegin( ) );
for( int i = 1; i <= 10; ++i ) {
if( *rit != i ) FAIL
++rit;
}
return( true );
}
/* ------------------------------------------------------------------
* merge_test
* test list merging methods
*/
struct merge_data {
int A[11];
int B[11];
int R[11];
};
struct merge_data merge_tests[] = {
{ { 0, 2, 4, -1 },
{ 1, 3, 5, -1 },
{ 0, 1, 2, 3, 4, 5, -1 } },
{ { 0, 2, 4, -1 },
{ -1 },
{ 0, 2, 4, -1 } },
{ { -1 },
{ 0, 2, 4, -1 },
{ 0, 2, 4, -1 } },
{ { 1, 3, 5, -1 },
{ 1, 2, -1 },
{ 1, 1, 2, 3, 5, -1 } },
{ { 1, 2, -1 },
{ 1, 3, 5, -1 },
{ 1, 1, 2, 3, 5, -1 } },
{ { 1, 2, -1 },
{ 3, 4, 5, -1 },
{ 1, 2, 3, 4, 5, -1 } },
{ { 3, 4, 5, -1 },
{ 1, 2, -1 },
{ 1, 2, 3, 4, 5, -1 } }
};
const int merge_test_count = sizeof(merge_tests)/sizeof(merge_data);
bool merge_test( )
{
int *p;
for( int test_no = 0; test_no < merge_test_count; ++test_no ) {
std::list< int > lst_1, lst_2;
//prepare the two lists and merge them.
p = merge_tests[test_no].A;
while( *p != -1 ) { lst_1.push_back( *p ); ++p; }
p = merge_tests[test_no].B;
while( *p != -1 ) { lst_2.push_back( *p ); ++p; }
lst_1.merge( lst_2 );
//did it work?
if( INSANE( lst_1 ) || INSANE( lst_2 ) ) FAIL;
p = merge_tests[test_no].R;
while( *p != -1 ) {
if( lst_1.front( ) != *p ) FAIL;
lst_1.pop_front( );
++p;
}
}
return( true );
}
/* ------------------------------------------------------------------
* allocator_test
* test stateful allocators and exception handling
*/
bool allocator_test( )
{
typedef std::list< int, LowMemAllocator<int> > list_t;
LowMemAllocator<int> mem(100);
mem.SetTripOnAlloc();
list_t lst( mem );
bool thrown = false;
//LowMemAllocator is set to trip after 100 allocations
try{
for( int i=0; i<101; i++ ){
lst.push_front( i );
}
}catch( std::bad_alloc const & ){
mem = lst.get_allocator();
if( mem.GetNumAllocs() != 101 ) FAIL //should fail on 101st
if( INSANE(lst) || lst.size() != 99 ) FAIL //one alloc for sentinel
thrown = true;
}
if( !thrown ) FAIL //exception should have been thrown
lst.clear();
mem.Reset(100);
mem.SetTripOnConstruct();
thrown = false;
//LowMemAllocator is set to trip after 100 allocations
try{
for( int i=0; i<101; i++ ){
lst.push_back( i );
}
}catch( std::bad_alloc const & ){
mem = lst.get_allocator();
if( mem.GetNumConstructs() != 101 ) FAIL
//should have cleaned up last one and left only 100 allocated items
if( mem.GetNumAllocs() != 101 || mem.GetNumDeallocs() != 1 ) FAIL
if( INSANE(lst) || lst.size() != 100 ) FAIL
thrown = true;
}
if( !thrown ) FAIL //exception should have been thrown
//if container didn't deal with the exception and clean up the allocated
//memory then the leak detector will also trip later
lst.clear();
mem.Reset(100);
thrown = false;
for( int i = 0; i < 70; i++ ){
lst.push_back( i );
}
//now reset the allocator so it trips at a lower threshold
//and test the copy mechanism works right
mem.Reset( 50 );
mem.SetTripOnAlloc();
try{
list_t lst2( lst );
}catch( std::bad_alloc ){
if( mem.GetNumConstructs() != 49 ) FAIL //sentinel not constructed
if( mem.GetNumAllocs() != 51 ) FAIL
if( mem.GetNumDestroys() != 49 ) FAIL //sentinel not destroyed
if( mem.GetNumDeallocs() != 50 ) FAIL
if( INSANE( lst ) || lst.size() != 70 ) FAIL
thrown = true;
}
if( !thrown ) FAIL
return( true );
}
int main( )
{
int rc = 0;
int original_count = heap_count( );
//heap_dump();
try {
if( !construct_test( ) || !heap_ok( "t01" ) ) rc = 1;
if( !access_test( ) || !heap_ok( "t02" ) ) rc = 1;
//if( !string_test( ) || !heap_ok( "t03" ) ) rc = 1;
//if( !torture_test( ) || !heap_ok( "t04" ) ) rc = 1;
if( !assign_test( ) || !heap_ok( "t05" ) ) rc = 1;
if( !clear_test( ) || !heap_ok( "t06" ) ) rc = 1;
if( !erase_test( ) || !heap_ok( "t07" ) ) rc = 1;
if( !swap_test( ) || !heap_ok( "t08" ) ) rc = 1;
if( !remove_test( ) || !heap_ok( "t09" ) ) rc = 1;
if( !iterator_test( ) || !heap_ok( "t10" ) ) rc = 1;
if( !reverse_iterator_test( ) || !heap_ok( "t11" ) ) rc = 1;
if( !copy_test( ) || !heap_ok( "t12" ) ) rc = 1;
if( !splice_test( ) || !heap_ok( "t13" ) ) rc = 1;
if( !reverse_test( ) || !heap_ok( "t14" ) ) rc = 1;
if( !merge_test( ) || !heap_ok( "t15" ) ) rc = 1;
if( !allocator_test( ) || !heap_ok( "t16" ) ) rc = 1;
}
catch( ... ) {
std::cout << "Unexpected exception of unexpected type.\n";
rc = 1;
}
if( heap_count( ) != original_count ) {
std::cout << "Possible memory leak!\n";
heap_dump();
rc = 1;
}
return( rc );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?