📄 ycpp_string.hpp
字号:
n, c ); }
self& assign( const self& str, size_type index = 0, size_type n = npos )
{ return replace( size_type(0), npos, str, index, n ); }
self& assign( const CharT* str, size_type n )
{ return replace( size_type(0), npos, str, n ); }
self& assign( const CharT* str )
{ return replace( size_type(0), npos, str, Traits::length(str) ); }
self& assign( size_type n, CharT c )
{ return replace( size_type(0), npos, n, c ); }
template< typename InputIterator >
self& assign( InputIterator first, InputIterator last )
{ return replace( begin(), end(), first, last ); }
self& append( const self& str, size_type index = 0, size_type n = npos )
{ return replace( size(), size_type(0), str, index, n ); }
self& append( const CharT* str, size_type n )
{ return replace( size(), size_type(0), str, n ); }
self& append( const CharT* str )
{ return replace( size(), size_type(0), str, Traits::length(str) ); }
self& append( size_type n, CharT c )
{ return replace( size(), size_type(0), n, c ); }
template< typename InputIterator >
self& append( InputIterator first, InputIterator last )
{ return replace( end(), end(), first, last ); }
self& insert( size_type index, const self& str,
size_type str_pos = 0, size_type n = npos )
{ return replace( index, size_type(0), str, str_pos, n ); }
self& insert( size_type index, const CharT* str, size_type n )
{ return replace( index, size_type(0), str, n ); }
self& insert( size_type index, const CharT* str )
{ return replace( index, size_type(0), str, Traits::length(str) ); }
self& insert( size_type index, size_type n, CharT c )
{ return replace( index, size_type(0), n, c ); }
iterator insert( iterator pos, CharT c )
{
size_type i = pos - begin();
replace( i, size_type(0), size_type(1), c );
return begin() + i;
}
void insert( iterator pos, size_type n, CharT c )
{ replace( pos - begin(), size_type(0), n, c ); }
template< typename InputIterator >
void insert( iterator pos, InputIterator first, InputIterator last )
{ replace( pos, pos, first, last ); }
iterator erase( iterator pos );
iterator erase( iterator first, iterator last );
self& erase( size_type index = 0, size_type n = npos );
// (1) < 0 :this < str; (2) = 0 : this = str; (3) > 0 : this > str
int compare( const self& str ) const;
int compare( const CharT* str ) const;
int compare( size_type index, size_type n, const self& str,
size_type sindex, size_type sn = npos ) const;
int compare( size_type index, size_type n, const CharT* str,
size_type sn = npos ) const;
size_type find( CharT c, size_type index = 0 ) const;
size_type find( const CharT* str, size_type index, size_type n ) const;
size_type find( const CharT* str, size_type index = 0 ) const
{ return find( str, index, Traits::length(str) ); }
size_type find( const self& str, size_type index = 0 ) const
{ return find( str.data(), index, str.size() ); }
size_type rfind( CharT c, size_type index = npos ) const;
size_type rfind( const CharT* str, size_type index, size_type n ) const;
size_type rfind( const CharT* str, size_type index = npos ) const
{ return rfind( str, index, Traits::length(str) ); }
size_type rfind( const self& str, size_type index = npos) const
{ return rfind( str.data(), index, str.size() ); }
size_type find_first_of( const CharT* str, size_type index,
size_type n ) const;
size_type find_first_of( const self& str, size_type index = 0 ) const
{ return find_first_of( str.data(), index, str.size() ); }
size_type find_first_of( const CharT* str, size_type index = 0 ) const
{ return find_first_of( str, index, Traits::length(str) ); }
size_type find_first_of( CharT c, size_type index = 0 ) const
{ return find( c, index ); }
size_type find_last_of( const CharT* str, size_type index,
size_type n ) const;
size_type find_last_of( const self& str, size_type index = npos ) const
{ return find_last_of( str.data(), index, str.size() ); }
size_type find_last_of( const CharT* str, size_type index = npos ) const
{ return find_last_of( str, index, Traits::length(str) ); }
size_type find_last_of( CharT c, size_type index = npos ) const
{ return rfind( c, index ); }
size_type find_first_not_of( CharT c, size_type index = 0 ) const;
size_type find_first_not_of( const CharT* str, size_type index,
size_type n ) const;
size_type find_first_not_of( const CharT* str, size_type index = 0 ) const
{ return find_first_not_of( str, index, Traits::length(str) ); }
size_type find_first_not_of( const self& str, size_type index = 0 ) const
{ return find_first_not_of( str.data(), index, str.size() ); }
size_type find_last_not_of( CharT c, size_type index = npos ) const;
size_type find_last_not_of( const CharT* str, size_type index,
size_type n ) const;
size_type find_last_not_of( const CharT* str, size_type index = npos ) const
{ return find_last_not_of( str, index, Traits::length(str) ); }
size_type find_last_not_of( const self& str, size_type index = npos ) const
{ return find_last_not_of( str.data(), index, str.size() ); }
private:
enum STRING_CONSTANT
{
STATIC_LEN = sizeof(youngc::dymemarray) < sizeof(CharT) * 2 ? 0
: ( sizeof(youngc::dymemarray) - sizeof(CharT) * 2 )
/ sizeof(CharT)
};
union string_base
{
youngc::dymemarray dy; //dynamic
struct
{
CharT len;
CharT data[ sizeof(youngc::dymemarray) < sizeof(CharT) ? 0
: ( sizeof(youngc::dymemarray) - sizeof(CharT) )
/ sizeof(CharT) ];
} st; //static
};
bool m_dynamic;
mutable string_base m_str;
void static_to_dynamic( size_type capa );
}; //end class basic_string
template< typename CharT, typename Traits, typename Allocator >
void basic_string<CharT, Traits, Allocator>::static_to_dynamic( size_type capa )
{
youngc::dymemarray arr;
dymemarr_init( &arr, sizeof(CharT), alloc_adapter<Allocator>,
dealloc_adapter<Allocator> );
if( !dymemarr_reserve( &arr, capa ) )
throw std::bad_alloc();
dymemarr_insert_array( &arr, 0, m_str.st.data, m_str.st.len );
m_str.dy = arr;
m_dynamic = true;
}
template< typename CharT, typename Traits, typename Allocator >
basic_string<CharT, Traits, Allocator>&
basic_string<CharT, Traits, Allocator>::replace( size_type index,
size_type before,
size_type after,
CharT c )
{
size_type old_len = size();
if( index > old_len )
throw std::out_of_range( "young::basic_string::replace_char out of range!" );
if( before > old_len - index )
before = old_len - index;
if( old_len - before > max_size() - after )
throw std::length_error( "young::basic_string::replace_char length error!" );
if( m_dynamic )
{
if( !dymemarr_replace_fill( &(m_str.dy), index, before, &c, after ) )
throw std::bad_alloc();
}
else
{
size_type new_len = old_len - before + after;
if( new_len <= STATIC_LEN )
{
Traits::move( m_str.st.data + index + after,
m_str.st.data + index + before,
old_len - index - before );
Traits::assign( m_str.st.data + index, after, c );
m_str.st.len = (CharT)new_len;
}
else
{
static_to_dynamic( new_len );
dymemarr_replace_fill( &(m_str.dy), index, before, &c, after );
}
}
return *this;
}
template< typename CharT, typename Traits, typename Allocator >
basic_string<CharT, Traits, Allocator>&
basic_string<CharT, Traits, Allocator>::replace( size_type index,
size_type before,
const CharT* str,
size_type after )
{
size_type old_len = size();
if( index > old_len )
throw std::out_of_range( "young::basic_string::replace_str out of range!" );
if( before > old_len - index )
before = old_len - index;
if( old_len - before > max_size() - after )
throw std::length_error( "young::basic_string::replace_str length error!" );
if( m_dynamic )
{
if( !dymemarr_replace_array( &(m_str.dy), index, before, str, after ) )
throw std::bad_alloc();
}
else
{
size_type new_len = old_len - before + after;
if( new_len <= STATIC_LEN )
{
Traits::move( m_str.st.data + index + after,
m_str.st.data + index + before,
old_len - index - before );
Traits::copy( m_str.st.data + index, str, after );
m_str.st.len = (CharT)new_len;
}
else
{
static_to_dynamic( new_len );
dymemarr_replace_array( &(m_str.dy), index, before, str, after );
}
}
return *this;
}
template< typename CharT, typename Traits, typename Allocator >
template< typename InputIterator >
basic_string<CharT, Traits, Allocator>&
basic_string<CharT, Traits, Allocator>::replace( iterator first_pos,
iterator last_pos,
InputIterator first,
InputIterator last )
{
if( first == last )
return *this;
size_type old_len = size();
size_type f_index = first_pos - begin();
size_type l_index = last_pos - begin();
if( f_index > old_len )
throw std::out_of_range( "young::basic_string::replace_range out of range!" );
size_type before = last_pos - first_pos;
size_type after = std::distance( first, last );
if( before > old_len - f_index )
before = old_len - f_index;
if( old_len - before > max_size() - after )
throw std::length_error( "young::basic_string::replace_range length error!" );
if( m_dynamic )
{
if( !dymemarr_replace_array( &(m_str.dy), f_index, before, NULL, after ) )
throw std::bad_alloc();
}
else
{
size_type new_len = old_len - before + after;
if( new_len <= STATIC_LEN )
{
Traits::move( m_str.st.data + f_index + after,
m_str.st.data + f_index + before,
old_len - f_index - before );
m_str.st.len = (CharT)new_len;
}
else
{
static_to_dynamic( new_len );
if( !dymemarr_replace_array( &(m_str.dy), f_index, before, NULL, after ) )
throw std::bad_alloc();
}
}
std::copy( first, last, begin() + f_index );
return *this;
}
template< typename CharT, typename Traits, typename Allocator >
typename basic_string<CharT, Traits, Allocator>::iterator
basic_string<CharT, Traits, Allocator>::erase( iterator pos )
{
iterator b = begin();
size_type i = pos - b;
if( m_dynamic )
dymemarr_erase_pos( &(m_str.dy), i );
else
{
Traits::copy( pos + 1, pos, end() - pos );
--m_str.st.len;
}
return b + i;
}
template< typename CharT, typename Traits, typename Allocator >
typename basic_string<CharT, Traits, Allocator>::iterator
basic_string<CharT, Traits, Allocator>::erase( iterator first, iterator last )
{
iterator b = begin();
size_type i = first - b;
if( m_dynamic )
dymemarr_erase_range( &(m_str.dy), i, last - b );
else
{
Traits::copy( first, last, end() - last );
m_str.st.len -= ( last - first );
}
return b + i;
}
template< typename CharT, typename Traits, typename Allocator >
basic_string<CharT, Traits, Allocator>&
basic_string<CharT, Traits, Allocator>::erase( size_type index, size_type n )
{
size_type len = size();
if( index > len )
throw std::out_of_range( "young::basic_string::erase out of range!" );
iterator f = begin() + index;
erase( f, f + std::min(len - index, n) );
return *this;
}
template< typename CharT, typename Traits, typename Allocator >
int basic_string<CharT, Traits, Allocator>::compare( const self& str ) const
{
size_type len = size(), slen = str.size();
int result = Traits::compare( data(), str.data(), std::min(len, slen) );
if( result == 0 ) //如果等长的部分相等,则比较哪个字符串更长
result = static_cast<int>( len - slen );
return result;
}
template< typename CharT, typename Traits, typename Allocator >
int basic_string<CharT, Traits, Allocator>::compare( const CharT* str ) const
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -