Merge remote-tracking branch 'refs/remotes/origin/master'
This commit is contained in:
commit
35b64db13c
@ -38,6 +38,8 @@
|
|||||||
#include "rexy.hpp"
|
#include "rexy.hpp"
|
||||||
#include "compat/standard.hpp"
|
#include "compat/standard.hpp"
|
||||||
|
|
||||||
|
#include <type_traits> //declval
|
||||||
|
|
||||||
namespace rexy{
|
namespace rexy{
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@ -170,6 +172,13 @@ namespace rexy{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<REXY_ALLOCATOR_CONCEPT T>
|
||||||
|
struct is_nothrow_allocator{
|
||||||
|
static constexpr bool value = noexcept(std::declval<T>().allocate(0)) && noexcept(std::declval<T>().deallocate(nullptr, 0));
|
||||||
|
};
|
||||||
|
template<REXY_ALLOCATOR_CONCEPT T>
|
||||||
|
static constexpr bool is_nothrow_allocator_v = is_nothrow_allocator<T>::value;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -31,17 +31,17 @@ namespace rexy::detail{
|
|||||||
{
|
{
|
||||||
Alloc m_alloc;
|
Alloc m_alloc;
|
||||||
|
|
||||||
REXY_CPP20_CONSTEXPR auto allocate(typename Alloc::size_type bytes)noexcept(noexcept(m_alloc.allocate(0))){
|
REXY_CPP20_CONSTEXPR auto allocate(typename Alloc::size_type bytes)noexcept(is_nothrow_allocator_v<Alloc>){
|
||||||
return m_alloc.allocate(bytes);
|
return m_alloc.allocate(bytes);
|
||||||
}
|
}
|
||||||
REXY_CPP20_CONSTEXPR void deallocate(typename Alloc::pointer p, typename Alloc::size_type bytes)noexcept(noexcept(m_alloc.deallocate(nullptr,0))){
|
REXY_CPP20_CONSTEXPR void deallocate(typename Alloc::pointer p, typename Alloc::size_type bytes)noexcept(is_nothrow_allocator_v<Alloc>){
|
||||||
m_alloc.deallocate(p, bytes);
|
m_alloc.deallocate(p, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
Alloc& allocator(void){
|
constexpr Alloc& allocator(void){
|
||||||
return m_alloc;
|
return m_alloc;
|
||||||
}
|
}
|
||||||
const Alloc& allocator(void)const{
|
constexpr const Alloc& allocator(void)const{
|
||||||
return m_alloc;
|
return m_alloc;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -52,21 +52,21 @@ namespace rexy::detail{
|
|||||||
[[no_unique_address]]
|
[[no_unique_address]]
|
||||||
Alloc m_alloc;
|
Alloc m_alloc;
|
||||||
|
|
||||||
REXY_CPP20_CONSTEXPR auto allocate(typename Alloc::size_type bytes)noexcept(noexcept(m_alloc.allocate(0))){
|
REXY_CPP20_CONSTEXPR auto allocate(typename Alloc::size_type bytes)noexcept(is_nothrow_allocator_v<Alloc>){
|
||||||
return m_alloc.allocate(bytes);
|
return m_alloc.allocate(bytes);
|
||||||
}
|
}
|
||||||
REXY_CPP20_CONSTEXPR void deallocate(typename Alloc::pointer p, typename Alloc::size_type bytes)noexcept(noexcept(m_alloc.deallocate(nullptr,0))){
|
REXY_CPP20_CONSTEXPR void deallocate(typename Alloc::pointer p, typename Alloc::size_type bytes)noexcept(is_nothrow_allocator_v<Alloc>){
|
||||||
m_alloc.deallocate(p, bytes);
|
m_alloc.deallocate(p, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
Alloc& allocator(void){
|
constexpr Alloc& allocator(void){
|
||||||
return m_alloc;
|
return m_alloc;
|
||||||
}
|
}
|
||||||
const Alloc& allocator(void)const{
|
constexpr const Alloc& allocator(void)const{
|
||||||
return m_alloc;
|
return m_alloc;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif //no_unique_address
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -27,6 +27,7 @@ namespace rexy{
|
|||||||
|
|
||||||
//new allocated string
|
//new allocated string
|
||||||
using string = basic_string<char,allocator<char>>;
|
using string = basic_string<char,allocator<char>>;
|
||||||
|
using wstring = basic_string<wchar_t,allocator<wchar_t>>;
|
||||||
|
|
||||||
#ifndef LIBREXY_HEADER_ONLY
|
#ifndef LIBREXY_HEADER_ONLY
|
||||||
extern template class basic_string<char,allocator<char>>;
|
extern template class basic_string<char,allocator<char>>;
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
#include "expression.hpp"
|
#include "expression.hpp"
|
||||||
#include "detail/string_appender.hpp"
|
#include "detail/string_appender.hpp"
|
||||||
#include "detail/hasallocator.hpp"
|
#include "detail/hasallocator.hpp"
|
||||||
|
#include "allocator.hpp"
|
||||||
#include "rexy.hpp"
|
#include "rexy.hpp"
|
||||||
|
|
||||||
#include "compat/standard.hpp"
|
#include "compat/standard.hpp"
|
||||||
@ -241,7 +242,7 @@ namespace rexy{
|
|||||||
|
|
||||||
|
|
||||||
//Supplies all functions that string_base can't implement
|
//Supplies all functions that string_base can't implement
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc = rexy::allocator<Char>>
|
||||||
class basic_string : protected detail::hasallocator<Alloc>, public string_base<Char>
|
class basic_string : protected detail::hasallocator<Alloc>, public string_base<Char>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -260,74 +261,64 @@ namespace rexy{
|
|||||||
|
|
||||||
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(noexcept(this->allocate(0)));
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
REXY_CPP20_CONSTEXPR basic_string& _copy_string(const_pointer s, size_type len)
|
REXY_CPP20_CONSTEXPR basic_string& _copy_string(const_pointer s, size_type len)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
noexcept(this->deallocate(nullptr,0)));
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr basic_string(void)noexcept;
|
constexpr basic_string(void)noexcept;
|
||||||
constexpr basic_string(rexy::steal<pointer> data, size_type len)noexcept;
|
constexpr basic_string(rexy::steal<pointer> data, size_type len)noexcept;
|
||||||
constexpr basic_string(rexy::steal<pointer> data, size_type len, size_type cap)noexcept;
|
constexpr basic_string(rexy::steal<pointer> data, size_type len, size_type cap)noexcept;
|
||||||
constexpr basic_string(rexy::steal<pointer> data)noexcept;
|
constexpr basic_string(rexy::steal<pointer> data)noexcept;
|
||||||
REXY_CPP20_CONSTEXPR basic_string(const_pointer data, size_type len)noexcept(noexcept(this->allocate(0)));
|
REXY_CPP20_CONSTEXPR basic_string(const_pointer data, size_type len)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
REXY_CPP20_CONSTEXPR basic_string(const_pointer data, size_type len, size_type cap)noexcept(noexcept(this->allocate(0)));
|
REXY_CPP20_CONSTEXPR basic_string(const_pointer data, size_type len, size_type cap)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
REXY_CPP20_CONSTEXPR basic_string(const_pointer data)noexcept(noexcept(this->allocate(0)));
|
REXY_CPP20_CONSTEXPR basic_string(const_pointer data)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
REXY_CPP20_CONSTEXPR explicit basic_string(size_type len)noexcept(noexcept(this->allocate(0)));
|
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(noexcept(this->allocate(0)));
|
REXY_CPP20_CONSTEXPR basic_string(size_type len, size_type cap)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR basic_string(InputIt start, InputIt fin)noexcept(noexcept(this->allocate(0)));
|
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(noexcept(this->allocate(0)));
|
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
|
||||||
REXY_CPP20_CONSTEXPR basic_string(const basic_string& b)noexcept(noexcept(this->allocate(0)));
|
REXY_CPP20_CONSTEXPR basic_string(const basic_string& b)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
constexpr basic_string(basic_string&& s)noexcept;
|
constexpr basic_string(basic_string&& s)noexcept;
|
||||||
REXY_CPP20_CONSTEXPR basic_string(const string_base<Char>&)noexcept(noexcept(this->allocate(0)));
|
REXY_CPP20_CONSTEXPR basic_string(const string_base<Char>&)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
|
|
||||||
//dtor
|
//dtor
|
||||||
REXY_CPP20_CONSTEXPR ~basic_string(void)noexcept(noexcept(this->deallocate(nullptr, 0)));
|
REXY_CPP20_CONSTEXPR ~basic_string(void)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
|
|
||||||
REXY_CPP20_CONSTEXPR basic_string& operator=(const basic_string& s)
|
REXY_CPP20_CONSTEXPR basic_string& operator=(const basic_string& s)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
noexcept(this->deallocate(nullptr,0)));
|
|
||||||
|
|
||||||
constexpr basic_string& operator=(basic_string&& s)noexcept;
|
constexpr basic_string& operator=(basic_string&& s)noexcept;
|
||||||
|
|
||||||
REXY_CPP20_CONSTEXPR basic_string& operator=(const string_base<Char>& s)
|
REXY_CPP20_CONSTEXPR basic_string& operator=(const string_base<Char>& s)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
noexcept(this->deallocate(nullptr,0)));
|
|
||||||
REXY_CPP20_CONSTEXPR basic_string& operator=(const basic_string_view<Char>& sv)
|
REXY_CPP20_CONSTEXPR basic_string& operator=(const basic_string_view<Char>& sv)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
noexcept(this->deallocate(nullptr,0)));
|
|
||||||
//Copy from c string
|
//Copy from c string
|
||||||
REXY_CPP20_CONSTEXPR basic_string& operator=(const_pointer c)
|
REXY_CPP20_CONSTEXPR basic_string& operator=(const_pointer c)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
noexcept(this->deallocate(nullptr,0)));
|
|
||||||
|
|
||||||
//Replace managed pointer. Frees existing value
|
//Replace managed pointer. Frees existing value
|
||||||
REXY_CPP20_CONSTEXPR void reset(pointer val = nullptr)noexcept(noexcept(this->deallocate(nullptr,0)));
|
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(noexcept(this->deallocate(nullptr,0)));
|
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(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
noexcept(this->deallocate(nullptr,0)));
|
|
||||||
|
|
||||||
REXY_CPP20_CONSTEXPR void push_back(value_type data)
|
REXY_CPP20_CONSTEXPR void push_back(value_type data)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
noexcept(this->deallocate(nullptr,0)));
|
|
||||||
REXY_CPP20_CONSTEXPR void append(const_pointer data, size_type len)
|
REXY_CPP20_CONSTEXPR void append(const_pointer data, size_type len)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
noexcept(this->deallocate(nullptr,0)));
|
|
||||||
REXY_CPP20_CONSTEXPR void append(const_pointer data)
|
REXY_CPP20_CONSTEXPR void append(const_pointer data)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
noexcept(this->deallocate(nullptr,0)));
|
|
||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR void append(InputIt start, InputIt fin)
|
REXY_CPP20_CONSTEXPR void append(InputIt start, InputIt fin)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
noexcept(this->deallocate(nullptr,0)));
|
|
||||||
|
|
||||||
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 pointer release(void)noexcept(noexcept(this->allocate(0)));
|
REXY_CPP20_CONSTEXPR pointer release(void)noexcept(is_nothrow_allocator_v<Alloc>);
|
||||||
using detail::hasallocator<Alloc>::allocator;
|
using detail::hasallocator<Alloc>::allocator;
|
||||||
|
|
||||||
constexpr basic_string_view<value_type> create_view(void)const noexcept;
|
constexpr basic_string_view<value_type> create_view(void)const noexcept;
|
||||||
|
|||||||
@ -82,7 +82,7 @@ namespace rexy{
|
|||||||
//allocate string if longer than small string capacity, copy otherwise
|
//allocate string if longer than small string capacity, copy otherwise
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::_copy_construct_string(const_pointer data, size_type len, size_type cap)
|
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::_copy_construct_string(const_pointer data, size_type len, size_type cap)
|
||||||
noexcept(noexcept(this->allocate(0)))
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
{
|
{
|
||||||
if(cap > this->get_short_capacity()){
|
if(cap > this->get_short_capacity()){
|
||||||
this->set_islong_flag(true);
|
this->set_islong_flag(true);
|
||||||
@ -116,31 +116,31 @@ namespace rexy{
|
|||||||
string_base<Char>(data.value(), len, cap){}
|
string_base<Char>(data.value(), len, cap){}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const_pointer data, size_type len, size_type cap)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const_pointer data, size_type len, size_type cap)
|
||||||
noexcept(noexcept(this->allocate(0)))
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
{
|
{
|
||||||
_copy_construct_string(data, len, cap);
|
_copy_construct_string(data, len, cap);
|
||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const_pointer data, size_type len)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const_pointer data, size_type len)
|
||||||
noexcept(noexcept(this->allocate(0))):
|
noexcept(is_nothrow_allocator_v<Alloc>):
|
||||||
basic_string(data, len, len){}
|
basic_string(data, len, len){}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const_pointer data)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const_pointer data)
|
||||||
noexcept(noexcept(this->allocate(0))):
|
noexcept(is_nothrow_allocator_v<Alloc>):
|
||||||
basic_string(data, data ? strlen(data) : 0){}
|
basic_string(data, data ? strlen(data) : 0){}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(size_type cap)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(size_type cap)
|
||||||
noexcept(noexcept(this->allocate(0))):
|
noexcept(is_nothrow_allocator_v<Alloc>):
|
||||||
basic_string(size_type{0}, cap){}
|
basic_string(size_type{0}, cap){}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(size_type len, size_type cap)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(size_type len, size_type cap)
|
||||||
noexcept(noexcept(this->allocate(0)))
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
{
|
{
|
||||||
_copy_construct_string(nullptr, len, cap);
|
_copy_construct_string(nullptr, len, cap);
|
||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const basic_string_view<Char>& sv)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const basic_string_view<Char>& sv)
|
||||||
noexcept(noexcept(this->allocate(0)))
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
{
|
{
|
||||||
_copy_construct_string(sv.c_str(), sv.length(), sv.length());
|
_copy_construct_string(sv.c_str(), sv.length(), sv.length());
|
||||||
}
|
}
|
||||||
@ -148,7 +148,7 @@ 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 basic_string<Char,Alloc>::basic_string(InputIt start, InputIt fin)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(InputIt start, InputIt fin)
|
||||||
noexcept(noexcept(this->allocate(0))):
|
noexcept(is_nothrow_allocator_v<Alloc>):
|
||||||
basic_string(nullptr, size_type{fin - start})
|
basic_string(nullptr, size_type{fin - start})
|
||||||
{
|
{
|
||||||
auto raw = this->get_pointer();
|
auto raw = this->get_pointer();
|
||||||
@ -161,7 +161,7 @@ namespace rexy{
|
|||||||
//normal copy and move ctors
|
//normal copy and move ctors
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const basic_string& b)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::basic_string(const basic_string& b)
|
||||||
noexcept(noexcept(this->allocate(0))):
|
noexcept(is_nothrow_allocator_v<Alloc>):
|
||||||
detail::hasallocator<Alloc>(b)
|
detail::hasallocator<Alloc>(b)
|
||||||
{
|
{
|
||||||
_copy_construct_string(b.get(), b.length(), b.capacity());
|
_copy_construct_string(b.get(), b.length(), b.capacity());
|
||||||
@ -172,7 +172,7 @@ namespace rexy{
|
|||||||
string_base<Char>(std::move(s)){}
|
string_base<Char>(std::move(s)){}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
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(noexcept(this->allocate(0)))
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
{
|
{
|
||||||
_copy_construct_string(b.get(), b.length(), b.capacity());
|
_copy_construct_string(b.get(), b.length(), b.capacity());
|
||||||
}
|
}
|
||||||
@ -180,7 +180,7 @@ namespace rexy{
|
|||||||
//dtor
|
//dtor
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::~basic_string(void)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>::~basic_string(void)
|
||||||
noexcept(noexcept(this->deallocate(nullptr, 0)))
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
{
|
{
|
||||||
if(this->islong()){
|
if(this->islong()){
|
||||||
this->deallocate(this->get_pointer(), sizeof(value_type)*(this->get_long_capacity()+1));
|
this->deallocate(this->get_pointer(), sizeof(value_type)*(this->get_long_capacity()+1));
|
||||||
@ -189,8 +189,7 @@ namespace rexy{
|
|||||||
|
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>& basic_string<Char,Alloc>::operator=(const basic_string& s)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>& basic_string<Char,Alloc>::operator=(const basic_string& s)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
noexcept(this->deallocate(nullptr, 0)))
|
|
||||||
{
|
{
|
||||||
if(s.length() < this->capacity()){
|
if(s.length() < this->capacity()){
|
||||||
memcpy(this->get_pointer(), s.get_pointer(), sizeof(value_type)*(s.length()+1));
|
memcpy(this->get_pointer(), s.get_pointer(), sizeof(value_type)*(s.length()+1));
|
||||||
@ -207,24 +206,21 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>& basic_string<Char,Alloc>::operator=(const string_base<Char>& s)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>& basic_string<Char,Alloc>::operator=(const string_base<Char>& s)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
noexcept(this->deallocate(nullptr,0)))
|
|
||||||
{
|
{
|
||||||
return (*this = basic_string(s));
|
return (*this = basic_string(s));
|
||||||
}
|
}
|
||||||
//Copy from c string
|
//Copy from c string
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>& basic_string<Char,Alloc>::operator=(const basic_string_view<Char>& sv)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>& basic_string<Char,Alloc>::operator=(const basic_string_view<Char>& sv)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
noexcept(this->deallocate(nullptr,0)))
|
|
||||||
{
|
{
|
||||||
return _copy_string(sv.c_str(), sv.length());
|
return _copy_string(sv.c_str(), sv.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>& basic_string<Char,Alloc>::operator=(const_pointer c)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>& basic_string<Char,Alloc>::operator=(const_pointer c)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
noexcept(this->deallocate(nullptr,0)))
|
|
||||||
{
|
{
|
||||||
return _copy_string(c, strlen(c));
|
return _copy_string(c, strlen(c));
|
||||||
}
|
}
|
||||||
@ -232,13 +228,13 @@ namespace rexy{
|
|||||||
//Replace managed pointer. Frees existing value
|
//Replace managed pointer. Frees existing value
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::reset(pointer val)
|
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::reset(pointer val)
|
||||||
noexcept(noexcept(this->deallocate(nullptr,0)))
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
{
|
{
|
||||||
reset(val, val ? strlen(val) : 0);
|
reset(val, val ? strlen(val) : 0);
|
||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::reset(pointer val, size_type len)
|
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::reset(pointer val, size_type len)
|
||||||
noexcept(noexcept(this->deallocate(nullptr,0)))
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
{
|
{
|
||||||
if(this->islong())
|
if(this->islong())
|
||||||
this->deallocate(this->get_long_ptr(),sizeof(value_type)*(this->get_long_capacity()+1));
|
this->deallocate(this->get_long_ptr(),sizeof(value_type)*(this->get_long_capacity()+1));
|
||||||
@ -249,8 +245,7 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR bool basic_string<Char,Alloc>::resize(size_type newsize)
|
REXY_CPP20_CONSTEXPR bool basic_string<Char,Alloc>::resize(size_type newsize)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
noexcept(this->deallocate(nullptr,0)))
|
|
||||||
{
|
{
|
||||||
if(newsize < this->capacity())
|
if(newsize < this->capacity())
|
||||||
return false;
|
return false;
|
||||||
@ -261,16 +256,14 @@ namespace rexy{
|
|||||||
|
|
||||||
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(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
noexcept(this->deallocate(nullptr,0)))
|
|
||||||
{
|
{
|
||||||
append(&data, 1);
|
append(&data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::append(const_pointer data, size_type len)
|
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::append(const_pointer data, size_type len)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
noexcept(this->deallocate(nullptr,0)))
|
|
||||||
{
|
{
|
||||||
size_type mylen = this->length();
|
size_type mylen = this->length();
|
||||||
size_type mycap = this->capacity();
|
size_type mycap = this->capacity();
|
||||||
@ -290,8 +283,7 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::append(const_pointer data)
|
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::append(const_pointer data)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
noexcept(this->deallocate(nullptr,0)))
|
|
||||||
{
|
{
|
||||||
if(data)
|
if(data)
|
||||||
append(data, strlen(data));
|
append(data, strlen(data));
|
||||||
@ -299,8 +291,7 @@ 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 void basic_string<Char,Alloc>::append(InputIt start, InputIt fin)
|
REXY_CPP20_CONSTEXPR void basic_string<Char,Alloc>::append(InputIt start, InputIt fin)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
noexcept(this->deallocate(nullptr,0)))
|
|
||||||
{
|
{
|
||||||
size_type append_len = fin - start;
|
size_type append_len = fin - start;
|
||||||
|
|
||||||
@ -334,7 +325,7 @@ namespace rexy{
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
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(noexcept(this->allocate(0))) -> pointer{
|
REXY_CPP20_CONSTEXPR auto basic_string<Char,Alloc>::release(void)noexcept(is_nothrow_allocator_v<Alloc>) -> pointer{
|
||||||
if(this->islong()){
|
if(this->islong()){
|
||||||
pointer raw = this->get_long_ptr();
|
pointer raw = this->get_long_ptr();
|
||||||
this->set_islong_flag(false);
|
this->set_islong_flag(false);
|
||||||
@ -363,8 +354,7 @@ namespace rexy{
|
|||||||
|
|
||||||
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>& basic_string<Char,Alloc>::_copy_string(const_pointer s, size_type len)
|
REXY_CPP20_CONSTEXPR basic_string<Char,Alloc>& basic_string<Char,Alloc>::_copy_string(const_pointer s, size_type len)
|
||||||
noexcept(noexcept(this->allocate(0)) &&
|
noexcept(is_nothrow_allocator_v<Alloc>)
|
||||||
noexcept(this->deallocate(nullptr,0)))
|
|
||||||
{
|
{
|
||||||
if(!s || !len)
|
if(!s || !len)
|
||||||
return (*this = basic_string(rexy::steal<pointer>(nullptr), 0, 0));
|
return (*this = basic_string(rexy::steal<pointer>(nullptr), 0, 0));
|
||||||
|
|||||||
@ -41,7 +41,7 @@ namespace rexy{
|
|||||||
using const_pointer = const value_type*;
|
using const_pointer = const value_type*;
|
||||||
using reference = value_type&;
|
using reference = value_type&;
|
||||||
using const_reference = const value_type&;
|
using const_reference = const value_type&;
|
||||||
using iterator = pointer;
|
using iterator = const_pointer;
|
||||||
using const_iterator = const_pointer;
|
using const_iterator = const_pointer;
|
||||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
@ -53,31 +53,38 @@ namespace rexy{
|
|||||||
size_type m_length = 0;
|
size_type m_length = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr basic_string_view(void)noexcept;
|
constexpr basic_string_view(void)noexcept = default;
|
||||||
constexpr basic_string_view(const_pointer str, size_type len)noexcept;
|
constexpr basic_string_view(const_pointer str, size_type len)noexcept;
|
||||||
constexpr basic_string_view(const_pointer c)noexcept;
|
constexpr basic_string_view(const_pointer c)noexcept;
|
||||||
constexpr basic_string_view(const basic_string_view& s)noexcept;
|
constexpr basic_string_view(const basic_string_view& s)noexcept = default;
|
||||||
constexpr basic_string_view(const string_base<Char>& s)noexcept;
|
constexpr basic_string_view(const string_base<Char>& s)noexcept;
|
||||||
constexpr basic_string_view(basic_string_view&& s)noexcept;
|
constexpr basic_string_view(basic_string_view&& s)noexcept = default;
|
||||||
template<class InIter>
|
template<class InIter>
|
||||||
constexpr basic_string_view(InIter start, InIter fin)noexcept;
|
constexpr basic_string_view(InIter start, InIter fin)noexcept;
|
||||||
REXY_CPP20_CONSTEXPR ~basic_string_view(void)noexcept = default;
|
REXY_CPP20_CONSTEXPR ~basic_string_view(void)noexcept = default;
|
||||||
|
|
||||||
constexpr basic_string_view& operator=(const_pointer c)noexcept;
|
constexpr basic_string_view& operator=(const_pointer c)noexcept;
|
||||||
constexpr basic_string_view& operator=(const basic_string_view& s)noexcept;
|
constexpr basic_string_view& operator=(const basic_string_view& s)noexcept = default;
|
||||||
constexpr basic_string_view& operator=(basic_string_view&&)noexcept;
|
constexpr basic_string_view& operator=(basic_string_view&&)noexcept = default;
|
||||||
|
|
||||||
|
|
||||||
//Length of string not including null terminator
|
//Length of string not including null terminator
|
||||||
constexpr size_type length(void)const noexcept{return m_length;}
|
constexpr size_type length(void)const noexcept{return m_length;}
|
||||||
|
constexpr size_type size(void)const noexcept{return m_length;}
|
||||||
|
constexpr bool empty(void)const noexcept{return m_length == 0;}
|
||||||
//direct access to managed pointer
|
//direct access to managed pointer
|
||||||
constexpr const_pointer c_str(void)const noexcept{return m_data;}
|
constexpr const_pointer c_str(void)const noexcept{return m_data;}
|
||||||
|
constexpr const_pointer data(void)const noexcept{return m_data;}
|
||||||
constexpr const_pointer get(void)const noexcept{return m_data;}
|
constexpr const_pointer get(void)const noexcept{return m_data;}
|
||||||
constexpr operator const_pointer(void)const noexcept{return m_data;}
|
constexpr operator const_pointer(void)const noexcept{return m_data;}
|
||||||
//true if m_data is not empty
|
//true if m_data is not empty
|
||||||
constexpr bool valid(void)const noexcept{return m_length > 0;}
|
constexpr bool valid(void)const noexcept{return m_length > 0;}
|
||||||
|
|
||||||
constexpr const_reference operator[](size_type i)const noexcept{return m_data[i];}
|
constexpr const_reference operator[](size_type i)const noexcept{return m_data[i];}
|
||||||
|
constexpr const_reference at(size_type i)const noexcept{return m_data[i];}
|
||||||
|
constexpr const_reference front(size_type i)const noexcept{return m_data[0];}
|
||||||
|
constexpr const_reference back(size_type i)const noexcept{return m_data[m_length-1];}
|
||||||
|
constexpr const_iterator it_at(size_type i)const noexcept{return m_data + i;}
|
||||||
|
|
||||||
constexpr const_iterator search(const basic_string_view& s)const;
|
constexpr const_iterator search(const basic_string_view& s)const;
|
||||||
constexpr const_iterator search(const_pointer c)const;
|
constexpr const_iterator search(const_pointer c)const;
|
||||||
@ -115,6 +122,7 @@ namespace rexy{
|
|||||||
basic_string_view(const T*, size_t) -> basic_string_view<T>;
|
basic_string_view(const T*, size_t) -> basic_string_view<T>;
|
||||||
|
|
||||||
using string_view = basic_string_view<char>;
|
using string_view = basic_string_view<char>;
|
||||||
|
using wstring_view = basic_string_view<wchar_t>;
|
||||||
|
|
||||||
#ifndef LIBREXY_HEADER_ONLY
|
#ifndef LIBREXY_HEADER_ONLY
|
||||||
extern template class basic_string_view<char>;
|
extern template class basic_string_view<char>;
|
||||||
|
|||||||
@ -25,33 +25,17 @@
|
|||||||
|
|
||||||
namespace rexy{
|
namespace rexy{
|
||||||
|
|
||||||
template<class Char>
|
|
||||||
constexpr basic_string_view<Char>::basic_string_view(void)noexcept:
|
|
||||||
basic_string_view(nullptr, 0){}
|
|
||||||
|
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr basic_string_view<Char>::basic_string_view(const_pointer str, size_type len)noexcept:
|
constexpr basic_string_view<Char>::basic_string_view(const_pointer str, size_type len)noexcept:
|
||||||
m_data(str), m_length(len){}
|
m_data(str), m_length(len){}
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr basic_string_view<Char>::basic_string_view(const basic_string_view& s)noexcept:
|
|
||||||
m_data(s.m_data), m_length(s.m_length){}
|
|
||||||
template<class Char>
|
|
||||||
constexpr basic_string_view<Char>::basic_string_view(const string_base<Char>& s)noexcept:
|
constexpr basic_string_view<Char>::basic_string_view(const string_base<Char>& s)noexcept:
|
||||||
m_data(s.c_str()), m_length(s.length()){}
|
m_data(s.c_str()), m_length(s.length()){}
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr basic_string_view<Char>::basic_string_view(basic_string_view&& s)noexcept:
|
|
||||||
m_data(s.m_data), m_length(s.m_length){}
|
|
||||||
template<class Char>
|
|
||||||
template<class InIter>
|
template<class InIter>
|
||||||
constexpr basic_string_view<Char>::basic_string_view(InIter start, InIter fin)noexcept:
|
constexpr basic_string_view<Char>::basic_string_view(InIter start, InIter fin)noexcept:
|
||||||
basic_string_view(compat::to_address(start), fin - start){}
|
basic_string_view(compat::to_address(start), fin - start){}
|
||||||
|
|
||||||
template<class Char>
|
|
||||||
constexpr basic_string_view<Char>& basic_string_view<Char>::operator=(const basic_string_view& s)noexcept{
|
|
||||||
m_data = s.m_data;
|
|
||||||
m_length = s.m_length;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr basic_string_view<Char>::basic_string_view(const_pointer c)noexcept:
|
constexpr basic_string_view<Char>::basic_string_view(const_pointer c)noexcept:
|
||||||
basic_string_view(c, strlen(c)){}
|
basic_string_view(c, strlen(c)){}
|
||||||
@ -61,12 +45,6 @@ namespace rexy{
|
|||||||
m_length = strlen(c);
|
m_length = strlen(c);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template<class Char>
|
|
||||||
constexpr basic_string_view<Char>& basic_string_view<Char>::operator=(basic_string_view&& s)noexcept{
|
|
||||||
m_data = s.m_data;
|
|
||||||
m_length = s.m_length;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr auto basic_string_view<Char>::search(const basic_string_view& s)const -> const_iterator{
|
constexpr auto basic_string_view<Char>::search(const basic_string_view& s)const -> const_iterator{
|
||||||
|
|||||||
@ -145,6 +145,10 @@ namespace rexy{
|
|||||||
ld[i] = rd[i];
|
ld[i] = rd[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template<class T>
|
||||||
|
constexpr T abs(const T& val){
|
||||||
|
return val > 0 ? val : -val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif //__cpp_lib_is_constant_evaluated
|
#endif //__cpp_lib_is_constant_evaluated
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user