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