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

📄 ycpp_string.hpp

📁 一个类STL的多平台可移植的算法容器库,主要用于嵌入式系统编程时的内存管理等方面
💻 HPP
📖 第 1 页 / 共 5 页
字号:
/*
 * The young Library
 * Copyright (c) 2005 by Yang Huan(杨桓)

 * Permission to use, copy, modify, distribute and sell this software for any
 * purpose is hereby granted without fee, provided that the above copyright
 * notice appear in all copies and that both that copyright notice and this
 * permission notice appear in supporting documentation.
 * The author make no representations about the suitability of this software
 * for any purpose. It is provided "as is" without express or implied warranty.
 */

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#ifndef __MACRO_CPLUSPLUS_YOUNG_LIBRARY_STRING_HEADER_FILE__
#define __MACRO_CPLUSPLUS_YOUNG_LIBRARY_STRING_HEADER_FILE__
//------------------------------------------------------------------------------
#include <memory>
#include <string>
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <algorithm>
#include "ycpp_memory.hpp"
#include "../youngc/yc_dymemarr.h"
//------------------------------------------------------------------------------
namespace youngcpp {
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

template< typename CharT, typename Traits = std::char_traits<CharT>,
          typename Allocator = std::allocator<CharT> >
class basic_string
{
public:
    typedef  basic_string<CharT, Traits, Allocator>  self;

    typedef  Traits                                 traits_type;
    typedef  Allocator                              allocator_type;
    typedef  CharT                                  value_type;
    typedef  value_type&                            reference;
    typedef  const value_type&                      const_reference;
    typedef  value_type*                            pointer;
    typedef  const value_type*                      const_pointer;
    typedef  size_t                                 size_type;
    typedef  ptrdiff_t                              difference_type;
    typedef  value_type*                            iterator;
    typedef  const value_type*                      const_iterator;
    typedef  std::reverse_iterator<iterator>        reverse_iterator;
    typedef  std::reverse_iterator<const_iterator>  const_reverse_iterator;

    static const size_type npos = SIZE_MAX;



    basic_string()
        {  m_dynamic = false;  m_str.st.len = 0;  }

    basic_string( const CharT* str )
    {
        m_dynamic = false;
        m_str.st.len = 0;
        replace( size_type(0), size_type(0), str, Traits::length(str) );
    }

    basic_string( const CharT* str, size_type n )
    {
        m_dynamic = false;
        m_str.st.len = 0;
        replace( size_type(0), size_type(0), str, n );
    }

    basic_string( size_type n, CharT c )
    {
        m_dynamic = false;
        m_str.st.len = 0;
        replace( size_type(0), size_type(0), n, c );
    }
    basic_string( int n, CharT c )
    {
        m_dynamic = false;
        m_str.st.len = 0;
        replace( size_type(0), size_type(0), (size_type)n, c );
    }
    basic_string( long n, CharT c )
    {
        m_dynamic = false;
        m_str.st.len = 0;
        replace( size_type(0), size_type(0), (size_type)n, c );
    }

    template< typename InputIterator >
    basic_string( InputIterator first, InputIterator last )
    {
        m_dynamic = false;
        m_str.st.len = 0;
        replace( m_str.st.data, m_str.st.data, first, last );
    }

    basic_string( const self& rhs, size_type index = 0, size_type n = npos )
    {
        m_dynamic = false;
        m_str.st.len = 0;
        if( index > rhs.size() )
            throw std::out_of_range( "young::basic_string::copy_constructor out of range!" );
        replace( size_type(0), size_type(0), rhs.begin() + index,
                 std::min(rhs.size() - index, n) );
    }

    self& operator=( const self& rhs )
    {
        if( &rhs != this )
            replace( size_type(0), size(), rhs.data(), rhs.size() );
        return *this;
    }

    basic_string( const std::basic_string<CharT, Traits, Allocator>& rhs )
    {
        m_dynamic = false;
        m_str.st.len = 0;
        replace( m_str.st.data, m_str.st.data, rhs.begin(), rhs.end() );
    }

    self& operator=( const std::basic_string<CharT, Traits, Allocator>& rhs )
    {
        replace( begin(), end(), rhs.begin(), rhs.end() );
        return *this;
    }

    ~basic_string()
    {
        if( m_dynamic )
            dymemarr_destroy( &(m_str.dy) );
    }

    static void init_move( void* uninit_dst, void* src )
    {
        self* d = static_cast<self*>(uninit_dst);
        self* s = static_cast<self*>(src);
        d->m_dynamic = s->m_dynamic;
        d->m_str = s->m_str;
        s->m_dynamic = false;
        s->m_str.st.len = 0;
    }

    static void assign_move( void* dst, void* src )
    {
        std::swap( static_cast<self*>(dst)->m_dynamic,
                   static_cast<self*>(src)->m_dynamic );
        std::swap( static_cast<self*>(dst)->m_str,
                   static_cast<self*>(src)->m_str );
    }

    const CharT* data() const
    {
        return m_dynamic ? DYMEMARR_BEGIN( m_str.dy, CharT )
                         : m_str.st.data;
    }

    const CharT* c_str() const
        {  *( (iterator)end() ) = 0;  return data();  }

    self substr( size_type index = 0, size_type n = npos ) const
        {  return self( *this, index, n );  }

    self& operator=( CharT c )
        {  return replace( size_type(0), npos, size_type(1), c );  }
    self& operator=( const CharT* str )
        {  return replace( size_type(0), size_type(0), str,
                           Traits::length(str) );  }

    self& operator+=( CharT c )
        {  push_back(c);  return *this;  }
    self& operator+=( const CharT* str )
        {  return replace( size(), size_type(0), str, Traits::length(str) );  }
    self& operator+=( const self& rhs )
        {  return replace( size(), size_type(0), rhs.data(), rhs.size() );  }

    void pop_back()
    {
        if( m_dynamic )
            dymemarr_pop_back( &(m_str.dy) );
        else
        {
            if( m_str.st.len > 0 )
                --m_str.st.len;
        }
    }

    void push_back( const CharT& c )
    {
        if( !m_dynamic && STATIC_LEN <= m_str.st.len )
            static_to_dynamic( STATIC_LEN + 1 );
        if( !m_dynamic )
        {
            m_str.st.data[ (size_type)m_str.st.len ] = c;
            ++m_str.st.len;
        }
        else
        {
            bool result = true;
            DYMEMARR_PUSH_BACK( m_str.dy, c, CharT, result );
            if( !result )
                throw std::bad_alloc();
        }
    }

    size_type size() const
        {  return m_dynamic ? DYMEMARR_SIZE(m_str.dy, CharT)
                            : m_str.st.len;  }
    size_type capacity() const
        {  return m_dynamic ? DYMEMARR_CAPACITY(m_str.dy, CharT)
                            : STATIC_LEN;  }
    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()
        {  return m_dynamic ? (iterator)dymemarr_begin( &(m_str.dy) )
                            : m_str.st.data;  }
    iterator end()
        {  return m_dynamic ? (iterator)dymemarr_end( &(m_str.dy) )
                            : m_str.st.data + m_str.st.len;  }
    const_iterator begin() const
        {  return m_dynamic ? (const_iterator)dymemarr_begin( &(m_str.dy) )
                            : m_str.st.data;  }
    const_iterator end() const
        {  return m_dynamic ? (const_iterator)dymemarr_end( &(m_str.dy) )
                            : m_str.st.data + m_str.st.len;  }

    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()
    {
        if( !m_dynamic )
            m_str.st.len = 0;
        else
            dymemarr_erase_range( &(m_str.dy), 0, SIZE_MAX );
    }

    void reserve( size_type new_capa )
    {
        if( capacity() < new_capa && new_capa > STATIC_LEN )
        {
            self temp;
            if( !dymemarr_reserve( &(m_str.dy), new_capa ) )
                throw std::bad_alloc();
            dymemarr_insert_array( &(m_str.dy), 0, data(), size() );
            swap( temp );
        }
    }

    void resize( size_type new_size, CharT c = CharT() )
    {
        if( new_size > max_size() )
            std::length_error( "young::basic_string::resize length error!" );
        size_type old_len = size();
        if( new_size > old_len )
            append( new_size - old_len, c );
        else if( new_size < old_len )
            erase( new_size, old_len - new_size );
    }

    CharT& operator[]( size_type index )
        {  return *( begin() + index );  }
    const CharT& operator[]( size_type index ) const
        {  return *( begin() + index );  }

    CharT& at( size_type index )
    {
        if( index >= size() )
            throw std::out_of_range( "young::basic_string::at out of range!" );
        return *( begin() + index );
    }
    const CharT& at( size_type index ) const
    {
        if( index >= size() )
            throw std::out_of_range( "young::basic_string::at out of range!" );
        return *( begin() + index );
    }

    void swap( self& rhs )
    {
        if( this != &rhs )
        {
            std::swap( m_dynamic, rhs.m_dynamic );
            std::swap( m_str, rhs.m_str );
        }
    }

    size_type copy( CharT* str, size_type n = npos, size_type index = 0 ) const
    {
        size_type len = size();
        if( index > size() )
            throw std::out_of_range( "young::basic_string::copy out of range!" );
        if( n > len - index )
            n = len - index;
        Traits::copy( str, data() + index, n );
        return n;
    }


    //replace 1:
    self& replace( size_type index, size_type before,
                   size_type after, CharT c );
    //replace 2:
    self& replace( size_type index, size_type before,
                   const CharT* str, size_type after );
    //replace 3:
    template< typename InputIterator >
    self& replace( iterator first_pos, iterator last_pos,
                   InputIterator first, InputIterator last );
    //replace 4:
    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( 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 );
    }
    //replace:5
    self& replace( size_type index, size_type n, const CharT* str )
        {  return replace( index, n, str, Traits::length(str) );  }
    //replace:6
    self& replace( size_type index, size_type n, CharT c )
        {  return replace( index, n, size_type(1), c );  }
    //replace:7
    self& replace( iterator first, iterator last, const self& str )
        {  return replace( size_type(first - begin()), size_type(last - first),
                           str, size_type(0), npos );  }
    //replace:8
    self& replace( iterator first, iterator last,
                   const CharT* str, size_type n )
        {  return replace( size_type(first - begin()),
                           size_type(last - first), str, n );  }
    //replace:9
    self& replace( iterator first, iterator last, const CharT* str )
        {  return replace( size_type(first - begin()), size_type(last - first),
                           str, Traits::length(str) );  }
    //replace:10
    self& replace( iterator first, iterator last, size_type n, CharT c )
        {  return replace( size_type(first - begin()), size_type(last - first),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -