Update cx::string to have better c++20 support
This commit is contained in:
parent
6f07577bf0
commit
a7474d5939
44
include/rexy/compat/cpp17/cx/string.hpp
Normal file
44
include/rexy/compat/cpp17/cx/string.hpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of rexy's general purpose library
|
||||||
|
Copyright (C) 2022 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REXY_COMPAT_CPP17_CX_STRING_HPP
|
||||||
|
#define REXY_COMPAT_CPP17_CX_STRING_HPP
|
||||||
|
|
||||||
|
#include "../../../string_base.hpp" //string_cat_expr
|
||||||
|
#include "../../../string_view.hpp" //string_view
|
||||||
|
#include <utility> //forward
|
||||||
|
#include <type_traits> //enable_if
|
||||||
|
|
||||||
|
namespace rexy::cx{
|
||||||
|
|
||||||
|
template<class Str1, class Str2, std::enable_if_t<is_cx_string<Str1,Str2>::value,int> = 0>
|
||||||
|
constexpr auto operator+(Str1&& l, Str2&& r)noexcept{
|
||||||
|
return string_cat_expr(std::forward<Str1>(l), std::forward<Str2>(r));
|
||||||
|
}
|
||||||
|
template<class Str1, std::enable_if_t<is_cx_string<Str1>::value,int> = 0>
|
||||||
|
constexpr auto operator+(Str1&& l, const char* r)noexcept{
|
||||||
|
return string_cat_expr(std::forward<Str1>(l), rexy::basic_string_view<char>(r));
|
||||||
|
}
|
||||||
|
template<class Str1, std::enable_if_t<is_cx_string<Str1>::value,int> = 0>
|
||||||
|
constexpr auto operator+(const char* l, Str1&& r)noexcept{
|
||||||
|
return string_cat_expr(rexy::basic_string_view<char>(l), std::forward<Str1>(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
46
include/rexy/compat/cpp20/cx/string.hpp
Normal file
46
include/rexy/compat/cpp20/cx/string.hpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of rexy's general purpose library
|
||||||
|
Copyright (C) 2022 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REXY_COMPAT_CPP20_CX_STRING_HPP
|
||||||
|
#define REXY_COMPAT_CPP20_CX_STRING_HPP
|
||||||
|
|
||||||
|
#include "../../../string_base.hpp" //string_cat_expr
|
||||||
|
#include "../../../string_view.hpp" //string_view
|
||||||
|
#include <utility> //forward
|
||||||
|
|
||||||
|
namespace rexy{
|
||||||
|
template<class T>
|
||||||
|
concept CxString = cx::is_cx_string<T>::value;
|
||||||
|
}
|
||||||
|
namespace rexy::cx{
|
||||||
|
template<CxString Str1, CxString Str2>
|
||||||
|
constexpr auto operator+(Str1&& l, Str2&& r)noexcept{
|
||||||
|
return string_cat_expr(std::forward<Str1>(l), std::forward<Str2>(r));
|
||||||
|
}
|
||||||
|
template<CxString Str1>
|
||||||
|
constexpr auto operator+(Str1&& l, const char* r)noexcept{
|
||||||
|
return string_cat_expr(std::forward<Str1>(l), rexy::basic_string_view<char>(r));
|
||||||
|
}
|
||||||
|
template<CxString Str1>
|
||||||
|
constexpr auto operator+(const char* l, Str1&& r)noexcept{
|
||||||
|
return string_cat_expr(rexy::basic_string_view<char>(l), std::forward<Str1>(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
This file is a part of rexy's general purpose library
|
This file is a part of rexy's general purpose library
|
||||||
Copyright (C) 2020 rexy712
|
Copyright (C) 2020-2022 rexy712
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -19,15 +19,17 @@
|
|||||||
#ifndef REXY_CX_STRING_HPP
|
#ifndef REXY_CX_STRING_HPP
|
||||||
#define REXY_CX_STRING_HPP
|
#define REXY_CX_STRING_HPP
|
||||||
|
|
||||||
|
#include <cstddef> //ptrdiff_t, size_t
|
||||||
|
|
||||||
namespace rexy::cx{
|
namespace rexy::cx{
|
||||||
template<size_t N, class Char>
|
template<std::size_t N, class Char>
|
||||||
class string;
|
class string;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../string_base.hpp"
|
#include "../string_base.hpp" //string_cat_expr
|
||||||
#include "../utility.hpp"
|
#include "../utility.hpp" //strlen
|
||||||
#include <type_traits>
|
#include "../detail/string_appender.hpp"
|
||||||
#include <cstddef> //ptrdiff_t, size_t
|
#include <type_traits> //nothrow_invocable, integral_constant, declval, remove_cvref_t
|
||||||
|
|
||||||
#include "../compat/standard.hpp"
|
#include "../compat/standard.hpp"
|
||||||
|
|
||||||
@ -42,8 +44,8 @@ namespace rexy::cx{
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using value_type = Char;
|
using value_type = Char;
|
||||||
using size_type = size_t;
|
using size_type = std::size_t;
|
||||||
using difference_type = ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using pointer = value_type*;
|
using pointer = value_type*;
|
||||||
using const_pointer = const value_type*;
|
using const_pointer = const value_type*;
|
||||||
using reference = value_type&;
|
using reference = value_type&;
|
||||||
@ -52,15 +54,15 @@ namespace rexy::cx{
|
|||||||
using const_iterator = const_pointer;
|
using const_iterator = const_pointer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr size_t max_size = N;
|
static constexpr std::size_t max_size = N;
|
||||||
private:
|
public:
|
||||||
value_type m_data[N] = {};
|
value_type m_data[N] = {};
|
||||||
size_type m_length = 0;
|
size_type m_length = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr string(void) = default;
|
constexpr string(void) = default;
|
||||||
template<size_type M>
|
template<size_type M>
|
||||||
constexpr string(const char(&data)[M])noexcept:
|
constexpr string(const value_type(&data)[M])noexcept:
|
||||||
m_length(M)
|
m_length(M)
|
||||||
{
|
{
|
||||||
static_assert(M <= N);
|
static_assert(M <= N);
|
||||||
@ -69,7 +71,7 @@ namespace rexy::cx{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
constexpr string(const_pointer data)noexcept:
|
constexpr string(const_pointer data)noexcept:
|
||||||
m_length(strlen(data))
|
m_length(rexy::strlen(data))
|
||||||
{
|
{
|
||||||
for(size_type i = 0;i < m_length;++i){
|
for(size_type i = 0;i < m_length;++i){
|
||||||
m_data[i] = data[i];
|
m_data[i] = data[i];
|
||||||
@ -103,7 +105,7 @@ namespace rexy::cx{
|
|||||||
REXY_CPP20_CONSTEXPR ~string(void)noexcept = default;
|
REXY_CPP20_CONSTEXPR ~string(void)noexcept = default;
|
||||||
|
|
||||||
constexpr string& operator=(const_pointer c)noexcept{
|
constexpr string& operator=(const_pointer c)noexcept{
|
||||||
m_length = strlen(c);
|
m_length = rexy::strlen(c);
|
||||||
for(size_type i = 0;i < m_length;++i){
|
for(size_type i = 0;i < m_length;++i){
|
||||||
m_data[i] = c[i];
|
m_data[i] = c[i];
|
||||||
}
|
}
|
||||||
@ -113,44 +115,34 @@ namespace rexy::cx{
|
|||||||
constexpr string& operator=(string&&)noexcept = default;
|
constexpr string& operator=(string&&)noexcept = default;
|
||||||
|
|
||||||
|
|
||||||
constexpr size_type length(void)const noexcept{
|
constexpr size_type length(void)const noexcept
|
||||||
return m_length;
|
{return m_length;}
|
||||||
}
|
constexpr size_type capacity(void)const noexcept
|
||||||
constexpr size_type capacity(void)const noexcept{
|
{return max_size;}
|
||||||
return max_size;
|
constexpr pointer c_str(void)noexcept
|
||||||
}
|
{return m_data;}
|
||||||
constexpr pointer c_str(void)noexcept{
|
constexpr const_pointer c_str(void)const noexcept
|
||||||
return m_data;
|
{return m_data;}
|
||||||
}
|
constexpr pointer get(void)noexcept
|
||||||
constexpr const_pointer c_str(void)const noexcept{
|
{return m_data;}
|
||||||
return m_data;
|
constexpr const_pointer get(void)const noexcept
|
||||||
}
|
{return m_data;}
|
||||||
constexpr pointer get(void)noexcept{
|
constexpr operator pointer(void)noexcept
|
||||||
return m_data;
|
{return m_data;}
|
||||||
}
|
constexpr operator const_pointer(void)const noexcept
|
||||||
constexpr const_pointer get(void)const noexcept{
|
{return m_data;}
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
constexpr operator pointer(void)noexcept{
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
constexpr operator const_pointer(void)const noexcept{
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool valid(void)const noexcept{
|
constexpr bool valid(void)const noexcept
|
||||||
return m_length > 0;
|
{return m_length > 0;}
|
||||||
}
|
constexpr reference operator[](size_type i)noexcept
|
||||||
constexpr reference operator[](size_type i)noexcept{
|
{return m_data[i];}
|
||||||
return m_data[i];
|
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 bool resize(size_type i)noexcept{
|
constexpr bool resize(size_type i)noexcept{
|
||||||
if(i >= capacity())
|
if(i >= capacity()){
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
m_length = i;
|
m_length = i;
|
||||||
m_data[m_length] = 0;
|
m_data[m_length] = 0;
|
||||||
return true;
|
return true;
|
||||||
@ -161,45 +153,31 @@ namespace rexy::cx{
|
|||||||
m_data[m_length++] = data[i];
|
m_data[m_length++] = data[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
constexpr void append(const_pointer data)noexcept{
|
constexpr void append(const_pointer data)noexcept
|
||||||
append(data, strlen(data));
|
{append(data, rexy::strlen(data));}
|
||||||
}
|
constexpr void append(const string& s)noexcept
|
||||||
constexpr void append(const string& s)noexcept{
|
{append(s.get(), s.length());}
|
||||||
append(s.get(), s.length());
|
constexpr void append(const rexy::basic_string_view<value_type>& s)noexcept
|
||||||
}
|
{append(s.get(), s.length());}
|
||||||
constexpr void append(const rexy::basic_string_view<value_type>& s)noexcept{
|
|
||||||
append(s.get(), s.length());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
template<class Char, std::size_t N>
|
||||||
|
string(const Char(&data)[N]) -> string<N, Char>;
|
||||||
|
|
||||||
namespace detail{
|
|
||||||
template<class T>
|
|
||||||
struct is_cx_string_helper{
|
|
||||||
static constexpr bool value = false;
|
|
||||||
};
|
|
||||||
template<size_t N, class Char>
|
|
||||||
struct is_cx_string_helper<cx::string<N,Char>>{
|
|
||||||
static constexpr bool value = true;
|
|
||||||
};
|
|
||||||
template<class... Ts>
|
template<class... Ts>
|
||||||
struct is_cx_string{
|
struct is_cx_string{
|
||||||
static constexpr bool value = (is_cx_string_helper<std::decay_t<Ts>>::value && ...);
|
template<class Char, std::size_t N>
|
||||||
|
static std::true_type check(cx::string<N,Char>);
|
||||||
|
static std::false_type check(...);
|
||||||
|
static constexpr bool value = (decltype(check(std::declval<std::remove_cvref_t<Ts>>()))::value && ...);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Str1, class Str2, std::enable_if_t<detail::is_cx_string<Str1,Str2>::value,int> = 0>
|
#ifdef __cpp_concepts
|
||||||
constexpr auto operator+(Str1&& l, Str2&& r)noexcept{
|
#include "../compat/cpp20/cx/string.hpp"
|
||||||
return string_cat_expr(std::forward<Str1>(l), std::forward<Str2>(r));
|
#else //__cpp_concepts
|
||||||
}
|
#include "../compat/cpp17/cx/string.hpp"
|
||||||
template<class Str1, std::enable_if_t<detail::is_cx_string<Str1>::value,int> = 0>
|
#endif //__cpp_concepts
|
||||||
constexpr auto operator+(Str1&& l, const char* r)noexcept{
|
|
||||||
return string_cat_expr(std::forward<Str1>(l), rexy::basic_string_view<char>(r));
|
|
||||||
}
|
|
||||||
template<class Str1, std::enable_if_t<detail::is_cx_string<Str1>::value,int> = 0>
|
|
||||||
constexpr auto operator+(const char* l, Str1&& r)noexcept{
|
|
||||||
return string_cat_expr(rexy::basic_string_view<char>(l), std::forward<Str1>(r));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef REXY_CX_HASH_HPP
|
#ifdef REXY_CX_HASH_HPP
|
||||||
#include "cx_string_hash.hpp"
|
#include "cx_string_hash.hpp"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user