📄 mstl_optm_string.hpp
字号:
size_type find_last_of( const self& str, size_type pos = npos ) const
{ return find_last_of( str.data(), pos, str.size() ); }
size_type find_last_of( const char_type* str, size_type pos = npos ) const
{ return find_last_of( str, pos, traits_type::length(str) ); }
size_type find_last_of( char_type c, size_type pos = npos ) const
{ return rfind(c, pos); }
size_type find_first_not_of( const char_type* str,
size_type pos, size_type count ) const;
size_type find_first_not_of( char_type c, size_type pos = 0 ) const;
size_type find_first_not_of( const char_type* str, size_type pos = 0 ) const
{ return find_first_not_of( str, pos, traits_type::length(str) ); }
size_type find_first_not_of( const self& str, size_type pos = 0 ) const
{ return find_first_not_of( str.data(), pos, str.size() ); }
size_type find_last_not_of( const char_type* str,
size_type pos, size_type count ) const;
size_type find_last_not_of( char_type c, size_type pos = npos ) const;
size_type find_last_not_of( const char_type* str, size_type pos = npos ) const
{ return find_last_not_of( str, pos, traits_type::length(str) ); }
size_type find_last_not_of( const self& str, size_type pos = npos ) const
{ return find_last_not_of( str.data(), pos, str.size() ); }
protected:
void release()
{
if( --(m_pstr->ref) == 0 )
delete m_pstr;
}
void copy( bool share = true )
{
if( m_pstr->ref > 1 && m_pstr->ref != unshareable )
{
self temp( data(), size() );
swap( temp );
}
m_pstr->ref = share ? 1 : unshareable;
}
bool check_realloc( size_type new_len )
{
if( (m_pstr->ref > 1 && m_pstr->ref != unshareable)
|| capacity() < new_len )
return true;
else
return false;
}
size_type find_char( const char_type* str, const char_type& c,
size_type pos, size_type end ) const
{
if( pos < end )
{
const char_type* p = traits_type::find( str + pos, end - pos, c );
if( p )
return ( p - str );
}
return npos;
}
}; //end class
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
inline typename optm_string<CharT, Traits, Allocator>::size_type
optm_string<CharT, Traits, Allocator>::ref_str::string_bytes( size_type n )
{
size_type n_bytes = n * sizeof( char_type );
size_type i_bytes = string_alignment_bytes;
while( i_bytes < n_bytes )
i_bytes *= 2;
return i_bytes;
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
void optm_string<CharT, Traits, Allocator>::ref_str::alloc_data( size_type n )
{
if( n < 1 )
{
data = NULL_POINTER;
capa = 0;
len = 0;
}
else
{
if( n > max_size() )
throw_length_error( "optm_string::alloc_data()" );
size_type bytes = string_bytes( n + 1 );
len = 0;
capa = bytes / sizeof( char_type );
data = alloc.allocate( capa );
--capa;
}
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
optm_string<CharT, Traits, Allocator>::optm_string( const self& rhs,
size_type pos,
size_type count )
{
if( rhs.m_pstr->ref != unshareable )
{
m_pstr = rhs.m_pstr;
++( m_pstr->ref );
}
else
{
if( pos > rhs.size() )
throw_length_error( "optm_string::optm_string" );
count = min( rhs.size() - pos, count );
m_pstr = new ref_str( count );
m_pstr->data_copy( 0, rhs.data() + pos, count );
m_pstr->len = count;
}
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
optm_string<CharT, Traits, Allocator>&
optm_string<CharT, Traits, Allocator>::operator=( const self& rhs )
{
if( m_pstr != rhs.m_pstr )
{
if( m_pstr->ref == unshareable || rhs.m_pstr->ref == unshareable )
{
if( capacity() < rhs.size() )
{
self temp( rhs );
swap( temp );
}
else
m_pstr->data_copy( 0, rhs.data(), rhs.size() );
}
else //均为可共享状态
{
if( m_pstr->ref > 1 || capacity() < rhs.size() )
{
release();
m_pstr = rhs.m_pstr;
++( m_pstr->ref );
}
else
m_pstr->data_copy( 0, rhs.data(), rhs.size() );
}
}
return *this;
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
void optm_string<CharT, Traits, Allocator>::resize( size_type new_size,
char_type c )
{
if( new_size > max_size() )
throw_length_error( "optm_string::resize()" );
if( m_pstr->ref > 1 || capacity() < new_size )
{
self temp( new_size, c );
swap( temp );
}
else if( new_size > m_pstr->len )
append( new_size - m_pstr->len, c );
else if( new_size < m_pstr->len )
erase( new_size, m_pstr->len - new_size );
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
inline optm_string<CharT, Traits, Allocator>&
optm_string<CharT, Traits, Allocator>::replace( size_type pos,
size_type before_count,
const self& str,
size_type str_pos,
size_type after_count )
{
const size_type str_len = str.size();
if( pos == 0 && before_count >= size()
&& str_pos == 0 && after_count >= str_len )
return operator=( str );
if( str_pos > str_len )
throw_out_of_range( "optm_string::replace()" );
if( after_count > str_len - str_pos )
after_count = str_len - str_pos;
return replace( pos, before_count, str.data() + str_pos, after_count );
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
optm_string<CharT, Traits, Allocator>&
optm_string<CharT, Traits, Allocator>::replace( size_type pos,
size_type before_count,
const char_type* str,
size_type after_count )
{
const size_type old_len = size();
if( pos > old_len )
throw_out_of_range( "optm_string::replace()" );
if( before_count > old_len - pos )
before_count = old_len - pos;
if( old_len - before_count > max_size() - after_count )
throw_length_error( "optm_string::replace()" );
size_type new_len = old_len - before_count + after_count;
if( check_realloc(new_len) )
{
self temp( new_len );
temp.m_pstr->data_copy( 0, data(), pos );
temp.m_pstr->data_copy( pos + after_count, data() + pos + before_count,
old_len - (pos + before_count) );
temp.m_pstr->data_copy( pos, str, after_count );
swap( temp );
}
else
{
m_pstr->data_move( pos + after_count, data() + pos + before_count,
old_len - (pos + before_count) );
m_pstr->data_copy( pos, str, after_count );
}
m_pstr->len = new_len;
return *this;
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
optm_string<CharT, Traits, Allocator>&
optm_string<CharT, Traits, Allocator>::replace( size_type pos,
size_type before_count,
size_type after_count,
char_type c )
{
const size_type old_len = size();
if( pos > old_len )
throw_out_of_range( "optm_string::replace()" );
if( before_count > old_len - pos )
before_count = old_len - pos;
if( old_len - before_count > max_size() - after_count )
throw_length_error( "optm_string::replace()" );
size_type new_len = old_len - before_count + after_count;
if( check_realloc(new_len) )
{
self temp( new_len );
temp.m_pstr->data_copy( 0, data(), pos );
temp.m_pstr->data_copy( pos + after_count, data() + pos + before_count,
old_len - (pos + before_count) );
temp.m_pstr->data_set( pos, c, after_count );
swap( temp );
}
else
{
m_pstr->data_move( pos + after_count, data() + pos + before_count,
old_len - (pos + before_count) );
m_pstr->data_set( pos, c, after_count );
}
m_pstr->len = new_len;
return *this;
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
template< typename InputIterator >
optm_string<CharT, Traits, Allocator>&
optm_string<CharT, Traits, Allocator>::replace( iterator first_pos,
iterator last_pos,
InputIterator first,
InputIterator last )
{
if( first == last )
return *this;
const size_type old_len = size();
size_type pos = first_pos - begin();
if( pos > old_len )
throw_out_of_range( "optm_string::replace()" );
size_type before_count = last_pos - first_pos;
size_type after_count = distance( first, last );
if( before_count > old_len - pos )
before_count = old_len - pos;
if( old_len - before_count > max_size() - after_count )
throw_length_error( "optm_string::replace()" );
size_type new_len = old_len - before_count + after_count;
if( check_realloc(new_len) )
{
self temp( new_len );
temp.m_pstr->data_copy( 0, data(), pos );
temp.m_pstr->data_copy( pos + after_count, data() + pos + before_count,
old_len - (pos + before_count) );
for( ; after_count > 0; ++first,++pos,--after_count )
traits_type::assign( *(m_pstr->data + pos), *first );
swap( temp );
}
else
{
m_pstr->data_move( pos + after_count, data() + pos + before_count,
old_len - (pos + before_count) );
for( ; after_count > 0; ++first,++pos,--after_count )
traits_type::assign( *(m_pstr->data + pos), *first );
}
m_pstr->len = new_len;
return *this;
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
inline
int optm_string<CharT, Traits, Allocator>::compare( const self& str ) const
{
int result = traits_type::compare( data(), str.data(),
min( size(), str.size() ) );
if( result == 0 )
result = size() - str.size();
return result;
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
inline
int optm_string<CharT, Traits, Allocator>::compare( const char_type* str ) const
{
size_type str_len = traits_type::length( str );
int result = traits_type::compare( data(), str, min(size(), str_len) );
if( result == 0 )
result = size() - str_len;
return result;
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
int optm_string<CharT, Traits, Allocator>::compare( size_type pos,
size_type count,
const self& str,
size_type str_pos,
size_type str_count ) const
{
if( pos > size() || str_pos > str.size() )
throw_out_of_range( "optm_string::compare()" );
size_type str_len = min( str.size() - str_pos, str_count );
size_type this_len = min( size() - pos, count );
int result = traits_type::compare( data() + pos, str.data() + str_pos,
min(str_len, this_len) );
if( result == 0 )
result = this_len - str_len;
return result;
}
//-----------------------------------------------------------------------------
template< typename CharT, typename Traits, typename Allocator >
int optm_string<CharT, Traits, Allocator>::compare( size_type pos,
size_type count,
const char_type* str,
size_type str_count ) const
{
if( pos > size() )
throw_out_of_range( "optm_string::compare()" );
size_type str_len = min( traits_type::length(str), str_count );
size_type this_len = min( size() - pos, count );
int result = traits_type::compare( data() + pos, str,
min(str_len, this_len) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -