⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mstl_optm_string.hpp

📁 一个类STL的多平台可移植的算法容器库,主要用于嵌入式系统编程时的内存管理等方面
💻 HPP
📖 第 1 页 / 共 3 页
字号:
    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 + -