📄 ycpp_string.hpp
字号:
/*
* 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 + -