Remove deprecated string functions. Add replace functions to basic_string.
This commit is contained in:
parent
2a69be29a6
commit
cdd51a6e3a
@ -37,7 +37,7 @@ namespace rexy::fmt{
|
|||||||
string_view errstr;
|
string_view errstr;
|
||||||
|
|
||||||
constexpr const char* what(void)const{
|
constexpr const char* what(void)const{
|
||||||
return errstr;
|
return errstr.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -49,10 +49,15 @@ namespace rexy::fmt{
|
|||||||
requires(!UTF8_String<Char>)
|
requires(!UTF8_String<Char>)
|
||||||
constexpr OutIt perform_standard_format(const Char* c, OutIt out, const format_specs& specs, const std::locale& loc);
|
constexpr OutIt perform_standard_format(const Char* c, OutIt out, const format_specs& specs, const std::locale& loc);
|
||||||
template<UTF8_String Char, class OutIt>
|
template<UTF8_String Char, class OutIt>
|
||||||
|
requires(UTF8_String<Char>)
|
||||||
constexpr OutIt perform_standard_format(const Char* c, OutIt out, const format_specs& specs, const std::locale& loc);
|
constexpr OutIt perform_standard_format(const Char* c, OutIt out, const format_specs& specs, const std::locale& loc);
|
||||||
template<class Char, class OutIt>
|
template<class Char, class OutIt>
|
||||||
constexpr OutIt perform_standard_format(const Char* c, OutIt out);
|
constexpr OutIt perform_standard_format(const Char* c, OutIt out);
|
||||||
template<class Char, class OutIt>
|
template<class Char, class OutIt>
|
||||||
|
constexpr OutIt perform_standard_format(basic_string_view<std::type_identity_t<Char>> str, OutIt out, const format_specs& specs, const std::locale& loc);
|
||||||
|
template<class Char, class OutIt>
|
||||||
|
constexpr OutIt perform_standard_format(basic_string_view<std::type_identity_t<Char>> str, OutIt out);
|
||||||
|
template<class Char, class OutIt>
|
||||||
constexpr OutIt perform_standard_format(Char b, OutIt out, const format_specs& specs, const std::locale& loc);
|
constexpr OutIt perform_standard_format(Char b, OutIt out, const format_specs& specs, const std::locale& loc);
|
||||||
template<class Char, class OutIt>
|
template<class Char, class OutIt>
|
||||||
constexpr OutIt perform_standard_format(Char b, OutIt out);
|
constexpr OutIt perform_standard_format(Char b, OutIt out);
|
||||||
|
|||||||
@ -204,6 +204,7 @@ namespace rexy::fmt::detail{
|
|||||||
}
|
}
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Char, class OutIt>
|
template<class Char, class OutIt>
|
||||||
requires(!UTF8_String<Char>)
|
requires(!UTF8_String<Char>)
|
||||||
constexpr OutIt perform_standard_format(const Char* c, OutIt out, const format_specs& specs, const std::locale& loc){
|
constexpr OutIt perform_standard_format(const Char* c, OutIt out, const format_specs& specs, const std::locale& loc){
|
||||||
@ -228,6 +229,7 @@ namespace rexy::fmt::detail{
|
|||||||
return perform_format_write_aligned(std::move(out), est_width, specs, alignment::left, outputter);
|
return perform_format_write_aligned(std::move(out), est_width, specs, alignment::left, outputter);
|
||||||
}
|
}
|
||||||
template<UTF8_String Char, class OutIt>
|
template<UTF8_String Char, class OutIt>
|
||||||
|
requires(UTF8_String<Char>)
|
||||||
constexpr OutIt perform_standard_format(const Char* c, OutIt out, const format_specs& specs, const std::locale& loc){
|
constexpr OutIt perform_standard_format(const Char* c, OutIt out, const format_specs& specs, const std::locale& loc){
|
||||||
const basic_string_view<Char> str{c};
|
const basic_string_view<Char> str{c};
|
||||||
std::size_t est_width = 0;
|
std::size_t est_width = 0;
|
||||||
@ -263,6 +265,14 @@ namespace rexy::fmt::detail{
|
|||||||
}
|
}
|
||||||
return std::move(out);
|
return std::move(out);
|
||||||
}
|
}
|
||||||
|
template<class Char, class OutIt>
|
||||||
|
constexpr OutIt perform_standard_format(basic_string_view<std::type_identity_t<Char>> str, OutIt out, const format_specs& specs, const std::locale& loc){
|
||||||
|
return perform_standard_format<Char>(str.c_str(), std::move(out), specs, loc);
|
||||||
|
}
|
||||||
|
template<class Char, class OutIt>
|
||||||
|
constexpr OutIt perform_standard_format(basic_string_view<std::type_identity_t<Char>> str, OutIt out){
|
||||||
|
return perform_standard_format(str.c_str(), std::move(out));
|
||||||
|
}
|
||||||
|
|
||||||
template<class Char, class OutIt>
|
template<class Char, class OutIt>
|
||||||
constexpr OutIt perform_standard_format(Char b, OutIt out, const format_specs& specs, const std::locale& loc){
|
constexpr OutIt perform_standard_format(Char b, OutIt out, const format_specs& specs, const std::locale& loc){
|
||||||
|
|||||||
@ -63,22 +63,22 @@ namespace rexy::fmt::detail{
|
|||||||
|
|
||||||
template<class T, class It>
|
template<class T, class It>
|
||||||
concept HasInsertMethod = requires(T t, It i){
|
concept HasInsertMethod = requires(T t, It i){
|
||||||
{t.insert(0, i, i)};
|
{t.insert(1, i, i)}; //don't use 0 index because pointer conversion causes ambiguous call
|
||||||
{t.size()};
|
{t.size()};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct container_traits_helper{
|
|
||||||
using container = int;
|
|
||||||
};
|
|
||||||
template<class It>
|
template<class It>
|
||||||
struct container_traits : public It, public container_traits_helper{
|
struct something : public It{
|
||||||
template<class T = container_traits, class U = typename T::container>
|
template<class U = something, class C = decltype(U::container)>
|
||||||
static std::false_type check(int);
|
static std::true_type check(int);
|
||||||
static std::true_type check(...);
|
static std::false_type check(...);
|
||||||
|
|
||||||
|
static constexpr bool value = decltype(check(0))::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Char, class OutIt>
|
template<class Char, class OutIt>
|
||||||
OutIt real_write_out(const Char* start, std::size_t write_count, OutIt out){
|
OutIt real_write_out(const Char* start, std::size_t write_count, OutIt out){
|
||||||
static constexpr bool has_container = decltype(container_traits<OutIt>::check(0))::value;
|
static constexpr bool has_container = something<OutIt>::value;//decltype(container_traits<OutIt>::check(0))::value;
|
||||||
|
|
||||||
//optimize for types where direct access to the underlying container is available
|
//optimize for types where direct access to the underlying container is available
|
||||||
//check for a container member and a 'container_type' typedef in OutIt
|
//check for a container member and a 'container_type' typedef in OutIt
|
||||||
|
|||||||
@ -336,18 +336,6 @@ namespace rexy{
|
|||||||
|
|
||||||
constexpr basic_string_view<value_type> create_view(void)const noexcept;
|
constexpr basic_string_view<value_type> create_view(void)const noexcept;
|
||||||
constexpr basic_string_view<value_type> create_view(const_iterator start, const_iterator fin)const noexcept;
|
constexpr basic_string_view<value_type> create_view(const_iterator start, const_iterator fin)const noexcept;
|
||||||
|
|
||||||
|
|
||||||
[[deprecated]] constexpr pointer get(void)noexcept{return get_pointer();}
|
|
||||||
[[deprecated]] constexpr const_pointer get(void)const noexcept{return get_pointer();}
|
|
||||||
[[deprecated]] constexpr operator pointer(void)noexcept{return get_pointer();}
|
|
||||||
[[deprecated]] constexpr operator const_pointer(void)const noexcept{return get_pointer();}
|
|
||||||
[[deprecated]] constexpr const_iterator search(const string_base& s)const;
|
|
||||||
[[deprecated]] constexpr iterator search(const string_base& s);
|
|
||||||
template<class Searcher>
|
|
||||||
[[deprecated]] constexpr const_iterator search(const string_base& s, const Searcher& searcher)const;
|
|
||||||
template<class Searcher>
|
|
||||||
[[deprecated]] constexpr iterator search(const string_base& s, const Searcher& searcher);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -378,6 +366,8 @@ namespace rexy{
|
|||||||
noexcept(is_nothrow_allocator_v<Alloc>);
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR basic_string& _insert_impl(size_type pos, InputIt start, size_type insert_count)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR basic_string& _insert_impl(size_type pos, InputIt start, size_type insert_count)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
|
template<class InputIt>
|
||||||
|
constexpr basic_string& _replace_impl(size_type pos, size_type count, InputIt src, size_type count2);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr basic_string(void)noexcept;
|
constexpr basic_string(void)noexcept;
|
||||||
@ -389,7 +379,7 @@ namespace rexy{
|
|||||||
REXY_CPP20_CONSTEXPR basic_string(const_pointer data)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR basic_string(const_pointer data)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
REXY_CPP20_CONSTEXPR explicit basic_string(size_type len)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR explicit basic_string(size_type len)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
REXY_CPP20_CONSTEXPR basic_string(size_type len, size_type cap)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR basic_string(size_type len, size_type cap)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
template<class InputIt>
|
template<class InputIt, class Enable = std::enable_if_t<is_legacy_input_iterator_v<InputIt>,int>>
|
||||||
REXY_CPP20_CONSTEXPR basic_string(InputIt start, InputIt fin)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR basic_string(InputIt start, InputIt fin)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
REXY_CPP20_CONSTEXPR basic_string(const basic_string_view<Char>& sv)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR basic_string(const basic_string_view<Char>& sv)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
//normal copy and move ctors
|
//normal copy and move ctors
|
||||||
@ -419,6 +409,8 @@ namespace rexy{
|
|||||||
REXY_CPP20_CONSTEXPR bool reserve(size_type newsize)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR bool reserve(size_type newsize)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
REXY_CPP20_CONSTEXPR void shrink_to_fit(void)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR void shrink_to_fit(void)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
|
|
||||||
|
REXY_CPP20_CONSTEXPR void resize(size_type newsize, value_type v = value_type())noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
|
|
||||||
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, 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, 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)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
@ -428,20 +420,22 @@ namespace rexy{
|
|||||||
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, 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>);
|
REXY_CPP20_CONSTEXPR basic_string& insert(const_iterator pos, size_type count, value_type v)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR basic_string& insert(const_iterator pos, InputIt start, InputIt last)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR auto insert(const_iterator pos, InputIt start, InputIt last)noexcept(is_nothrow_allocator_v<Alloc>) ->
|
||||||
|
std::enable_if_t<is_legacy_input_iterator_v<InputIt>,basic_string&>;
|
||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR basic_string& insert(size_type pos, InputIt start, InputIt last)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR auto insert(size_type pos, InputIt start, InputIt last)noexcept(is_nothrow_allocator_v<Alloc>) ->
|
||||||
|
std::enable_if_t<is_legacy_input_iterator_v<InputIt>,basic_string&>;
|
||||||
REXY_CPP20_CONSTEXPR basic_string& insert(const_iterator pos, std::initializer_list<value_type> list)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>
|
template<class StringView>
|
||||||
REXY_CPP20_CONSTEXPR auto insert(size_type pos, const StringView& sv)noexcept(is_nothrow_allocator_v<Alloc>) ->
|
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>>;
|
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>,basic_string&>;
|
||||||
template<class StringView>
|
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>) ->
|
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>>;
|
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>,basic_string&>;
|
||||||
|
|
||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR basic_string& append(InputIt start, InputIt fin)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR auto append(InputIt start, InputIt fin)noexcept(is_nothrow_allocator_v<Alloc>) ->
|
||||||
|
std::enable_if_t<is_legacy_input_iterator_v<InputIt>,basic_string&>;
|
||||||
|
|
||||||
REXY_CPP20_CONSTEXPR basic_string& append(const_pointer data, size_type len)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR basic_string& append(const_pointer data, size_type len)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
REXY_CPP20_CONSTEXPR basic_string& append(const_pointer data)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR basic_string& append(const_pointer data)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
REXY_CPP20_CONSTEXPR basic_string& append(const basic_string& other)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR basic_string& append(const basic_string& other)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
@ -449,6 +443,30 @@ namespace rexy{
|
|||||||
REXY_CPP20_CONSTEXPR void push_back(value_type data)noexcept(is_nothrow_allocator_v<Alloc>);
|
REXY_CPP20_CONSTEXPR void push_back(value_type data)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
constexpr void pop_back(void)noexcept;
|
constexpr void pop_back(void)noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
constexpr basic_string& replace(size_type pos, size_type count, const basic_string& str);
|
||||||
|
constexpr basic_string& replace(const_iterator pos, const_iterator last, const basic_string& str);
|
||||||
|
constexpr basic_string& replace(size_type pos, size_type count, const basic_string& str, size_type pos2, size_type count2 = npos);
|
||||||
|
template<class InputIt>
|
||||||
|
constexpr auto replace(const_iterator first, const_iterator last, InputIt first2, InputIt last2) ->
|
||||||
|
std::enable_if_t<is_legacy_input_iterator_v<InputIt>,basic_string&>;
|
||||||
|
constexpr basic_string& replace(size_type pos, size_type count, const_pointer cstr, size_type count2);
|
||||||
|
constexpr basic_string& replace(const_iterator first, const_iterator last, const_pointer cstr, size_type count);
|
||||||
|
constexpr basic_string& replace(size_type pos, size_type count, const_pointer cstr);
|
||||||
|
constexpr basic_string& replace(const_iterator first, const_iterator last, const_pointer cstr);
|
||||||
|
constexpr basic_string& replace(size_type pos, size_type count, size_type count2, value_type v);
|
||||||
|
constexpr basic_string& replace(const_iterator first, const_iterator last, size_type count2, value_type v);
|
||||||
|
constexpr basic_string& replace(const_iterator first, const_iterator last, std::initializer_list<value_type> list);
|
||||||
|
template<class StringView>
|
||||||
|
constexpr auto replace(size_type pos, size_type count, const StringView& sv) ->
|
||||||
|
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>,basic_string&>;
|
||||||
|
template<class StringView>
|
||||||
|
constexpr auto replace(const_iterator first, const_iterator last, const StringView& sv) ->
|
||||||
|
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>,basic_string&>;
|
||||||
|
template<class StringView>
|
||||||
|
constexpr auto replace(size_type pos, size_type count, const StringView& sv, size_type pos2, size_type count2 = npos) ->
|
||||||
|
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>,basic_string&>;
|
||||||
|
|
||||||
constexpr basic_string& erase(size_type index = 0, size_type count = npos)noexcept;
|
constexpr basic_string& erase(size_type index = 0, size_type count = npos)noexcept;
|
||||||
constexpr iterator erase(const_iterator pos)noexcept;
|
constexpr iterator erase(const_iterator pos)noexcept;
|
||||||
constexpr iterator erase(const_iterator first, const_iterator last)noexcept;
|
constexpr iterator erase(const_iterator first, const_iterator last)noexcept;
|
||||||
@ -460,8 +478,6 @@ namespace rexy{
|
|||||||
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;
|
||||||
|
|
||||||
|
|
||||||
[[deprecated]] REXY_CPP20_CONSTEXPR bool resize(size_type newsize)noexcept(is_nothrow_allocator_v<Alloc>);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Like an expression template but not really
|
//Like an expression template but not really
|
||||||
|
|||||||
@ -32,6 +32,23 @@
|
|||||||
|
|
||||||
namespace rexy{
|
namespace rexy{
|
||||||
|
|
||||||
|
namespace detail{
|
||||||
|
template<class T>
|
||||||
|
struct value_iterator_adapter{
|
||||||
|
T val;
|
||||||
|
|
||||||
|
constexpr value_iterator_adapter& operator++(void)noexcept{return *this;}
|
||||||
|
constexpr value_iterator_adapter operator++(int)noexcept{return *this;}
|
||||||
|
constexpr T operator*(void)const noexcept{return val;}
|
||||||
|
|
||||||
|
constexpr bool operator==(const value_iterator_adapter& other)const{return val == other.val;}
|
||||||
|
constexpr bool operator!=(const value_iterator_adapter& other)const{return val == other.val;}
|
||||||
|
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
value_iterator_adapter(T) -> value_iterator_adapter<T>;
|
||||||
|
}
|
||||||
|
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr auto string_base<Char>::search(basic_string_view<value_type> sv)const -> const_iterator{
|
constexpr auto string_base<Char>::search(basic_string_view<value_type> sv)const -> const_iterator{
|
||||||
if(sv.length() > length()){
|
if(sv.length() > length()){
|
||||||
@ -138,6 +155,8 @@ namespace rexy{
|
|||||||
set_length(0);
|
set_length(0);
|
||||||
get_pointer()[0] = 0;
|
get_pointer()[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr auto string_base<Char>::create_view(void)const noexcept -> basic_string_view<value_type>{
|
constexpr auto string_base<Char>::create_view(void)const noexcept -> basic_string_view<value_type>{
|
||||||
return basic_string_view<value_type>(data(), length());
|
return basic_string_view<value_type>(data(), length());
|
||||||
@ -229,7 +248,7 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
template<class InputIt>
|
template<class InputIt, class Enable>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(InputIt start, InputIt fin)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(InputIt start, InputIt fin)
|
||||||
noexcept(is_nothrow_allocator_v<Alloc>):
|
noexcept(is_nothrow_allocator_v<Alloc>):
|
||||||
basic_string(nullptr, size_type{fin - start})
|
basic_string(nullptr, size_type{fin - start})
|
||||||
@ -247,7 +266,7 @@ namespace rexy{
|
|||||||
noexcept(is_nothrow_allocator_v<Alloc>):
|
noexcept(is_nothrow_allocator_v<Alloc>):
|
||||||
detail::hasallocator<Alloc>(b)
|
detail::hasallocator<Alloc>(b)
|
||||||
{
|
{
|
||||||
_copy_construct_string(b.get(), b.length(), b.length());
|
_copy_construct_string(b.data(), b.length(), b.length());
|
||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
constexpr basic_string<Char,Alloc>::basic_string(basic_string&& s)noexcept:
|
constexpr basic_string<Char,Alloc>::basic_string(basic_string&& s)noexcept:
|
||||||
@ -257,7 +276,7 @@ namespace rexy{
|
|||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const string_base<Char>& b)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const string_base<Char>& b)
|
||||||
noexcept(is_nothrow_allocator_v<Alloc>)
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
{
|
{
|
||||||
_copy_construct_string(b.get(), b.length(), b.length());
|
_copy_construct_string(b.data(), b.length(), b.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
//dtor
|
//dtor
|
||||||
@ -337,7 +356,7 @@ namespace rexy{
|
|||||||
return false;
|
return false;
|
||||||
if(!this->islong() && newsize < string_base<Char>::short_string_size())
|
if(!this->islong() && newsize < string_base<Char>::short_string_size())
|
||||||
return false;
|
return false;
|
||||||
return (*this = basic_string(this->get_pointer(), newsize));
|
return (*this = basic_string(this->get_pointer(), newsize)).valid();
|
||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::shrink_to_fit(void)noexcept(is_nothrow_allocator_v<Alloc>){
|
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::shrink_to_fit(void)noexcept(is_nothrow_allocator_v<Alloc>){
|
||||||
@ -346,23 +365,31 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
*this = basic_string(this->get_pointer(), this->length(), this->length());
|
*this = basic_string(this->get_pointer(), this->length(), this->length());
|
||||||
}
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::resize(size_type newsize, value_type v)noexcept(is_nothrow_allocator_v<Alloc>){
|
||||||
|
const auto len = this->length();
|
||||||
|
const auto copy_count = std::min(newsize, len);
|
||||||
|
const auto insert_count = newsize > len ? newsize - len : 0;
|
||||||
|
|
||||||
|
basic_string newstr(newsize);
|
||||||
|
auto* ptr = newstr.data();
|
||||||
|
|
||||||
|
rexy::memcpy(ptr, this->data(), copy_count * sizeof(value_type));
|
||||||
|
ptr += copy_count;
|
||||||
|
|
||||||
|
for(size_type i = 0;i < insert_count;++i){
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
*ptr = 0;
|
||||||
|
newstr.set_length(newsize);
|
||||||
|
|
||||||
|
*this = std::move(newstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
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&{
|
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{
|
return _insert_impl(pos, detail::value_iterator_adapter{v}, insert_count);
|
||||||
value_type val;
|
|
||||||
|
|
||||||
constexpr insert_adapter& operator++(void)noexcept{return *this;}
|
|
||||||
constexpr insert_adapter operator++(int)noexcept{return *this;}
|
|
||||||
constexpr value_type operator*(void)const noexcept{return val;}
|
|
||||||
|
|
||||||
constexpr bool operator==(const insert_adapter& other)const{return val == other.val;}
|
|
||||||
constexpr bool operator!=(const insert_adapter& other)const{return val == other.val;}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
return _insert_impl(pos, insert_adapter{v}, insert_count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
@ -395,7 +422,9 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(const_iterator pos, InputIt start, InputIt last)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
|
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(const_iterator pos, InputIt start, InputIt last)noexcept(is_nothrow_allocator_v<Alloc>) ->
|
||||||
|
std::enable_if_t<is_legacy_input_iterator_v<InputIt>,basic_string&>
|
||||||
|
{
|
||||||
return insert(pos - this->begin(), std::move(start), std::move(last));
|
return insert(pos - this->begin(), std::move(start), std::move(last));
|
||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
@ -405,21 +434,23 @@ namespace rexy{
|
|||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
template<class StringView>
|
template<class StringView>
|
||||||
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, const StringView& sv)noexcept(is_nothrow_allocator_v<Alloc>) ->
|
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>>
|
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>,basic_string&>
|
||||||
{
|
{
|
||||||
return insert(pos, sv.begin(), sv.end());
|
return insert(pos, sv.begin(), sv.end());
|
||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
template<class StringView>
|
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>) ->
|
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>>
|
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>,basic_string&>
|
||||||
{
|
{
|
||||||
return insert(pos, sv.begin() + index_str, sv.begin() + index_str + count);
|
return insert(pos, sv.begin() + index_str, sv.begin() + index_str + count);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, InputIt start, InputIt last)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
|
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::insert(size_type pos, InputIt start, InputIt last)noexcept(is_nothrow_allocator_v<Alloc>) ->
|
||||||
|
std::enable_if_t<is_legacy_input_iterator_v<InputIt>,basic_string&>
|
||||||
|
{
|
||||||
size_type insert_count = 0;
|
size_type insert_count = 0;
|
||||||
for(auto it = start;it != last;++it, ++insert_count){}
|
for(auto it = start;it != last;++it, ++insert_count){}
|
||||||
return _insert_impl(pos, start, insert_count);
|
return _insert_impl(pos, start, insert_count);
|
||||||
@ -441,7 +472,9 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::append(InputIt start, InputIt fin)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
|
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::append(InputIt start, InputIt fin)noexcept(is_nothrow_allocator_v<Alloc>) ->
|
||||||
|
std::enable_if_t<is_legacy_input_iterator_v<InputIt>,basic_string&>
|
||||||
|
{
|
||||||
return insert(this->length(), start, fin);
|
return insert(this->length(), start, fin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,6 +489,85 @@ namespace rexy{
|
|||||||
erase(this->end() - 1);
|
erase(this->end() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(size_type pos, size_type count, const basic_string& str) -> basic_string&{
|
||||||
|
return replace(pos, count, str.create_view());
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(const_iterator first, const_iterator last, const basic_string& str) -> basic_string&{
|
||||||
|
return replace(first, last, str.create_view());
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(size_type pos, size_type count, const basic_string& str, size_type pos2, size_type count2) -> basic_string&{
|
||||||
|
return replace(pos, count, str.create_view(), pos2, count2);
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
template<class InputIt>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(const_iterator first, const_iterator last, InputIt first2, InputIt last2) ->
|
||||||
|
std::enable_if_t<is_legacy_input_iterator_v<InputIt>,basic_string&>
|
||||||
|
{
|
||||||
|
const size_type len = last - first;
|
||||||
|
size_type count = 0;
|
||||||
|
for(auto it = first2;count < len && it != last2;++count,++it);
|
||||||
|
return _replace_impl(size_type{first - this->begin()}, len, first2, count);
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(size_type pos, size_type count, const_pointer cstr, size_type count2) -> basic_string&{
|
||||||
|
return _replace_impl(pos, count, cstr, count2);
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(const_iterator first, const_iterator last, const_pointer cstr, size_type count) -> basic_string&{
|
||||||
|
return _replace_impl(size_type{first - this->begin()}, size_type{last - first}, cstr, count);
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(size_type pos, size_type count, const_pointer cstr) -> basic_string&{
|
||||||
|
return _replace_impl(pos, count, cstr, rexy::strlen(cstr));
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(const_iterator first, const_iterator last, const_pointer cstr) -> basic_string&{
|
||||||
|
return _replace_impl(size_type{first - this->begin()}, size_type{last - first}, cstr, rexy::strlen(cstr));
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(size_type pos, size_type count, size_type count2, value_type v) -> basic_string&{
|
||||||
|
return _replace_impl(pos, count, detail::value_iterator_adapter{v}, count2);
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(const_iterator first, const_iterator last, size_type count2, value_type v) -> basic_string&{
|
||||||
|
return _replace_impl(size_type{first - this->begin()}, size_type{last - first}, detail::value_iterator_adapter{v}, count2);
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(const_iterator first, const_iterator last, std::initializer_list<value_type> list) -> basic_string&{
|
||||||
|
return _replace_impl(size_type{first - this->begin()}, size_type{last - first}, list.begin(), list.size());
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
template<class StringView>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(size_type pos, size_type count, const StringView& sv) ->
|
||||||
|
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>,basic_string&>
|
||||||
|
{
|
||||||
|
return _replace_impl(pos, count, sv.begin(), sv.length());
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
template<class StringView>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(const_iterator first, const_iterator last, const StringView& sv) ->
|
||||||
|
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>,basic_string&>
|
||||||
|
{
|
||||||
|
return _replace_impl(size_type{first - this->begin()}, size_type{last - first}, sv.begin(), sv.length());
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
template<class StringView>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::replace(size_type pos, size_type count, const StringView& sv, size_type pos2, size_type count2) ->
|
||||||
|
std::enable_if_t<std::is_convertible_v<const StringView&, basic_string_view<value_type>> && !std::is_convertible_v<const StringView&,const_pointer>,basic_string&>
|
||||||
|
{
|
||||||
|
if(pos2 > sv.length()){
|
||||||
|
pos2 = sv.length();
|
||||||
|
}
|
||||||
|
const auto maxlen2 = sv.length() - pos2;
|
||||||
|
if(count2 > maxlen2){
|
||||||
|
count2 = maxlen2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _replace_impl(pos, count, sv.begin() + pos2, maxlen2);
|
||||||
|
}
|
||||||
|
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
constexpr auto basic_string<Char,Alloc>::erase(size_type index, size_type count)noexcept -> basic_string&{
|
constexpr auto basic_string<Char,Alloc>::erase(size_type index, size_type count)noexcept -> basic_string&{
|
||||||
@ -496,7 +608,7 @@ namespace rexy{
|
|||||||
return {};
|
return {};
|
||||||
const size_type newlen = end - start;
|
const size_type newlen = end - start;
|
||||||
basic_string<value_type,Alloc> tmp(newlen);
|
basic_string<value_type,Alloc> tmp(newlen);
|
||||||
tmp.append(this->get() + start, newlen);
|
tmp.append(this->data() + start, newlen);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
@ -545,24 +657,66 @@ namespace rexy{
|
|||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::_insert_impl(size_type pos, InputIt start, size_type insert_count)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
|
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::_insert_impl(size_type pos, InputIt start, size_type insert_count)noexcept(is_nothrow_allocator_v<Alloc>) -> basic_string&{
|
||||||
const size_type len = this->length();
|
const size_type len = this->length();
|
||||||
|
const size_type cap = this->capacity();
|
||||||
const size_type after_pos_count = len > pos ? len - pos : 0;
|
const size_type after_pos_count = len > pos ? len - pos : 0;
|
||||||
|
|
||||||
basic_string newstr(rexy::max(pos + insert_count, len + insert_count));
|
if(insert_count + len <= cap){
|
||||||
auto* ptr = newstr.get_pointer();
|
|
||||||
|
|
||||||
rexy::memcpy(ptr, this->get_pointer(), sizeof(value_type) * pos);
|
auto* dest_ptr = this->data() + pos + insert_count;
|
||||||
ptr += pos;
|
const auto* src_ptr = this->data() + pos;
|
||||||
|
for(size_type i = 0;i < after_pos_count;++i){
|
||||||
|
*dest_ptr++ = *src_ptr++;
|
||||||
|
}
|
||||||
|
dest_ptr = this->data() + pos;
|
||||||
|
for(size_type i = 0;i < insert_count;++i){
|
||||||
|
*dest_ptr++ = *start++;
|
||||||
|
}
|
||||||
|
this->data()[len + insert_count] = 0; //null terminator
|
||||||
|
this->set_length(len + insert_count);
|
||||||
|
|
||||||
for(size_type i = 0;i < insert_count;++i){
|
return *this;
|
||||||
*ptr++ = *start++;
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
basic_string newstr(rexy::max(pos + insert_count, len + insert_count));
|
||||||
|
auto* ptr = newstr.get_pointer();
|
||||||
|
|
||||||
|
rexy::memcpy(ptr, this->get_pointer(), sizeof(value_type) * pos);
|
||||||
|
ptr += pos;
|
||||||
|
|
||||||
|
for(size_type i = 0;i < insert_count;++i){
|
||||||
|
*ptr++ = *start++;
|
||||||
|
}
|
||||||
|
|
||||||
|
rexy::memcpy(ptr, this->get_pointer() + pos, sizeof(value_type) * after_pos_count);
|
||||||
|
ptr += after_pos_count;
|
||||||
|
*ptr = 0; //null terminator
|
||||||
|
newstr.set_length(len + insert_count);
|
||||||
|
|
||||||
|
return (*this = std::move(newstr));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
template<class InputIt>
|
||||||
|
constexpr auto basic_string<Char,Alloc>::_replace_impl(size_type pos, size_type count, InputIt src, size_type count2) -> basic_string&{
|
||||||
|
const auto len = this->length();
|
||||||
|
if(pos > len){
|
||||||
|
pos = len;
|
||||||
|
}
|
||||||
|
const auto maxlen = len - pos;
|
||||||
|
if(count > maxlen){
|
||||||
|
count = maxlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
rexy::memcpy(ptr, this->get_pointer() + pos, sizeof(value_type) * after_pos_count);
|
const auto real_count = std::min(count, count2);
|
||||||
ptr += after_pos_count;
|
|
||||||
*ptr = 0; //null terminator
|
|
||||||
newstr.set_length(len + insert_count);
|
|
||||||
|
|
||||||
return (*this = std::move(newstr));
|
auto* dest_ptr = this->get_pointer() + pos;
|
||||||
|
for(size_type i = 0;i < real_count;++i){
|
||||||
|
*dest_ptr++ = *src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Left, class Right>
|
template<class Left, class Right>
|
||||||
@ -582,31 +736,6 @@ namespace rexy{
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Char>
|
|
||||||
[[deprecated]] constexpr auto string_base<Char>::search(const string_base& s)const -> const_iterator{
|
|
||||||
return two_way_search(cbegin(), cend(), s.begin(), s.end());
|
|
||||||
}
|
|
||||||
template<class Char>
|
|
||||||
[[deprecated]] constexpr auto string_base<Char>::search(const string_base& s) -> iterator{
|
|
||||||
return two_way_search(begin(), end(), s.begin(), s.end());
|
|
||||||
}
|
|
||||||
template<class Char>
|
|
||||||
template<class Searcher>
|
|
||||||
[[deprecated]] constexpr auto string_base<Char>::search(const string_base& s, const Searcher& searcher)const -> const_iterator{
|
|
||||||
return searcher(cbegin(), cend(), s.begin(), s.end());
|
|
||||||
}
|
|
||||||
template<class Char>
|
|
||||||
template<class Searcher>
|
|
||||||
[[deprecated]] constexpr auto string_base<Char>::search(const string_base& s, const Searcher& searcher) -> iterator{
|
|
||||||
return searcher(begin(), end(), s.begin(), s.end());
|
|
||||||
}
|
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
|
||||||
[[deprecated]] REXY_CPP20_CONSTEXPR bool basic_string<Char,Alloc>::resize(size_type newsize)noexcept(is_nothrow_allocator_v<Alloc>){
|
|
||||||
return reserve(newsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} //namespace rexy
|
} //namespace rexy
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -127,9 +127,6 @@ namespace rexy{
|
|||||||
constexpr size_type find_last_of(const_pointer c, size_type pos = 0)const;
|
constexpr size_type find_last_of(const_pointer c, size_type pos = 0)const;
|
||||||
constexpr size_type find_last_of(const_pointer c, size_type pos, size_type size)const;
|
constexpr size_type find_last_of(const_pointer c, size_type pos, size_type size)const;
|
||||||
|
|
||||||
|
|
||||||
[[deprecated]] constexpr const_pointer get(void)const noexcept{return m_data;}
|
|
||||||
[[deprecated]] constexpr operator const_pointer(void)const noexcept{return m_data;}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#define REXY_TRAITS_HPP
|
#define REXY_TRAITS_HPP
|
||||||
|
|
||||||
#include <type_traits> //is_same, decay, integral_constant, declval
|
#include <type_traits> //is_same, decay, integral_constant, declval
|
||||||
|
#include <iterator> //iterator_traits
|
||||||
|
|
||||||
#include "rexy.hpp"
|
#include "rexy.hpp"
|
||||||
|
|
||||||
@ -53,6 +54,85 @@ namespace rexy{
|
|||||||
static constexpr bool value = std::is_same<std::true_type,decltype(test(static_cast<std::decay_t<T>*>(nullptr)))>::value;
|
static constexpr bool value = std::is_same<std::true_type,decltype(test(static_cast<std::decay_t<T>*>(nullptr)))>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class T, class = void>
|
||||||
|
struct is_dereferencable : public std::false_type{};
|
||||||
|
template<class T>
|
||||||
|
struct is_dereferencable<T,std::void_t<decltype(*(std::declval<T>()))>> : public std::true_type{};
|
||||||
|
template<class T>
|
||||||
|
static constexpr bool is_dereferencable_v = is_dereferencable<T>::value;
|
||||||
|
|
||||||
|
template<class T, class = void>
|
||||||
|
struct is_pointer_dereferencable : public std::false_type{};
|
||||||
|
template<class T>
|
||||||
|
struct is_pointer_dereferencable<T,std::void_t<decltype(std::declval<T>().operator->())>> : public std::true_type{};
|
||||||
|
template<class T>
|
||||||
|
struct is_pointer_dereferencable<T*,std::void_t<T*>> : public std::true_type{};
|
||||||
|
template<class T>
|
||||||
|
static constexpr bool is_pointer_dereferencable_v = is_pointer_dereferencable<T>::value;
|
||||||
|
|
||||||
|
template<class T, class = void>
|
||||||
|
struct is_prefix_incrementable : public std::false_type{};
|
||||||
|
template<class T>
|
||||||
|
struct is_prefix_incrementable<T,std::void_t<decltype(++(std::declval<std::add_lvalue_reference_t<std::remove_cvref_t<T>>>()))>> : public std::true_type{};
|
||||||
|
template<class T>
|
||||||
|
static constexpr bool is_prefix_incrementable_v = is_prefix_incrementable<T>::value;
|
||||||
|
|
||||||
|
template<class T, class = void>
|
||||||
|
struct is_postfix_incrementable : public std::false_type{};
|
||||||
|
template<class T>
|
||||||
|
struct is_postfix_incrementable<T,std::void_t<decltype((std::declval<std::add_lvalue_reference_t<std::remove_cvref_t<T>>>())++)>> : public std::true_type{};
|
||||||
|
template<class T>
|
||||||
|
static constexpr bool is_postfix_incrementable_v = is_postfix_incrementable<T>::value;
|
||||||
|
|
||||||
|
template<class T, class = void>
|
||||||
|
struct is_equality_comparable : public std::false_type{};
|
||||||
|
template<class T>
|
||||||
|
struct is_equality_comparable<T,std::void_t<decltype(std::declval<T>() == std::declval<T>())>> : public std::true_type{};
|
||||||
|
template<class T>
|
||||||
|
static constexpr bool is_equality_comparable_v = is_equality_comparable<T>::value;
|
||||||
|
|
||||||
|
template<class T, class = void>
|
||||||
|
struct is_inequality_comparable : public std::false_type{};
|
||||||
|
template<class T>
|
||||||
|
struct is_inequality_comparable<T,std::void_t<decltype(std::declval<T>() != std::declval<T>())>> : public std::true_type{};
|
||||||
|
template<class T>
|
||||||
|
static constexpr bool is_inequality_comparable_v = is_inequality_comparable<T>::value;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct is_legacy_iterator{
|
||||||
|
static constexpr bool value = is_prefix_incrementable_v<T> && is_dereferencable_v<T>;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
static constexpr bool is_legacy_iterator_v = is_legacy_iterator<T>::value;
|
||||||
|
|
||||||
|
template<class T, bool = is_legacy_iterator_v<T> &&
|
||||||
|
is_inequality_comparable_v<T> &&
|
||||||
|
is_pointer_dereferencable_v<T> &&
|
||||||
|
is_postfix_incrementable_v<T>>
|
||||||
|
struct is_legacy_input_iterator : public std::false_type{};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct is_legacy_input_iterator<T,true>{
|
||||||
|
static constexpr bool value = std::is_convertible_v<decltype(std::declval<T>() == std::declval<T>()),bool> &&
|
||||||
|
std::is_same_v<decltype(*(std::declval<T>())),typename std::iterator_traits<T>::reference> &&
|
||||||
|
std::is_same_v<decltype(++std::declval<std::add_lvalue_reference_t<std::remove_cvref_t<T>>>()),std::add_lvalue_reference_t<T>> &&
|
||||||
|
std::is_convertible_v<decltype(*std::declval<std::add_lvalue_reference_t<std::remove_cvref_t<T>>>()++), typename std::iterator_traits<T>::value_type>;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
static constexpr bool is_legacy_input_iterator_v = is_legacy_input_iterator<T>::value;
|
||||||
|
|
||||||
|
template<class T, class Value, bool = is_legacy_iterator_v<T> &&
|
||||||
|
is_postfix_incrementable_v<T>>
|
||||||
|
struct is_legacy_output_iterator : public std::false_type{};
|
||||||
|
|
||||||
|
template<class T, class Value>
|
||||||
|
struct is_legacy_output_iterator<T,Value,true>{
|
||||||
|
static constexpr bool value =
|
||||||
|
std::is_same_v<decltype(++std::declval<std::add_lvalue_reference_t<std::remove_cvref_t<T>>>()),std::add_lvalue_reference_t<T>> &&
|
||||||
|
std::is_convertible_v<decltype(std::declval<std::add_lvalue_reference_t<std::remove_cvref_t<T>>>()++), std::add_lvalue_reference_t<std::add_const_t<T>>>;
|
||||||
|
};
|
||||||
|
template<class T, class Value>
|
||||||
|
static constexpr bool is_legacy_output_iterator_v = is_legacy_output_iterator<T,Value>::value;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -92,14 +92,14 @@ namespace rexy{
|
|||||||
return val > 0 ? val : -val;
|
return val > 0 ? val : -val;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef REXY_if_constexpr
|
#ifdef REXY_if_consteval
|
||||||
template<class T>
|
template<class T>
|
||||||
constexpr size_t strlen(const T* c)noexcept{
|
constexpr size_t strlen(const T* c)noexcept{
|
||||||
return std::char_traits<T>::length(c);
|
return std::char_traits<T>::length(c);
|
||||||
}
|
}
|
||||||
template<class T>
|
template<class T>
|
||||||
constexpr int strcmp(const T* l, const T* r)noexcept{
|
constexpr int strcmp(const T* l, const T* r)noexcept{
|
||||||
REXY_if_constexpr{
|
REXY_if_consteval{
|
||||||
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
||||||
return std::strcmp(l, r);
|
return std::strcmp(l, r);
|
||||||
}else if constexpr(std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
}else if constexpr(std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
||||||
@ -111,7 +111,7 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
template<class T>
|
template<class T>
|
||||||
constexpr int strncmp(const T* l, const T* r, std::size_t max)noexcept{
|
constexpr int strncmp(const T* l, const T* r, std::size_t max)noexcept{
|
||||||
REXY_if_constexpr{
|
REXY_if_consteval{
|
||||||
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
||||||
return std::strncmp(l, r, max);
|
return std::strncmp(l, r, max);
|
||||||
}else if constexpr (std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
}else if constexpr (std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
||||||
@ -123,7 +123,7 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
template<class T, class Compare>
|
template<class T, class Compare>
|
||||||
constexpr int strncmp(const T* l, const T* r, std::size_t max, Compare cmp)noexcept{
|
constexpr int strncmp(const T* l, const T* r, std::size_t max, Compare cmp)noexcept{
|
||||||
REXY_if_constexpr{
|
REXY_if_consteval{
|
||||||
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
||||||
return std::strncmp(l, r, max);
|
return std::strncmp(l, r, max);
|
||||||
}else if constexpr (std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
}else if constexpr (std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
||||||
@ -139,7 +139,7 @@ namespace rexy{
|
|||||||
return *l - *r;
|
return *l - *r;
|
||||||
}
|
}
|
||||||
constexpr void memcpy(void* l, const void* r, size_t n){
|
constexpr void memcpy(void* l, const void* r, size_t n){
|
||||||
REXY_if_constexpr{
|
REXY_if_consteval{
|
||||||
std::memcpy(l, r, n);
|
std::memcpy(l, r, n);
|
||||||
}else{
|
}else{
|
||||||
char* ld = static_cast<char*>(l);
|
char* ld = static_cast<char*>(l);
|
||||||
@ -150,7 +150,7 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else // REXY_if_constexpr
|
#else // REXY_if_consteval
|
||||||
template<class T>
|
template<class T>
|
||||||
constexpr size_t strlen(const T* c)noexcept{
|
constexpr size_t strlen(const T* c)noexcept{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
@ -180,7 +180,7 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // REXY_if_constexpr
|
#endif // REXY_if_consteval
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,8 @@
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using namespace rexy::str_literals;
|
||||||
|
|
||||||
using test_str = rexy::basic_string<char,rexy::allocator<char>>;
|
using test_str = rexy::basic_string<char,rexy::allocator<char>>;
|
||||||
|
|
||||||
void check_empty_construction(){
|
void check_empty_construction(){
|
||||||
@ -295,6 +297,42 @@ void check_string_erase(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check_string_replace(){
|
||||||
|
rexy::string test = "test string";
|
||||||
|
test.replace(0, 4, "yolo");
|
||||||
|
if(test != "yolo string"){
|
||||||
|
error("string replace operation 1 did not result in a correct result\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
test = "this is a long string version"_sv;
|
||||||
|
auto it = test.search("long"_sv);
|
||||||
|
if(it == test.end()){
|
||||||
|
error("string search failed in replace test\n");
|
||||||
|
}
|
||||||
|
test.replace(it, it+4, "thic");
|
||||||
|
if(test != "this is a thic string version"){
|
||||||
|
error("string replace operation 2 did not result in a correct result\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
test.replace(test.end() - 7, test.end(), "vrisiod");
|
||||||
|
if(test != "this is a thic string vrisiod"){
|
||||||
|
error("string replace operation 3 did not result in a correct result\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
test.replace(test.begin(), test.end(), "change");
|
||||||
|
if(test != "changes a thic string vrisiod"){
|
||||||
|
error("string replace operation 4 did not result in a correct result\n");
|
||||||
|
}
|
||||||
|
test = "short"_sv;
|
||||||
|
|
||||||
|
test.replace(test.begin(), test.end(), "a longer string");
|
||||||
|
if(test != "a lon"){
|
||||||
|
error("string replace operation 5 did not result in a correct result\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
check_empty_construction();
|
check_empty_construction();
|
||||||
check_short_construction();
|
check_short_construction();
|
||||||
@ -307,4 +345,5 @@ int main(){
|
|||||||
check_string_search();
|
check_string_search();
|
||||||
check_string_insert();
|
check_string_insert();
|
||||||
check_string_erase();
|
check_string_erase();
|
||||||
|
check_string_replace();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user