Add insertion functions to basic_string. Add size function to basic_string.

This commit is contained in:
rexy712 2022-06-21 19:31:07 -07:00
parent 00355a64c6
commit 1799c1640b
2 changed files with 134 additions and 2 deletions

View File

@ -26,6 +26,7 @@
#include <climits> //CHAR_BIT #include <climits> //CHAR_BIT
#include <iterator> //reverse_iterator #include <iterator> //reverse_iterator
#include <iostream> //ostream #include <iostream> //ostream
#include <initializer_list>
#include "steal.hpp" #include "steal.hpp"
#include "utility.hpp" #include "utility.hpp"
@ -188,6 +189,9 @@ namespace rexy{
else else
return get_short_length(); return get_short_length();
} }
constexpr size_type size(void)const noexcept{
return length();
}
constexpr size_type capacity(void)const noexcept{ constexpr size_type capacity(void)const noexcept{
if(islong()) if(islong())
return get_long_capacity(); return get_long_capacity();
@ -259,6 +263,8 @@ namespace rexy{
using const_reverse_iterator = typename string_base<Char>::const_reverse_iterator; using const_reverse_iterator = typename string_base<Char>::const_reverse_iterator;
using allocator_type = Alloc; using allocator_type = Alloc;
static constexpr size_type npos = size_type{-1};
private: private:
REXY_CPP20_CONSTEXPR void _copy_construct_string(const_pointer data, size_type len, size_type cap) REXY_CPP20_CONSTEXPR void _copy_construct_string(const_pointer data, size_type len, size_type cap)
noexcept(is_nothrow_allocator_v<Alloc>); noexcept(is_nothrow_allocator_v<Alloc>);
@ -302,8 +308,28 @@ namespace rexy{
//Replace managed pointer. Frees existing value //Replace managed pointer. Frees existing value
REXY_CPP20_CONSTEXPR void reset(pointer val = nullptr)noexcept(is_nothrow_allocator_v<Alloc>); REXY_CPP20_CONSTEXPR void reset(pointer val = nullptr)noexcept(is_nothrow_allocator_v<Alloc>);
REXY_CPP20_CONSTEXPR void reset(pointer val, size_type len)noexcept(is_nothrow_allocator_v<Alloc>); REXY_CPP20_CONSTEXPR void reset(pointer val, size_type len)noexcept(is_nothrow_allocator_v<Alloc>);
REXY_CPP20_CONSTEXPR bool resize(size_type newsize) REXY_CPP20_CONSTEXPR bool resize(size_type newsize)noexcept(is_nothrow_allocator_v<Alloc>);
noexcept(is_nothrow_allocator_v<Alloc>);
//TODO more insert
REXY_CPP20_CONSTEXPR basic_string& insert(size_type pos, size_type insert_count, value_type v)noexcept(is_nothrow_allocator_v<Alloc>);
REXY_CPP20_CONSTEXPR basic_string& insert(size_type pos, value_type v)noexcept(is_nothrow_allocator_v<Alloc>);
REXY_CPP20_CONSTEXPR basic_string& insert(size_type pos, const_pointer str)noexcept(is_nothrow_allocator_v<Alloc>);
REXY_CPP20_CONSTEXPR basic_string& insert(size_type pos, const_pointer str, size_type insert_count)noexcept(is_nothrow_allocator_v<Alloc>);
REXY_CPP20_CONSTEXPR basic_string& insert(size_type pos, const basic_string& other)noexcept(is_nothrow_allocator_v<Alloc>);
REXY_CPP20_CONSTEXPR basic_string& insert(size_type pos, const basic_string& other, size_type index_str, size_type count = npos)noexcept(is_nothrow_allocator_v<Alloc>);
REXY_CPP20_CONSTEXPR basic_string& insert(const_iterator pos, value_type v)noexcept(is_nothrow_allocator_v<Alloc>);
REXY_CPP20_CONSTEXPR basic_string& insert(const_iterator pos, size_type count, value_type v)noexcept(is_nothrow_allocator_v<Alloc>);
template<class InIt>
REXY_CPP20_CONSTEXPR basic_string& insert(const_iterator pos, InIt start, InIt last)noexcept(is_nothrow_allocator_v<Alloc>);
template<class InIt>
REXY_CPP20_CONSTEXPR basic_string& insert(size_type pos, InIt start, InIt last)noexcept(is_nothrow_allocator_v<Alloc>);
REXY_CPP20_CONSTEXPR basic_string& insert(const_iterator pos, std::initializer_list<value_type> list)noexcept(is_nothrow_allocator_v<Alloc>);
template<class StringView>
REXY_CPP20_CONSTEXPR auto insert(size_type pos, const StringView& sv)noexcept(is_nothrow_allocator_v<Alloc>) ->
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>>;
template<class StringView>
REXY_CPP20_CONSTEXPR auto insert(size_type pos, const StringView& sv, size_type index_str, size_type count = npos)noexcept(is_nothrow_allocator_v<Alloc>) ->
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>>;
REXY_CPP20_CONSTEXPR void push_back(value_type data) REXY_CPP20_CONSTEXPR void push_back(value_type data)
noexcept(is_nothrow_allocator_v<Alloc>); noexcept(is_nothrow_allocator_v<Alloc>);
@ -317,6 +343,7 @@ namespace rexy{
template<REXY_ALLOCATOR_CONCEPT A = allocator_type> template<REXY_ALLOCATOR_CONCEPT A = allocator_type>
REXY_CPP20_CONSTEXPR basic_string<value_type,A> substring(size_type start, size_type end)const; REXY_CPP20_CONSTEXPR basic_string<value_type,A> substring(size_type start, size_type end)const;
REXY_CPP20_CONSTEXPR basic_string substr(size_type start, size_type end)const;
REXY_CPP20_CONSTEXPR pointer release(void)noexcept(is_nothrow_allocator_v<Alloc>); REXY_CPP20_CONSTEXPR pointer release(void)noexcept(is_nothrow_allocator_v<Alloc>);
using detail::hasallocator<Alloc>::allocator; using detail::hasallocator<Alloc>::allocator;

View File

@ -250,6 +250,106 @@ namespace rexy{
return (*this = basic_string(this->get_pointer(), newsize)); return (*this = basic_string(this->get_pointer(), newsize));
} }
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, size_type insert_count, value_type v)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
struct insert_adapter{
size_type max;
value_type val;
constexpr insert_adapter& operator++(void)noexcept{
--max;
return *this;
}
constexpr value_type operator*(void)const noexcept{
return val;
}
constexpr bool operator==(const insert_adapter& other)const = default;
constexpr bool operator!=(const insert_adapter& other)const = default;
};
return insert(pos, insert_adapter{insert_count, v}, insert_adapter{0, v});
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, value_type v)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
return insert(pos, size_type{1}, v);
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, const_pointer str)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
const size_type slen = rexy::strlen(str);
return insert(pos, str, str + slen);
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, const_pointer str, size_type insert_count)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
return insert(pos, str, str + insert_count);
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, const basic_string& other)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
return insert(pos, other.begin(), other.end());
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, const basic_string& other, size_type index_str, size_type count)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
return insert(pos, other.begin() + index_str, other.begin() + index_str + count);
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(const_iterator pos, value_type v)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
return insert(pos, size_type{1}, v);
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(const_iterator pos, size_type count, value_type v)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
return insert(pos - this->begin(), count, v);
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
template<class InIt>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(const_iterator pos, InIt start, InIt last)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
return insert(pos - this->begin(), std::move(start), std::move(last));
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(const_iterator pos, std::initializer_list<value_type> list)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
return insert(pos, list.begin(), list.end());
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
template<class StringView>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, const StringView& sv)noexcept(is_nothrow_allocator_v<Alloc>) ->
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>>
{
return insert(pos, sv.begin(), sv.end());
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
template<class StringView>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, const StringView& sv, size_type index_str, size_type count)noexcept(is_nothrow_allocator_v<Alloc>) ->
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>>
{
return insert(pos, sv.begin() + index_str, sv.begin() + index_str + count);
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
template<class InIt>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, InIt start, InIt last)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
const size_type len = this->length();
size_type insert_count = 0;
for(auto it = start;it != last;++it, ++insert_count){}
resize(rexy::max(pos + insert_count, len + insert_count));
const size_type move_count = rexy::min<size_type>(0, len - pos);
const auto ptr = this->get_pointer();
for(size_type i = move_count+1;i > 0;--i){
const size_type index = i + pos;
ptr[index] = ptr[index-1];
}
{
size_type i = 0;
for(auto it = start;it != last;++it,++i){
ptr[pos+i] = *it;
}
}
this->set_length(len + insert_count);
return *this;
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc> template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::push_back(value_type data) REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::push_back(value_type data)
noexcept(is_nothrow_allocator_v<Alloc>) noexcept(is_nothrow_allocator_v<Alloc>)
@ -320,6 +420,11 @@ namespace rexy{
tmp.append(this->get() + start, newlen); tmp.append(this->get() + start, newlen);
return tmp; return tmp;
} }
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::substr(size_type start, size_type end)const -> basic_string{
return substring<allocator_type>(start, end);
}
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc> template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::release(void)noexcept(is_nothrow_allocator_v<Alloc>) -> pointer{ REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::release(void)noexcept(is_nothrow_allocator_v<Alloc>) -> pointer{
if(this->islong()){ if(this->islong()){