vector.mh

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

MH
955
字号
    if( new_capacity > max_size( ) )
        throw length_error( "vector::reserve" );

    size_type temp_length;
    pointer temp_buffer = alloc( new_capacity, temp_length );
    try {
        uninitialized_copy( buffer, buffer + vec_length, temp_buffer );
    }
    catch( ... ) {
        mem.deallocate( temp_buffer, temp_length );
        throw;
    }

    // New allocation successful.
    for( size_type i = 0; i < vec_length; ++i ) {
        mem.destroy( &buffer[i] );
    }
    mem.deallocate( buffer, buf_length );

    buffer     = temp_buffer;
    buf_length = temp_length;
}

// operator[]( size_type )
// ***********************
template< class Type, class Allocator >
inline
typename vector< Type, Allocator >::reference
    vector< Type, Allocator >::operator[]( size_type n )
{
    return( buffer[n] );
}

// operator[]( size_type ) const
// *****************************
template< class Type, class Allocator >
inline typename vector< Type, Allocator >::const_reference
    vector< Type, Allocator >::operator[]( size_type n ) const
{
    return( buffer[n] );
}

// at( size_type )
// ***************
template< class Type, class Allocator >
typename vector< Type, Allocator >::reference
    vector< Type, Allocator >::at( size_type n )
{
    if( n >= vec_length )
        throw out_of_range( "vector::at" );
    return( buffer[n] );
}

// at( size_type ) const
// *********************
template< class Type, class Allocator >
typename vector< Type, Allocator >::const_reference
    vector< Type, Allocator >::at( size_type n ) const
{
    if( n >= vec_length )
        throw out_of_range( "vector::at" );
    return( buffer[n] );
}

// front( )
// ********
template< class Type, class Allocator >
inline
typename vector< Type, Allocator >::reference
    vector< Type, Allocator >::front( )
{
    return( buffer[0] );
}

// front( ) const
// **************
template< class Type, class Allocator >
inline
typename vector< Type, Allocator >::const_reference
    vector< Type, Allocator >::front( ) const
{
    return( buffer[0] );
}

// back( )
// *******
template< class Type, class Allocator >
inline
typename vector< Type, Allocator >::reference
    vector< Type, Allocator >::back( )
{
    return( buffer[vec_length - 1] );
}

// back( ) const
// *************
template< class Type, class Allocator >
inline
typename vector< Type, Allocator >::const_reference
    vector< Type, Allocator >::back( ) const
{
    return( buffer[vec_length - 1] );
}

// push_back( const Type & )
// *************************
template< class Type, class Allocator >
void vector< Type, Allocator >::push_back( const Type &item )
{
    if( vec_length + 1 > buf_length ) {
        reserve( buf_length + 1 );
    }
    new ( static_cast<void *>( buffer + vec_length ) ) Type( item );
    ++vec_length;
}

// pop_back( )
// ***********
template< class Type, class Allocator >
inline
void vector< Type, Allocator >::pop_back( )
{
    mem.destroy( &buffer[vec_length - 1] );
    --vec_length;
}

// insert( iterator, const Type & )
// ********************************
template< class Type, class Allocator >
vector< Type, Allocator >::iterator
    vector< Type, Allocator >::insert( iterator position, const Type &x )
{
    size_type iposition = static_cast< size_type >( position - buffer );
    size_type tail_count = vec_length - iposition;

    // Deal with zero length vector as a special case.
    if( vec_length == 0 ) {
        mem.construct( &buffer[0], x );
        vec_length++;
        return( buffer );
    }

    // Handle case were reallocation isn't necessary.
    if( vec_length + 1 <= buf_length ) {
        mem.construct( &buffer[vec_length], buffer[vec_length - 1] );
        vec_length++;
        for( size_type i = 2; i <= tail_count; ++i ) {
            buffer[vec_length - i] = buffer[vec_length - 1 - i];
        }
        *position = x;
        return( position );
    }

    // Handle case where reallocation is necessary.
    size_type temp_length;
    pointer temp_buffer = alloc( vec_length + 1, temp_length );

    size_type copy_count = 0;
    pointer   src_iterator = buffer;
    pointer   dst_iterator = temp_buffer;
    try {
        while( src_iterator != position ) {
            mem.construct( dst_iterator, *src_iterator );
            ++copy_count; ++src_iterator; ++dst_iterator;
        }
        mem.construct( dst_iterator, x );
        ++copy_count; ++dst_iterator;
        while( src_iterator != buffer + vec_length ) {
            mem.construct( dst_iterator, *src_iterator );
            ++copy_count; ++src_iterator; ++dst_iterator;
        }
    }
    catch( ... ) {
        for( size_type i = 0; i < copy_count; ++i ) {
            mem.destroy( &temp_buffer[i] );
        }
        mem.deallocate( temp_buffer, temp_length );
        throw;
    }

    // It worked. Commit the new value.
    for( size_type i = 0; i < vec_length; ++i ) {
        mem.destroy( &buffer[i] );
    }
    mem.deallocate( buffer, buf_length );
    buffer     = temp_buffer;
    buf_length = temp_length;
    vec_length++;
    return( buffer + iposition );
}

// insert( iterator, size_type, const Type & )
// *******************************************
template< class Type, class Allocator >
void vector< Type, Allocator >::insert(
    iterator position, size_type n, const Type &x
)
{
    size_type iposition = static_cast< size_type >( position - buffer );
    if( n == 0 ) return;

    // Handle the case where reallocation isn't necessary.
    if( vec_length + n <= buf_length ) {

        // FIX ME: This code isn't exception safe.

        // Open a gap of size n.
        size_type copya;  // Number of objects needing assignment.
        size_type copyc;  // Number of objects needing copy construction.

        copya = ( iposition + n < vec_length ) ? vec_length - iposition - n : 0;
        copyc = vec_length - iposition - copya;

        // Copy construct tail of vector into fresh memory.
        uninitialized_copy( position + copya,
                            position + copya + copyc,
                            position + copya + n );

        // Assign remaining elements in reverse order.
        iterator src_iterator( position + copya - 1);
        iterator dst_iterator( buffer + vec_length - 1 );
        for( size_type i = 0; i < copya; ++i ) {
            *dst_iterator = *src_iterator;
            --src_iterator; --dst_iterator;
        }

        // Fill the gap.
        size_type filla;  // Number of objects needing assignment.
        size_type fillc;  // Number of objects needing copy construction.

        filla = ( n >= vec_length - iposition ) ? vec_length - iposition : n;
        fillc = n - filla;

        // Copy construct new objects (if any).
        uninitialized_fill_n( buffer + vec_length, fillc, x );

        // Assign remaining elements.
        dst_iterator = position;
        for( size_type i = 0; i < filla; ++i ) {
            *dst_iterator = x;
          ++dst_iterator;
        }

        vec_length += copyc + fillc;
        return;
    }

    // Handle case where reallocation is necessary.
    size_type temp_length;
    pointer temp_buffer = alloc( vec_length + n, temp_length );

    size_type copy_count = 0;
    pointer   src_iterator = buffer;
    pointer   dst_iterator = temp_buffer;
    try {
        while( src_iterator != position ) {
            mem.construct( dst_iterator, *src_iterator );
            ++copy_count; ++src_iterator; ++dst_iterator;
        }
        for( size_type i = 0; i < n; ++i ) {
            mem.construct( dst_iterator, x );
            ++copy_count; ++dst_iterator;
        }
        while( src_iterator != buffer + vec_length ) {
            mem.construct( dst_iterator, *src_iterator );
            ++copy_count; ++src_iterator; ++dst_iterator;
        }
    }
    catch( ... ) {
        for( size_type i = 0; i < copy_count; ++i ) {
            mem.destroy( &temp_buffer[i] );
        }
        mem.deallocate( temp_buffer, temp_length );
        throw;
    }

    // It worked. Commit the new value.
    for( size_type i = 0; i < vec_length; ++i ) {
        mem.destroy( &buffer[i] );
    }
    mem.deallocate( buffer, buf_length );
    buffer     = temp_buffer;
    buf_length = temp_length;
    vec_length = vec_length + n;
}

  // erase( iterator )
  // *****************
  template< class Type, class Allocator >
  typename vector< Type, Allocator >::iterator
    vector< Type, Allocator >::erase( iterator position )
  {
    iterator return_value( position );

    while( position != buffer + vec_length - 1 ) {
      *position = *( position + 1 );
      ++position;
    }
    mem.destroy( position );
    --vec_length;
    return( return_value );
  }

// erase( iterator, iterator )
// ***************************
template< class Type, class Allocator >
typename vector< Type, Allocator >::iterator
    vector< Type, Allocator >::erase( iterator first, iterator last )
{
    iterator        return_value( first );
    difference_type removed( last - first );

    while( last != buffer + vec_length ) {
        *first = *last;
        ++first; ++last;
    }
    while( first != buffer + vec_length ) {
        mem.destroy( first );
        ++first;
    }
    vec_length -= removed;
    return( return_value );
}

// swap( )
// *******
template< class Type, class Allocator >
void vector< Type, Allocator >::swap( vector &vec )
{
    typename Allocator::pointer ptemp;
    typename Allocator::size_type stemp;
    Allocator atemp;

    ptemp          = buffer;
    buffer         = vec.buffer;
    vec.buffer     = ptemp;

    stemp          = buf_length;
    buf_length     = vec.buf_length;
    vec.buf_length = stemp;

    stemp          = vec_length;
    vec_length     = vec.vec_length;
    vec.vec_length = stemp;

    atemp          = mem;
    mem            = vec.mem;
    vec.mem        = atemp;
}

// clear( )
// ********
template< class Type, class Allocator >
void vector< Type, Allocator >::clear( )
{
    // Delete objects actually in use.
    for( size_type i = 0; i < vec_length; ++i ) {
        mem.destroy( &buffer[i] );
    }
    vec_length = 0;
}

// _Sane( ) const
// **************
template< class Type, class Allocator >
bool vector< Type, Allocator >::_Sane( ) const
{
    if( buf_length == 0 ) return( false );
    if( buf_length < vec_length ) return( false );

    // Is buf_length a power of 2?
    size_type temp = buf_length;
    while( temp != 1 ) {
        if( temp & 0x1 ) return( false );
        temp >>= 1; 
    }
    return( true );
}

// ===============================
// Ordinary functions using vector
// ===============================

// operator==( const vector &, const vector & )
// ********************************************
template< class Type, class Allocator >
bool operator==(
    const vector< Type, Allocator > &x,
    const vector< Type, Allocator > &y )
{
    if( x.size( ) != y.size( ) ) return( false );

    vector< Type, Allocator>::size_type index = 0;
    while( index < x.size( ) ) {
        if( x[index] != y[index] ) return( false );
        ++index;
    }
    return( true );
}

// operator!=( const vector &, const vector & )
// ********************************************
template< class Type, class Allocator >
inline
bool operator!=(
    const vector< Type, Allocator > &x,
    const vector< Type, Allocator > &y )
{
    return( !(x == y) );
}

// operator<( const vector &, const vector & )
// *******************************************
template< class Type, class Allocator >
bool operator<(
    const vector< Type, Allocator > &x,
    const vector< Type, Allocator > &y )
 {
    vector< Type, Allocator>::size_type index = 0;
    while( index != x.size( ) && index != y.size( ) ) {
        if( x[index] < y[index] ) return( true );
        if( y[index] < x[index] ) return( false );
        ++index;
    }
    return( index == x.size( ) && index != y.size( ) );
}

// operator<=( const vector &, const vector & )
// ********************************************
template< class Type, class Allocator >
inline
bool operator<=(
    const vector< Type, Allocator > &x,
    const vector< Type, Allocator > &y )
{
    return( !( x > y) );
}

// operator>( const vector &, const vector & )
// *******************************************
template< class Type, class Allocator >
inline
bool operator>(
    const vector< Type, Allocator > &x,
    const vector< Type, Allocator > &y )
{
    return( y < x);
}

// operator>=( const vector &, const vector & )
// ********************************************
template< class Type, class Allocator >
inline
bool operator>=(
    const vector< Type, Allocator > &x,
    const vector< Type, Allocator > &y )
{
    return( !(x < y) );
}

:: Vector swap ambiguous if general swap (in algorithm) visible.
:: Need partial ordering of function templates for this to work.
#ifdef __NEVER
// swap( vector &, vector & )
// **************************
template< class Type, class Allocator >
inline
void swap( vector< Type, Allocator > &x, vector< Type, Allocator > &y )
{
    x.swap( y );
}
#endif

} // namespace std

#endif

⌨️ 快捷键说明

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