deque.mh
来自「开放源码的编译器open watcom 1.6.0版的源代码」· MH 代码 · 共 966 行 · 第 1/2 页
MH
966 行
///////////////////////////////////////////////////////////////////////////
// FILE: deque (Definition of std::deque)
//
:keep CPP_HDR
:include crwatcnt.sp
//
// Description: This header is part of the C++ standard library. It defines
// a double ended queue template that provides random access
// to its elements yet amortized O(1) time push/pop operations
// on *both* ends.
///////////////////////////////////////////////////////////////////////////
#ifndef _DEQUE_INCLUDED
#define _DEQUE_INCLUDED
:include readonly.sp
#ifndef __cplusplus
#error The header deque requires C++
#endif
#ifndef _ITERATOR_INCLUDED
#include <iterator>
#endif
#ifndef _LIMITS_INCLUDED
#include <limits>
#endif
#ifndef _MEMORY_INCLUDED
#include <memory>
#endif
#ifndef _STDEXCEPT_INCLUDED
#include <stdexcep>
#endif
namespace std {
template<class Type, class Allocator = allocator< Type > >
class deque {
public:
typedef typename Allocator::reference reference;
typedef typename Allocator::const_reference const_reference;
typedef typename Allocator::size_type size_type;
typedef typename Allocator::difference_type difference_type;
typedef Type value_type;
typedef Allocator allocator_type;
typedef typename Allocator::pointer pointer;
typedef typename Allocator::const_pointer const_pointer;
// Class iterator
// --------------
class iterator :
public std::iterator< random_access_iterator_tag, Type > {
public:
iterator( deque *p, deque::size_type i ) :
dp( p ), index( i ) { }
iterator( ) { }
value_type &operator*( )
{ return( dp->buffer[index] ); }
value_type *operator->( )
{ return( &dp->buffer[index] ); }
iterator &operator++( );
iterator operator++( int );
iterator &operator--( );
iterator operator--( int );
:: Due to a bug in the compiler (#492) these functions can't be defined
:: outside of the class and must be inline. As a result they must also
:: be friends (even when not otherwise necessary).
friend bool operator==(iterator lhs, iterator rhs)
{ return( lhs.dp == rhs.dp && lhs.index == rhs.index ); }
friend bool operator< (iterator lhs, iterator rhs)
{
deque::size_type xform1, xform2;
if( lhs.index >= lhs.dp->head_index )
xform1 = lhs.index - lhs.dp->head_index;
else
xform1 = (lhs.dp->deq_length - lhs.dp->head_index) + lhs.index;
if( rhs.index >= rhs.dp->head_index )
xform2 = rhs.index - rhs.dp->head_index;
else
xform2 = (rhs.dp->deq_length - rhs.dp->head_index) + rhs.index;
return( xform1 < xform2 );
}
friend bool operator!=(iterator lhs, iterator rhs)
{ return( !( lhs == rhs ) ); }
friend bool operator>=(iterator lhs, iterator rhs)
{ return( !( lhs < rhs ) ); }
friend bool operator> (iterator lhs, iterator rhs)
{ return( rhs < lhs ); }
friend bool operator<=(iterator lhs, iterator rhs)
{ return( !( lhs > rhs ) ); }
iterator &operator+=( difference_type n );
iterator &operator-=( difference_type n );
friend iterator operator+( iterator it, difference_type n )
{ it += n; return( it ); }
friend iterator operator+( difference_type n, iterator it )
{ it += n; return( it ); }
friend iterator operator-( iterator it, difference_type n )
{ it -= n; return( it ); }
private:
deque *dp;
deque::size_type index;
};
// Class const_iterator
// --------------------
class const_iterator :
public std::iterator< random_access_iterator_tag, const Type > {
public:
const_iterator( const deque *p, deque::size_type i ) :
dp( p ), index( i ) { }
const_iterator( ) { }
value_type &operator*( )
{ return( dp->buffer[index] ); }
value_type *operator->( )
{ return( &dp->buffer[index] ); }
const_iterator &operator++( );
const_iterator operator++( int );
const_iterator &operator--( );
const_iterator operator--( int );
:: Due to a bug in the compiler (#492) these functions can't be defined
:: outside of the class and must be inline. As a result they must also
:: be friends (even when not otherwise necessary).
friend bool operator==(const_iterator lhs, const_iterator rhs)
{ return( lhs.dp == rhs.dp && lhs.index == rhs.index ); }
friend bool operator< (const_iterator lhs, const_iterator rhs)
{
deque::size_type xform1, xform2;
if( lhs.index >= lhs.dp->head_index )
xform1 = lhs.index - lhs.dp->head_index;
else
xform1 = (lhs.dp->deq_length - lhs.dp->head_index) + lhs.index;
if( rhs.index >= rhs.dp->head_index )
xform2 = rhs.index - rhs.dp->head_index;
else
xform2 = (rhs.dp->deq_length - rhs.dp->head_index) + rhs.index;
return( xform1 < xform2 );
}
friend bool operator!=(const_iterator lhs, const_iterator rhs)
{ return( !( lhs == rhs ) ); }
friend bool operator>=(const_iterator lhs, const_iterator rhs)
{ return( !( lhs < rhs ) ); }
friend bool operator> (const_iterator lhs, const_iterator rhs)
{ return( rhs < lhs ); }
friend bool operator<=(const_iterator lhs, const_iterator rhs)
{ return( !( lhs > rhs ) ); }
const_iterator &operator+=( difference_type n );
const_iterator &operator-=( difference_type n );
friend const_iterator operator+( const_iterator it, difference_type n )
{ it += n; return( it ); }
friend const_iterator operator+( difference_type n, const_iterator it )
{ it += n; return( it ); }
friend const_iterator operator-( const_iterator it, difference_type n )
{ it -= n; return( it ); }
private:
const deque *dp;
deque::size_type index;
};
friend class iterator;
friend class const_iterator;
typedef reverse_iterator< iterator > reverse_iterator;
typedef reverse_iterator< const_iterator > const_reverse_iterator;
explicit deque( const Allocator & = Allocator( ) );
explicit deque( size_type n, const Type &value = Type( ), const Allocator & = Allocator( ) );
deque( const deque &other );
~deque( );
deque &operator=( const deque &other );
void assign( size_type n, const Type &value );
allocator_type get_allocator( ) const;
iterator begin( );
const_iterator begin( ) const;
iterator end( );
const_iterator end( ) const;
reverse_iterator rbegin( );
const_reverse_iterator rbegin( ) const;
reverse_iterator rend( );
const_reverse_iterator rend( ) const;
size_type size( ) const;
size_type max_size( ) const;
void resize( size_type n, Type c = Type( ) );
size_type capacity( ) const; // Not required by the standard.
bool empty( ) const;
void reserve( size_type n ); // Not required by the standard.
reference operator[]( size_type n );
const_reference operator[]( size_type n ) const;
reference at( size_type n );
const_reference at( size_type n ) const;
reference front( );
const_reference front( ) const;
reference back( );
const_reference back( ) const;
void push_front( const Type &item );
void push_back( const Type &item );
void pop_front( );
void pop_back( );
iterator insert( iterator position, const Type &x );
void insert( iterator position, size_type n, const Type &x );
iterator erase( iterator position );
iterator erase( iterator first, iterator last );
void swap( deque &x );
void clear( );
bool _Sane( ) const; // Check invariants.
private:
// 1. buffer has size buf_length.
// 2. buffer never shrinks (except in ...).
// 3. buf_length > deq_length.
// 4. buf_length is a power of two.
// 5. buffer allocated with mem or a copy of mem.
// 6. tail_index [-] head_index == deq_length (after considering wrap)
// 7. buffer reallocated when deq_length == buf_length - 1
// Note: tail_index == head_index implies buffer is empty, not full.
//
Allocator mem; // Object used to get and release memory.
pointer buffer; // Pointer to start of buffer space.
size_type buf_length; // Total number of buffer slots.
size_type deq_length; // Number of buffer slots in use by objects.
size_type head_index; // Buffer position of the first object.
size_type tail_index; // Buffer position just past the last object.
// This method encapsulates the memory allocation policy.
pointer alloc( size_type required, size_type &found );
};
// ===================================
// Member functions of deque::iterator
// ===================================
// operator++( )
// *************
template< class Type, class Allocator >
typename deque< Type, Allocator >::iterator &
deque< Type, Allocator >::iterator::operator++( )
{
++index;
if( index >= dp->buf_length ) index = 0;
return( *this );
}
// operator++( int )
// *****************
template< class Type, class Allocator >
typename deque< Type, Allocator >::iterator
deque< Type, Allocator >::iterator::operator++( int )
{
iterator ret_value( *this );
++index;
if( index >= dp->buf_length ) index = 0;
return( ret_value );
}
// operator--( )
// *************
template< class Type, class Allocator >
typename deque< Type, Allocator >::iterator &
deque< Type, Allocator >::iterator::operator--( )
{
if( index == 0 ) {
index = dp->buf_length - 1;
}
else {
--index;
}
return( *this );
}
// operator--( int )
// *****************
template< class Type, class Allocator >
typename deque< Type, Allocator >::iterator
deque< Type, Allocator >::iterator::operator--( int )
{
iterator ret_value( *this );
if( index == 0 ) {
index = dp->buf_length - 1;
}
else {
--index;
}
return( ret_value );
}
// operator+=( difference_type )
// *****************************
template< class Type, class Allocator >
typename deque< Type, Allocator >::iterator &
deque< Type, Allocator >::iterator::operator+=( difference_type n )
{
if( n >= 0 ) index = ( index + n ) % dp->buf_length;
else {
n = -n;
if( index >= n ) index -= n;
else index = dp->buf_length - ( n - index );
}
return( *this );
}
// operator-=( difference_type )
// *****************************
template< class Type, class Allocator >
inline
typename deque< Type, Allocator >::iterator &
deque< Type, Allocator >::iterator::operator-=( difference_type n )
{
return( ( *this ) += -n );
}
// =========================================
// Member functions of deque::const_iterator
// =========================================
// operator++( )
// *************
template< class Type, class Allocator >
typename deque< Type, Allocator >::const_iterator &
deque< Type, Allocator >::const_iterator::operator++( )
{
++index;
if( index >= dp->buf_length ) index = 0;
return( *this );
}
// operator++( int )
// *****************
template< class Type, class Allocator >
typename deque< Type, Allocator >::const_iterator
deque< Type, Allocator >::const_iterator::operator++( int )
{
const_iterator ret_value( *this );
++index;
if( index >= dp->buf_length ) index = 0;
return( ret_value );
}
// operator--( )
// *************
template< class Type, class Allocator >
typename deque< Type, Allocator >::const_iterator &
deque< Type, Allocator >::const_iterator::operator--( )
{
if( index == 0 ) {
index = dp->buf_length - 1;
}
else {
--index;
}
return( *this );
}
// operator--( int )
// *****************
template< class Type, class Allocator >
typename deque< Type, Allocator >::const_iterator
deque< Type, Allocator >::const_iterator::operator--( int )
{
const_iterator ret_value( *this );
if( index == 0 ) {
index = dp->buf_length - 1;
}
else {
--index;
}
return( ret_value );
}
// operator+=( difference_type )
// *****************************
template< class Type, class Allocator >
typename deque< Type, Allocator >::const_iterator &
deque< Type, Allocator >::const_iterator::operator+=( difference_type n )
{
if( n >= 0 ) index = ( index + n ) % dp->buf_length;
else {
n = -n;
if( index >= n ) index -= n;
else index = dp->buf_length - ( n - index );
}
return( *this );
}
// operator-=( difference_type )
// *****************************
template< class Type, class Allocator >
inline
typename deque< Type, Allocator >::const_iterator &
deque< Type, Allocator >::const_iterator::operator-=( difference_type n )
{
return( ( *this ) += -n );
}
// =========================
// Member functions of deque
// =========================
template< class Type, class Allocator >
deque< Type, Allocator >::pointer
deque< Type, Allocator >::alloc(
size_type required,
size_type &found )
{
pointer result;
size_type length = 16;
// Find a power of two that produces a sufficient size.
while( length < required ) length <<= 1;
result = mem.allocate( length );
// Update outputs only if allocation successful.
found = length;
return( result );
}
// deque( const Allocator & )
// **************************
template< class Type, class Allocator >
deque< Type, Allocator >::deque( const Allocator &a ) : mem( a )
{
buffer = alloc( 1, buf_length );
deq_length = 0;
head_index = 0;
tail_index = 0;
}
// deque( size_type, const Type &, const Allocator & )
//****************************************************
template< class Type, class Allocator >
deque< Type, Allocator >::deque(
size_type n,
const Type &value,
const Allocator &a ) : mem( a )
{
buffer = alloc( n + 1, buf_length );
try {
uninitialized_fill_n( buffer, n, value );
}
catch( ... ) {
mem.deallocate( buffer, buf_length );
throw;
}
deq_length = n;
head_index = 0;
tail_index = n;
}
// deque( const deque & )
// ************************
template< class Type, class Allocator >
deque< Type, Allocator >::deque( const deque &other )
: mem( other.mem )
{
buffer = alloc( other.deq_length + 1, buf_length );
bool part1_done = false;
size_type part1_size = ( ( other.tail_index >= other.head_index ) ?
other.tail_index : other.buf_length ) - other.head_index;
try {
pointer bookmark = uninitialized_copy(
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?