Fix c++17 string compat

This commit is contained in:
rexy712 2022-05-21 23:21:31 -07:00
parent d9f44cfeda
commit e5cf445f19
2 changed files with 40 additions and 6 deletions

View File

@ -405,6 +405,9 @@ namespace rexy{
REXY_CPP20_CONSTEXPR pointer release(void)noexcept(noexcept(this->allocate(0))); REXY_CPP20_CONSTEXPR pointer release(void)noexcept(noexcept(this->allocate(0)));
using detail::hasallocator<Allocator>::allocator; using detail::hasallocator<Allocator>::allocator;
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;
}; };
//Like an expression template but not really //Like an expression template but not really
@ -592,11 +595,11 @@ namespace rexy{
#define HAS_MEMFUN_WITH_RET(type, ret, fun, ...) \ #define HAS_MEMFUN_WITH_RET(type, ret, fun, ...) \
template<class T> \ template<class T> \
struct has_##fun##_f{ \ struct has_##fun##_f{ \
std::false_type check(...); \ static std::false_type check(...); \
template<class type> \ template<class type> \
auto check(type* u) -> std::enable_if<std::is_convertible_v<std::declval<type>().fun(__VA_ARGS__),ret>,std::true_type>; \ static auto check(type* u) -> std::enable_if_t<std::is_convertible_v<decltype(std::declval<type>().fun(__VA_ARGS__)),ret>,std::true_type>; \
\ \
static constexpr bool value = decltype(check(std::declval<T*>()))::value; \ static constexpr bool value = decltype(check(std::declval<std::remove_reference_t<T>*>()))::value; \
}; \ }; \
template<class T> \ template<class T> \
static constexpr bool has_##fun##_f_v = has_##fun##_f<T>::value static constexpr bool has_##fun##_f_v = has_##fun##_f<T>::value
@ -604,11 +607,11 @@ namespace rexy{
#define HAS_MEMOP_WITH_RET(type, ret, opname, op, ...) \ #define HAS_MEMOP_WITH_RET(type, ret, opname, op, ...) \
template<class T> \ template<class T> \
struct has_##opname##_f{ \ struct has_##opname##_f{ \
std::false_type check(...); \ static std::false_type check(...); \
template<class type> \ template<class type> \
auto check(type* u) -> std::enable_if<std::is_convertible_v<std::declval<type>().operator op(__VA_ARGS__),ret>,std::true_type>; \ static auto check(type* u) -> std::enable_if_t<std::is_convertible_v<decltype(std::declval<type>().operator op(__VA_ARGS__)),ret>,std::true_type>; \
\ \
static constexpr bool value = decltype(check(std::declval<T*>()))::value; \ static constexpr bool value = decltype(check(std::declval<std::remove_reference_t<T>*>()))::value; \
}; \ }; \
template<class T> \ template<class T> \
static constexpr bool has_##opname##_f_v = has_##opname##_f<T>::value static constexpr bool has_##opname##_f_v = has_##opname##_f<T>::value
@ -629,6 +632,10 @@ namespace rexy{
}; };
template<class T> template<class T>
static constexpr bool is_string_v = is_string<T>::value; static constexpr bool is_string_v = is_string<T>::value;
static_assert(is_string_v<basic_string_view<char>>);
template<class... Ts> template<class... Ts>
struct are_strings{ struct are_strings{
static constexpr bool value = (is_string<Ts>::value && ...); static constexpr bool value = (is_string<Ts>::value && ...);
@ -701,12 +708,14 @@ namespace rexy{
{ {
return string_cat_expr(std::forward<Left>(l), std::forward<Right>(r)); return string_cat_expr(std::forward<Left>(l), std::forward<Right>(r));
} }
//String + char pointer
template<class Right, std::enable_if_t<is_string<Right>::value,int> = 0> template<class Right, std::enable_if_t<is_string<Right>::value,int> = 0>
constexpr auto operator+(typename std::decay_t<Right>::const_pointer left, Right&& right) constexpr auto operator+(typename std::decay_t<Right>::const_pointer left, Right&& right)
noexcept(noexcept(::new (nullptr) string_cat_expr(rexy::basic_string_view(left), std::forward<Right>(right)))) noexcept(noexcept(::new (nullptr) string_cat_expr(rexy::basic_string_view(left), std::forward<Right>(right))))
{ {
return string_cat_expr(rexy::basic_string_view(left), std::forward<Right>(right)); return string_cat_expr(rexy::basic_string_view(left), std::forward<Right>(right));
} }
//Char pointer + string
template<class Left, std::enable_if_t<is_string<Left>::value,int> = 0> template<class Left, std::enable_if_t<is_string<Left>::value,int> = 0>
constexpr auto operator+(Left&& left, typename std::decay_t<Left>::const_pointer right) constexpr auto operator+(Left&& left, typename std::decay_t<Left>::const_pointer right)
noexcept(noexcept(::new (nullptr) string_cat_expr(std::forward<Left>(left), rexy::basic_string_view(right)))) noexcept(noexcept(::new (nullptr) string_cat_expr(std::forward<Left>(left), rexy::basic_string_view(right))))
@ -720,10 +729,26 @@ namespace rexy{
constexpr auto operator+(Left&& left, Right&& right){ constexpr auto operator+(Left&& left, Right&& right){
return string_cat_expr(std::forward<Left>(left), std::forward<Right>(right)); return string_cat_expr(std::forward<Left>(left), std::forward<Right>(right));
} }
//Expr + string
template<class Left, class Right, std::enable_if_t<is_string_expr<Left>::value && is_string<Right>::value,int> = 0> template<class Left, class Right, std::enable_if_t<is_string_expr<Left>::value && is_string<Right>::value,int> = 0>
constexpr auto operator+(Left&& left, Right&& right){ constexpr auto operator+(Left&& left, Right&& right){
return string_cat_expr(std::forward<Left>(left), std::forward<Right>(right)); return string_cat_expr(std::forward<Left>(left), std::forward<Right>(right));
} }
//Expr + expr
template<class Left, class Right, std::enable_if_t<are_string_expr<Left,Right>::value,int> = 0>
constexpr auto operator+(Left&& left, Right&& right){
return string_cat_expr(std::forward<Left>(left), std::forward<Right>(right));
}
//Expr + char pointer
template<class Left, std::enable_if_t<is_string_expr<Left>::value,int> = 0>
constexpr auto operator+(Left&& left, typename std::decay_t<Left>::const_pointer right){
return string_cat_expr(std::forward<Left>(left), rexy::basic_string_view(right));
}
//char pointer + Expr
template<class Right, std::enable_if_t<is_string_expr<Right>::value,int> = 0>
constexpr auto operator+(typename std::decay_t<Right>::const_pointer left, Right&& right){
return string_cat_expr(rexy::basic_string_view(left), std::forward<Right>(right));
}
//String concat assignment //String concat assignment
template<class Left, class Right, std::enable_if_t<are_strings<Left,Right>::value,int> = 0> template<class Left, class Right, std::enable_if_t<are_strings<Left,Right>::value,int> = 0>

View File

@ -336,6 +336,15 @@ namespace rexy{
this->set_short_length(0); this->set_short_length(0);
return retval; return retval;
} }
template<class Char, class Allocator>
constexpr auto basic_string<Char,Allocator>::create_view(void)const noexcept -> basic_string_view<value_type>{
const auto ptr = this->get_pointer();
return basic_string_view<value_type>(ptr, ptr + this->length());
}
template<class Char, class Allocator>
constexpr auto basic_string<Char,Allocator>::create_view(const_iterator start, const_iterator fin)const noexcept -> basic_string_view<value_type>{
return basic_string_view<value_type>(start, fin);
}
template<class Char, class Allocator> template<class Char, class Allocator>
REXY_CPP20_CONSTEXPR basic_string<Char,Allocator>& basic_string<Char,Allocator>::_copy_string(const_pointer s, size_type len) REXY_CPP20_CONSTEXPR basic_string<Char,Allocator>& basic_string<Char,Allocator>::_copy_string(const_pointer s, size_type len)