以前写的一个动态字符串的实现,本来是想找一下原来写的数据库与通讯程序的封装类,好像被弄丢了,遗憾!
// Filename: DynamicString.h
#ifndef _DYNAMICSTRING_
#define _DYNAMICSTRING_
#include
class DynamicString
{
public:
DynamicString();
DynamicString( std::size_t n , char c );
DynamicString( const char *first , const char *last );
DynamicString( const char *str );
DynamicString( const DynamicString &rhs );
DynamicString& operator=( const DynamicString &rhs ) ;
~ DynamicString ( ) ;
std::size_t _size( ) const ;
char* _begin();
char* _end();
const char* _begin() const;
const char* _end() const;
const char* _c_str() ;
const char* _data() const ;
DynamicString _substr( std::size_t index , std::size_t n ) ;
void _push_back( char c );
void _pop_back() ;
std::size_t _capacity( ) const ;
void _reserve( std::size_t n );
void _resize( std::size_t n ,char c );
void _erase( std::size_t index );
void _erase( std::size_t first ,std::size_t last ) ;
void _insert( std::size_t index , std::size_t n , char c ) ;
void _insert(std::size_t index , const char* first , const char* last ) ;
char& operator[]( std::size_t index );
const char& operator[]( std::size_t index ) const ;
char& _at( std::size_t index );
const char& _at( std::size_t index ) const ;
void _swap( DynamicString& rhs ) ;
void _assign( std::size_t n , char c ) ;
void _assign( const char* first , const char* last ) ;
void _assign( const char* str ) ;
bool _empty() { return m_len ? false : true ; }
DynamicString &operator+= ( char c ) ;
DynamicString &operator+= ( char *s ) ;
DynamicString &operator+= ( DynamicString &str ) ;
DynamicString &operator= ( char c ) ;
DynamicString &operator= ( char *s ) ;
private:
const static std::size_t MINLENGTH ;
std::size_t m_len;
std::size_t m_capa;
char *m_data;
char* alloc_char( std::size_t n) { return new char[n]; }
//计算机器分配的最小空间
std::size_t cal_data( std::size_t n )
{
std::size_t result = MINLENGTH ;
if( n >= MINLENGTH )
while( result < n )
result *= 2 ;
return result ;
}
};
bool operator== ( const DynamicString &left, const DynamicString &right )
{
bool tmpb = false ;
if( left._size() == right._size() )
{
tmpb = std::equal( left._begin(), left._end(), right._begin() ) ;
}
return tmpb ;
}
bool operator!= ( const DynamicString & left, const DynamicString &right )
{
bool tmpb = false ;
tmpb = ( ! ( left == right ) ) ;
return tmpb ;
}
/*
template
bool lexicographical_compare(InIt1 first1, InIt1 last1,
InIt2 first2, InIt2 last2);
template
bool lexicographical_compare(InIt1 first1, InIt1 last1,
InIt2 first2, InIt2 last2, Pred pr);
*/
bool operator< ( const DynamicString &left, const DynamicString &right )
{
bool tmpb = false ;
tmpb = std::lexicographical_compare( left._begin(), left._end(),
right._begin(), right._end() ) ;
return tmpb ;
}
bool operator<= ( const DynamicString &left, const DynamicString &right )
{
bool tmpb = false ;
tmpb = ( ! ( right < left ) ) ;
return tmpb ;
}
bool operator> ( const DynamicString &left, const DynamicString &right )
{
bool tmpb = false ;
tmpb = ( ! ( left <= right ) ) ;
return tmpb ;
}
bool operator>= ( const DynamicString &left, const DynamicString &right )
{
bool tmpb = false ;
tmpb = ( ! ( left < right ) ) ;
return tmpb ;
}
#endif
// Filename: DynamicString.cpp
//define the identidy-type size_t
#include "DynamicString.h"
#include
#include
#include
const std::size_t DynamicString::MINLENGTH = 32 ;
DynamicString::DynamicString( ) : m_len(0), m_capa(0), m_data(0) { }
DynamicString::DynamicString( std::size_t n , char c ) : m_len(0),
m_capa( 0 ) , m_data( 0 )
{
std::size_t tmpx = cal_data( 2 * n + 1 ) ;
m_data = alloc_char( tmpx );
if( m_data )
{
std::fill( m_data , m_data + tmpx ,'\0' );
std::fill_n( m_data , n , c);
m_len = n ;
m_capa = tmpx - 1 ;
}
}
DynamicString::DynamicString( const char* first , const char* last ) :
m_len( 0 ), m_capa( 0 ),m_data( 0 )
{
ptrdiff_t tmpi = last - first ;
std::size_t tmpx = cal_data( 2 * tmpi + 1 );
m_data = alloc_char( tmpx );
if( m_data )
{
std::fill( m_data , m_data + tmpx , '\0');
m_len = tmpi ;
m_capa = tmpx - 1 ;
char *tmpj = m_data ;
for( const char* tmpk = first ; tmpk != last ; ++tmpk , ++tmpj )
*tmpj = *tmpk ;
//std::copy( first ,last ,m_data );
}
}
DynamicString::DynamicString( const char* str ) : m_len( 0 ),
m_capa( 0 ) , m_data( 0 )
{
std::size_t tmpi = strlen(str);
std::size_t tmpx = cal_data( 2 * tmpi + 1 );
m_data = alloc_char( tmpx ) ;
if( m_data )
{
std::fill( m_data , m_data + tmpx , '\0');
m_len = tmpi;
m_capa = tmpx - 1 ;
char *tmpj = m_data ;
for( const char *tmpk = str; tmpk != str + tmpi +1; ++tmpk,++tmpj )
*tmpj = *tmpk;
}
}
DynamicString::DynamicString( const DynamicString &rhs ) : m_len(0),m_capa(0),
m_data(0)
{
std::size_t tmpx = cal_data( 2 * rhs.m_len + 1 ) ;
m_data = alloc_char( tmpx );
if( m_data )
{
std::fill( m_data , m_data + tmpx , '\0' );
/*
for ( char* tmpi = m_data ; tmpi != rhs.m_data + m_len ; ++tmpi)
*tmpi = (*rhs.m_data)++;
*/
std::copy( rhs._begin(), rhs._end(), m_data ) ;
m_len = rhs.m_len;
m_capa = tmpx - 1 ;
}
}
DynamicString& DynamicString::operator=( const DynamicString &rhs )
{
if( &rhs != this )
{
if( m_capa <= rhs._size() )
{
delete [] m_data ;
std::size_t tmpx = cal_data( rhs.m_len * 2 + 1 ) ;
m_data = alloc_char( tmpx );
if( m_data )
{
std::copy( rhs._begin(), rhs._end() , m_data ) ;
m_len = rhs.m_len ;
m_capa = tmpx - 1 ;
}
}
else
{
std::copy( rhs.m_data, rhs.m_data + rhs.m_capa ,m_data );
m_len = rhs.m_len ;
}
}
return *this ;
}
DynamicString::~DynamicString( )
{
if( ! m_data ) delete []m_data ;
}
std::size_t DynamicString::_size( ) const
{
return m_len ;
}
char* DynamicString::_begin()
{
return m_data ;
}
const char* DynamicString::_begin() const
{
return m_data ;
}
char* DynamicString::_end()
{
return m_data + m_len ;
}
const char* DynamicString::_end() const
{
return m_data + m_len ;
}
const char* DynamicString::_c_str()
{
*( m_data + m_len ) = '\0' ;
return m_data;
}
const char* DynamicString::_data() const
{
return m_data;
}
DynamicString DynamicString::_substr( std::size_t index , std::size_t n )
{
if( index < m_len )
return DynamicString( m_data + index,
m_data + std::min( index + n, m_len ) ) ;
else
throw std::out_of_range( "Access out of rang ! " ) ;
}
void DynamicString::_push_back( char c )
{
if( m_len + 1 > m_capa )
{
std::size_t tmpx = cal_data( 2 * m_capa + 1 ) ;
char *tmp = alloc_char( tmpx ) ;
std::fill( tmp, tmp + tmpx, '\0' );
std::copy( m_data , m_data + m_len , tmp );
*( tmp + m_capa ) = c ;
m_len = m_capa ;
m_capa = tmpx - 1 ;
delete []m_data ;
m_data = tmp ;
}
else
{
*(m_data + m_len ) = c ;
++ m_len ;
}
}
void DynamicString::_pop_back()
{
if( m_data )
{
if( m_len != 0 )
{
m_len -= 1 ;
*( m_data + m_len ) = '\0' ;
}
}
return ;
}
std::size_t DynamicString::_capacity() const
{
if( m_data )
return m_capa ;
else
return 0;
}
void DynamicString::_reserve( std::size_t n )
{
if( n > m_capa )
{
std::size_t tmpx = cal_data( n + 1 ) ;
char* tmp = alloc_char( tmpx );
std::fill( tmp, tmp + tmpx, '\0' ) ;
std::copy( m_data, m_data + m_capa + 1 , tmp );
m_capa = tmpx - 1 ;
delete []m_data ;
m_data = tmp ;
}
return ;
}
void DynamicString::_resize( std::size_t n, char c )
{
if( m_len < n )
_insert( m_len, n - m_len, c ) ;
else if( m_len > n )
_erase( n, m_len ) ;
return ;
}
void DynamicString::_erase( std::size_t index )
{
if( m_data )
{
if( index < m_len )
{
std::copy( m_data + index + 1 , m_data + m_len, m_data + index );
--m_len ;
*( m_data + m_len ) = '\0';
}
}
return ;
}
void DynamicString::_erase( std::size_t first, std::size_t last )
{
if( first < m_len )
{
std::copy( m_data + std::min( last, m_len ), m_data + m_len, m_data + first ) ;
m_len -= ( std::min( last, m_len ) - first ) ;
std::fill( m_data + m_len, m_data + m_capa, '\0' );
}
return ;
}
void DynamicString::_insert( std::size_t index, std::size_t n, char c )
{
if( index <= m_len )
if( m_len + n < m_capa )
{
std::copy_backward( m_data + index , m_data + m_len, m_data + m_len + n );
std::fill_n( m_data + index, n, c ) ;
m_len += n ;
}
else
{
std::size_t tmpx = cal_data( ( m_len + n ) * 2 + 1 );
char* tmp = alloc_char( tmpx ) ;
std::fill( tmp, tmp + tmpx, '\0');
std::copy( m_data, m_data + index, tmp ) ;
std::fill_n( tmp + index, n, c );
std::copy( m_data + index, m_data + m_len, tmp + index + n );
m_len += n ;
m_capa = tmpx - 1 ;
delete []m_data ;
m_data = tmp ;
}
//else
// throw std::out_of_range( "Access out of range ! " ) ;
}
void DynamicString::_insert( std::size_t index, const char* first,
const char* last )
{
if( index > m_len )
{
//throw std::out_of_range( "Access out of range !" ) ;
//std::copy( first, last, m_len ) ;
//m_len += ( last - first ) ;
}
else
{ if( m_len + ( last - first ) < m_capa )
{
std::copy_backward( m_data + index, m_data + m_len,
m_data + m_len + ( last - first ) ) ;
std::copy( first, last, m_data + index ) ;
m_len += ( last - first );
}
else
{
std::size_t tmpx = cal_data( ( m_len + ( last - first ) ) * 2 + 1 );
char* tmp = alloc_char( tmpx ) ;
std::fill( tmp,tmp + tmpx, '\0' );
std::copy( m_data, m_data + index, tmp);
std::copy( first, last, tmp + index );
std::copy( m_data + index + 1, m_data + m_len,
tmp + index + ( last - first ) );
m_len += ( last - first );
m_capa = tmpx - 1 ;
}
}
}
char& DynamicString::operator[]( std::size_t index )
{
return *( m_data + index ) ;
}
const char& DynamicString::operator[]( std::size_t index ) const
{
return *( m_data + index ) ;
}
char& DynamicString::_at( std::size_t index )
{
if( 0 <= index && index < m_len )
return *( m_data + index ) ;
else
throw std::out_of_range("Access out of range !") ;
}
const char& DynamicString::_at( std::size_t index ) const
{
if( 0 <= index && index < m_len )
return *( m_data + index ) ;
else
throw std::out_of_range("Access out of range !") ;
}
void DynamicString::_swap( DynamicString& rhs )
{
char *tmp = rhs.m_data ;
std::size_t tmplen = rhs.m_len ;
std::size_t tmpcapa = rhs.m_capa ;
rhs.m_data = m_data ;
rhs.m_len = m_len ;
rhs.m_capa = m_capa ;
m_data = tmp ;
m_len = tmplen ;
m_capa = tmpcapa ;
}
void DynamicString::_assign( std::size_t n, char c )
{
if( n >= m_capa )
{
std::size_t tmpx = cal_data( 2 * n + 1 ) ;
char *tmp = alloc_char( tmpx ) ;
std::fill( tmp, tmp + tmpx, '\0' );
std::fill_n( tmp, n, c );
m_len = n ;
m_capa = tmpx - 1 ;
delete []m_data ;
m_data = tmp ;
}
else
{
std::fill( m_data, m_data + m_capa, '\0' );
std::fill( m_data, m_data + n, c );
m_len = n ;
}
}
void DynamicString::_assign( const char* first, const char* last )
{
if( ( last - first ) >= static_cast
( m_capa ) )
{
std::size_t tmpx = cal_data( 2 * ( last - first ) + 1 ) ;
char *tmp = alloc_char( tmpx ) ;
std::fill( tmp, tmp + tmpx, '\0' );
std::copy( first, last, tmp );
m_len = static_cast< std::size_t >( last - first ) ;
m_capa = tmpx - 1 ;
delete []m_data ;
m_data = tmp ;
}
else
{
std::fill( m_data, m_data + m_capa, '\0' );
std::copy( first, last, m_data );
m_len += ( last - first );
}
}
void DynamicString::_assign( const char* str )
{
std::size_t stringlen = strlen( str );
if( stringlen >= m_capa )
{
std::size_t tmpx = cal_data( 2 * stringlen + 1 ) ;
char *tmp = alloc_char( tmpx ) ;
std::fill( tmp, tmp + tmpx, '\0' );
std::copy( str, str + stringlen, tmp );
m_len = stringlen ;
m_capa = tmpx - 1 ;
delete []m_data ;
m_data = tmp ;
}
else
{
std::fill( m_data, m_data + m_capa, '\0' );
std::copy( str, str + strlen( str ), m_data );
m_len = strlen( str );
}
}
DynamicString & DynamicString::operator+= ( char c )
{
_push_back( c ) ;
return *this ;
}
DynamicString & DynamicString::operator+= ( char *s )
{
_insert( m_len, s, s + strlen( s ) ) ;
return *this ;
}
DynamicString & DynamicString::operator+= ( DynamicString &str )
{
_insert( m_len, str._begin(),str._end() ) ;
return *this ;
}
DynamicString & DynamicString::operator= ( char c )
{
_assign( 1, c ) ;
return *this ;
}
DynamicString & DynamicString::operator= ( char *s )
{
_assign( s ) ;
return *this ;
}
//template
// bool equal(InIt1 first, InIt1 last, InIt2 x);