From a7474d59393102d36707464f7561f8df297f96e4 Mon Sep 17 00:00:00 2001 From: rexy712 Date: Fri, 17 Jun 2022 13:40:48 -0700 Subject: [PATCH] Update cx::string to have better c++20 support --- include/rexy/compat/cpp17/cx/string.hpp | 44 ++++++++ include/rexy/compat/cpp20/cx/string.hpp | 46 ++++++++ include/rexy/cx/string.hpp | 144 ++++++++++-------------- 3 files changed, 151 insertions(+), 83 deletions(-) create mode 100644 include/rexy/compat/cpp17/cx/string.hpp create mode 100644 include/rexy/compat/cpp20/cx/string.hpp diff --git a/include/rexy/compat/cpp17/cx/string.hpp b/include/rexy/compat/cpp17/cx/string.hpp new file mode 100644 index 0000000..342328a --- /dev/null +++ b/include/rexy/compat/cpp17/cx/string.hpp @@ -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 . +*/ + +#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 //forward +#include //enable_if + +namespace rexy::cx{ + + template::value,int> = 0> + constexpr auto operator+(Str1&& l, Str2&& r)noexcept{ + return string_cat_expr(std::forward(l), std::forward(r)); + } + template::value,int> = 0> + constexpr auto operator+(Str1&& l, const char* r)noexcept{ + return string_cat_expr(std::forward(l), rexy::basic_string_view(r)); + } + template::value,int> = 0> + constexpr auto operator+(const char* l, Str1&& r)noexcept{ + return string_cat_expr(rexy::basic_string_view(l), std::forward(r)); + } + +} + +#endif diff --git a/include/rexy/compat/cpp20/cx/string.hpp b/include/rexy/compat/cpp20/cx/string.hpp new file mode 100644 index 0000000..47db615 --- /dev/null +++ b/include/rexy/compat/cpp20/cx/string.hpp @@ -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 . +*/ + +#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 //forward + +namespace rexy{ + template + concept CxString = cx::is_cx_string::value; +} +namespace rexy::cx{ + template + constexpr auto operator+(Str1&& l, Str2&& r)noexcept{ + return string_cat_expr(std::forward(l), std::forward(r)); + } + template + constexpr auto operator+(Str1&& l, const char* r)noexcept{ + return string_cat_expr(std::forward(l), rexy::basic_string_view(r)); + } + template + constexpr auto operator+(const char* l, Str1&& r)noexcept{ + return string_cat_expr(rexy::basic_string_view(l), std::forward(r)); + } + +} + +#endif diff --git a/include/rexy/cx/string.hpp b/include/rexy/cx/string.hpp index 6029037..cbac8c8 100644 --- a/include/rexy/cx/string.hpp +++ b/include/rexy/cx/string.hpp @@ -1,6 +1,6 @@ /** 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 it under the terms of the GNU General Public License as published by @@ -19,15 +19,17 @@ #ifndef REXY_CX_STRING_HPP #define REXY_CX_STRING_HPP +#include //ptrdiff_t, size_t + namespace rexy::cx{ - template + template class string; } -#include "../string_base.hpp" -#include "../utility.hpp" -#include -#include //ptrdiff_t, size_t +#include "../string_base.hpp" //string_cat_expr +#include "../utility.hpp" //strlen +#include "../detail/string_appender.hpp" +#include //nothrow_invocable, integral_constant, declval, remove_cvref_t #include "../compat/standard.hpp" @@ -42,8 +44,8 @@ namespace rexy::cx{ { public: using value_type = Char; - using size_type = size_t; - using difference_type = ptrdiff_t; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; using pointer = value_type*; using const_pointer = const value_type*; using reference = value_type&; @@ -52,15 +54,15 @@ namespace rexy::cx{ using const_iterator = const_pointer; public: - static constexpr size_t max_size = N; - private: + static constexpr std::size_t max_size = N; + public: value_type m_data[N] = {}; size_type m_length = 0; public: constexpr string(void) = default; template - constexpr string(const char(&data)[M])noexcept: + constexpr string(const value_type(&data)[M])noexcept: m_length(M) { static_assert(M <= N); @@ -69,7 +71,7 @@ namespace rexy::cx{ } } constexpr string(const_pointer data)noexcept: - m_length(strlen(data)) + m_length(rexy::strlen(data)) { for(size_type i = 0;i < m_length;++i){ m_data[i] = data[i]; @@ -103,7 +105,7 @@ namespace rexy::cx{ REXY_CPP20_CONSTEXPR ~string(void)noexcept = default; 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){ m_data[i] = c[i]; } @@ -113,44 +115,34 @@ namespace rexy::cx{ constexpr string& operator=(string&&)noexcept = default; - constexpr size_type length(void)const noexcept{ - return m_length; - } - constexpr size_type capacity(void)const noexcept{ - return max_size; - } - constexpr pointer c_str(void)noexcept{ - return m_data; - } - constexpr const_pointer c_str(void)const noexcept{ - return m_data; - } - constexpr pointer get(void)noexcept{ - return m_data; - } - constexpr const_pointer get(void)const noexcept{ - return m_data; - } - constexpr operator pointer(void)noexcept{ - return m_data; - } - constexpr operator const_pointer(void)const noexcept{ - return m_data; - } + constexpr size_type length(void)const noexcept + {return m_length;} + constexpr size_type capacity(void)const noexcept + {return max_size;} + constexpr pointer c_str(void)noexcept + {return m_data;} + constexpr const_pointer c_str(void)const noexcept + {return m_data;} + constexpr pointer get(void)noexcept + {return m_data;} + constexpr const_pointer get(void)const noexcept + {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{ - return m_length > 0; - } - constexpr reference operator[](size_type i)noexcept{ - return m_data[i]; - } - constexpr const_reference operator[](size_type i)const noexcept{ - return m_data[i]; - } + constexpr bool valid(void)const noexcept + {return m_length > 0;} + constexpr reference operator[](size_type i)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{ - if(i >= capacity()) + if(i >= capacity()){ return false; + } m_length = i; m_data[m_length] = 0; return true; @@ -161,46 +153,32 @@ namespace rexy::cx{ m_data[m_length++] = data[i]; } } - constexpr void append(const_pointer data)noexcept{ - append(data, strlen(data)); - } - constexpr void append(const string& s)noexcept{ - append(s.get(), s.length()); - } - constexpr void append(const rexy::basic_string_view& s)noexcept{ - append(s.get(), s.length()); - } + constexpr void append(const_pointer data)noexcept + {append(data, rexy::strlen(data));} + constexpr void append(const string& s)noexcept + {append(s.get(), s.length());} + constexpr void append(const rexy::basic_string_view& s)noexcept + {append(s.get(), s.length());} + }; + template + string(const Char(&data)[N]) -> string; + + template + struct is_cx_string{ + template + static std::true_type check(cx::string); + static std::false_type check(...); + static constexpr bool value = (decltype(check(std::declval>()))::value && ...); }; - namespace detail{ - template - struct is_cx_string_helper{ - static constexpr bool value = false; - }; - template - struct is_cx_string_helper>{ - static constexpr bool value = true; - }; - template - struct is_cx_string{ - static constexpr bool value = (is_cx_string_helper>::value && ...); - }; - } - - template::value,int> = 0> - constexpr auto operator+(Str1&& l, Str2&& r)noexcept{ - return string_cat_expr(std::forward(l), std::forward(r)); - } - template::value,int> = 0> - constexpr auto operator+(Str1&& l, const char* r)noexcept{ - return string_cat_expr(std::forward(l), rexy::basic_string_view(r)); - } - template::value,int> = 0> - constexpr auto operator+(const char* l, Str1&& r)noexcept{ - return string_cat_expr(rexy::basic_string_view(l), std::forward(r)); - } } +#ifdef __cpp_concepts + #include "../compat/cpp20/cx/string.hpp" +#else //__cpp_concepts + #include "../compat/cpp17/cx/string.hpp" +#endif //__cpp_concepts + #ifdef REXY_CX_HASH_HPP #include "cx_string_hash.hpp" #endif