Update cx::string to have better c++20 support

This commit is contained in:
rexy712 2022-06-17 13:40:48 -07:00
parent 6f07577bf0
commit a7474d5939
3 changed files with 151 additions and 83 deletions

View 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

View 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

View File

@ -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"