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

📄 ycpp_string.hpp

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