📄 ycpp_string.hpp
字号:
size_type length() const { return size(); }
size_type space() const { return capacity() - size(); }
size_type max_size() const { return (npos - 1) / sizeof(CharT); }
bool empty() const { return size() == 0; }
iterator begin()
{ copy_str( 0, size(), false ); return m_pstr->memstr.begin(); }
iterator end()
{ copy_str( 0, size(), false ); return m_pstr->memstr.end(); }
const_iterator begin() const
{ return m_pstr->memstr.begin(); }
const_iterator end() const
{ return m_pstr->memstr.end(); }
reverse_iterator rbegin()
{ return reverse_iterator( end() ); }
reverse_iterator rend()
{ return reverse_iterator( begin() ); }
const_reverse_iterator rbegin() const
{ return const_reverse_iterator( end() ); }
const_reverse_iterator rend() const
{ return const_reverse_iterator( begin() ); }
reference front() { return *begin(); }
reference back() { return *( end() - 1 ); }
const_reference front() const { return *begin(); }
const_reference back() const { return *( end() - 1 ); }
void clear();
void reserve( size_type new_capa );
void resize( size_type new_size, CharT c = CharT() );
CharT& operator[]( size_type index )
{
copy_str( 0, size(), false );
return m_pstr->memstr[index];
}
const CharT& operator[]( size_type index ) const
{
copy_str( 0, size(), true );
return m_pstr->memstr[index];
}
CharT& at( size_type index )
{
copy_str( 0, size(), false );
return m_pstr->memstr.at( index );
}
const CharT& at( size_type index ) const
{
copy_str( 0, size(), true );
return m_pstr->memstr.at( index );
}
void swap( self& rhs )
{
copy_str( 0, size(), true );
rhs.copy_str( 0, rhs.size(), true );
m_pstr->memstr.swap( rhs.m_pstr->memstr );
}
size_type copy( CharT* str, size_type n = npos, size_type index = 0 ) const
{
return m_pstr->memstr.copy( str, n, index );
}
self& replace( size_type index, size_type before,
size_type after, CharT c );
self& replace( size_type index, size_type before,
const CharT* str, size_type after );
template< typename InputIterator >
self& replace( iterator first_pos, iterator last_pos,
InputIterator first, InputIterator last );
self& replace( size_type index, size_type before, const self& str,
size_type sindex, size_type after )
{
const size_type str_len = str.size();
if( index == 0 && before >= size() && sindex == 0 && after >= str_len )
return operator=( str );
if( sindex > str_len )
throw std::length_error( "young::basic_string::replace length error!" );
if( after > str_len - sindex )
after = str_len - sindex;
return replace( index, before, str.data() + sindex, after );
}
self& replace( size_type index, size_type n, const CharT* str )
{ return replace( index, n, str, Traits::length(str) ); }
self& replace( size_type index, size_type n, CharT c )
{ return replace( index, n, size_type(1), c ); }
self& replace( iterator first, iterator last, const self& str )
{ return replace( size_type(first - begin()), size_type(last - first),
str, size_type(0), npos ); }
self& replace( iterator first, iterator last,
const CharT* str, size_type n )
{ return replace( size_type(first - begin()),
size_type(last - first), str, n ); }
self& replace( iterator first, iterator last, const CharT* str )
{ return replace( size_type(first - begin()), size_type(last - first),
str, Traits::length(str) ); }
self& replace( iterator first, iterator last, size_type n, CharT c )
{ return replace( size_type(first - begin()), size_type(last - first),
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 )
{
size_type i = pos - begin();
replace( i, 1, size_type(0), CharT() );
return begin() + i;
}
iterator erase( iterator first, iterator last )
{
size_type i = first - begin();
size_type n = last - first;
replace( i, n, size_type(0), CharT() );
return begin() + i;
}
self& erase( size_type index = 0, size_type n = npos )
{
return replace( index, n, size_type(0), CharT() );
}
int compare( const self& str ) const
{ return m_pstr->memstr.compare( str.m_pstr->memstr ); }
int compare( const CharT* str ) const
{ return m_pstr->memstr.compare( str ); }
int compare( size_type index, size_type n, const self& str,
size_type sindex, size_type sn = npos ) const
{ return m_pstr->memstr.compare( index, n, str.m_pstr->memstr,
sindex, sn ); }
int compare( size_type index, size_type n, const CharT* str,
size_type sn = npos ) const
{ return m_pstr->memstr.compare( index, n, str, sn ); }
size_type find( CharT c, size_type index = 0 ) const
{ return m_pstr->memstr.find( c, index ); }
size_type find( const CharT* str, size_type index, size_type n ) const
{ return m_pstr->memstr.find( str, index, n ); }
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
{ return m_pstr->memstr.rfind( c, index ); }
size_type rfind( const CharT* str, size_type index, size_type n ) const
{ return m_pstr->memstr.rfind( str, index, n ); }
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
{ return m_pstr->memstr.find_first_of( str, index, n ); }
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
{ return m_pstr->memstr.find_last_of( str, index, n ); }
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
{ return m_pstr->memstr.find_first_not_of( c, index ); }
size_type find_first_not_of( const CharT* str, size_type index,
size_type n ) const
{ return m_pstr->memstr.find_first_not_of( str, index, n ); }
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
{ return m_pstr->memstr.find_last_not_of( c, index ); }
size_type find_last_not_of( const CharT* str, size_type index,
size_type n ) const
{ return m_pstr->memstr.find_last_not_of( str, index, n ); }
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:
static const size_type unshareable = SIZE_MAX;
class string_type
{
public:
size_type ref;
basic_string<CharT, Traits, Allocator> memstr;
string_type() : ref(1) {}
string_type( const string_type& rhs ) : ref(1), memstr(rhs.memstr) {}
private:
string_type& operator=( const string_type& );
} *m_pstr;
typename Allocator::template rebind<string_type>::other m_alloc;
string_type* alloc_str()
{
string_type* pstr = m_alloc.allocate( 1 );
if( !pstr )
throw std::bad_alloc();
m_alloc.construct( pstr, string_type() );
return pstr;
}
void dealloc_str( string_type* pstr )
{
m_alloc.destroy( pstr );
m_alloc.deallocate( pstr, 1 );
}
void release()
{
if( m_pstr && (m_pstr->ref == unshareable || --(m_pstr->ref) == 0) )
dealloc_str( m_pstr );
}
void copy_str( size_type index, size_type n, bool shareable )
{
if( m_pstr->ref == unshareable || m_pstr->ref == 1 )
return;
string_type* pstr = alloc_str();
pstr->memstr.replace( size_type(0), size_type(0),
m_pstr->memstr.data() + index, n );
--(m_pstr->ref);
if( !shareable )
pstr->ref = unshareable;
m_pstr = pstr;
}
}; //end class shared_string
template< typename CharT, typename Traits, typename Allocator >
void shared_string<CharT, Traits, Allocator>::clear()
{
if( m_pstr->ref == unshareable || m_pstr->ref == 1 )
m_pstr->memstr.clear();
else
{
--( m_pstr->ref );
m_pstr = alloc_str();
}
}
template< typename CharT, typename Traits, typename Allocator >
void shared_string<CharT, Traits, Allocator>::reserve( size_type new_capa )
{
if( capacity() < new_capa )
{
string_type* pstr = alloc_str();
pstr->memstr.reserve( new_capa );
pstr->memstr.replace( size_type(0), size_type(0),
m_pstr->memstr.data(), size() );
release();
m_pstr = pstr;
}
}
template< typename CharT, typename Traits, typename Allocator >
void shared_string<CharT, Traits, Allocator>::resize( size_type new_size,
CharT c )
{
if( capacity() < new_size )
{
string_type* pstr = alloc_str();
pstr->memstr.reserve( new_size );
pstr->memstr.replace( size_type(0), size_type(0),
m_pstr->memstr.data(),
std::min(size(), new_size) );
pstr->memstr.resize( new_size, c );
release();
m_pstr = pstr;
}
else if( size() != new_size )
{
copy_str( 0, size(), true );
m_pstr->memstr.resize( new_size, c );
}
}
template< typename CharT, typename Traits, typename Allocator >
shared_string<CharT, Traits, Allocator>&
shared_string<CharT, Traits, Allocator>::replace( size_type index,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -