Chinaunix首页 | 论坛 | 博客
  • 博客访问: 310091
  • 博文数量: 163
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: -40
  • 用 户 组: 普通用户
  • 注册时间: 2017-03-08 00:28
文章分类

全部博文(163)

文章存档

2015年(2)

2014年(35)

2013年(28)

2012年(30)

2011年(22)

2010年(14)

2009年(8)

2008年(13)

2007年(11)

分类: C/C++

2007-12-15 19:48:46

以前写的一个动态字符串的实现,本来是想找一下原来写的数据库与通讯程序的封装类,好像被弄丢了,遗憾!
 
 
// 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);
阅读(2587) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~