Improve string constexpr-ness and cleanup addition operators
This commit is contained in:
parent
72f8c0d592
commit
a280642cac
@ -31,7 +31,7 @@ namespace rexy{
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
template<class U>
|
template<class U>
|
||||||
steal(U&& u):
|
constexpr steal(U&& u):
|
||||||
m_val(std::forward<U>(u)){}
|
m_val(std::forward<U>(u)){}
|
||||||
|
|
||||||
steal(const steal&) = delete;
|
steal(const steal&) = delete;
|
||||||
@ -39,10 +39,10 @@ namespace rexy{
|
|||||||
steal& operator=(const steal&) = delete;
|
steal& operator=(const steal&) = delete;
|
||||||
steal& operator=(steal&&) = delete;
|
steal& operator=(steal&&) = delete;
|
||||||
|
|
||||||
T&& value(void){
|
constexpr T&& value(void){
|
||||||
return std::forward<T>(m_val);
|
return std::forward<T>(m_val);
|
||||||
}
|
}
|
||||||
const T& value(void)const{
|
constexpr const T& value(void)const{
|
||||||
return m_val;
|
return m_val;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -47,7 +47,7 @@ namespace rexy{
|
|||||||
constexpr string_base(char* data, size_t len, size_t cap):
|
constexpr string_base(char* data, size_t len, size_t cap):
|
||||||
m_length(len), m_cap(cap), m_data(data){}
|
m_length(len), m_cap(cap), m_data(data){}
|
||||||
//Copy ctor (do nothing)
|
//Copy ctor (do nothing)
|
||||||
string_base(const string_base&){}
|
constexpr string_base(const string_base&){}
|
||||||
~string_base(void) = default;
|
~string_base(void) = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -63,7 +63,7 @@ namespace rexy{
|
|||||||
constexpr operator char*(void){return m_data;}
|
constexpr operator char*(void){return m_data;}
|
||||||
constexpr operator const char*(void)const{return m_data;}
|
constexpr operator const char*(void)const{return m_data;}
|
||||||
//true if m_data is not null
|
//true if m_data is not null
|
||||||
constexpr operator bool(void)const{return m_data;}
|
constexpr bool valid(void)const{return m_data;}
|
||||||
|
|
||||||
char& operator[](size_t i);
|
char& operator[](size_t i);
|
||||||
const char& operator[](size_t i)const;
|
const char& operator[](size_t i)const;
|
||||||
@ -78,12 +78,12 @@ namespace rexy{
|
|||||||
using allocator_type = Allocator;
|
using allocator_type = Allocator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
string_intermediary(void) = default;
|
constexpr string_intermediary(void);
|
||||||
string_intermediary(rexy::steal<char*> data, size_t len);
|
constexpr string_intermediary(rexy::steal<char*> data, size_t len);
|
||||||
string_intermediary(rexy::steal<char*> data, size_t len, size_t cap);
|
constexpr string_intermediary(rexy::steal<char*> data, size_t len, size_t cap);
|
||||||
[[deprecated]] string_intermediary(char* data, size_t len);
|
[[deprecated]] string_intermediary(char* data, size_t len);
|
||||||
string_intermediary(const char* data, size_t len);
|
string_intermediary(const char* data, size_t len);
|
||||||
[[deprecated]] string_intermediary(char* data, size_t len, size_t cap);
|
[[deprecated]] constexpr string_intermediary(char* data, size_t len, size_t cap);
|
||||||
string_intermediary(const char* data);
|
string_intermediary(const char* data);
|
||||||
string_intermediary(rexy::steal<char*>);
|
string_intermediary(rexy::steal<char*>);
|
||||||
string_intermediary(size_t len);
|
string_intermediary(size_t len);
|
||||||
@ -91,7 +91,7 @@ namespace rexy{
|
|||||||
|
|
||||||
//normal copy and move ctors
|
//normal copy and move ctors
|
||||||
string_intermediary(const string_intermediary& b);
|
string_intermediary(const string_intermediary& b);
|
||||||
string_intermediary(string_intermediary&& s);
|
constexpr string_intermediary(string_intermediary&& s);
|
||||||
|
|
||||||
string_intermediary(const string_base& b);
|
string_intermediary(const string_base& b);
|
||||||
|
|
||||||
@ -137,6 +137,20 @@ namespace rexy{
|
|||||||
constexpr const Left& left(void)const;
|
constexpr const Left& left(void)const;
|
||||||
constexpr const Right& right(void)const;
|
constexpr const Right& right(void)const;
|
||||||
};
|
};
|
||||||
|
template<class Left, class Right>
|
||||||
|
string_cat_expr(Left&, Right&) -> string_cat_expr<Left&,Right&>;
|
||||||
|
template<class Left, class Right>
|
||||||
|
string_cat_expr(const Left&, const Right&) -> string_cat_expr<const Left&,const Right&>;
|
||||||
|
template<class Left, class Right>
|
||||||
|
string_cat_expr(Left&&,Right&&) -> string_cat_expr<Left,Right>;
|
||||||
|
template<class Left, class Right>
|
||||||
|
string_cat_expr(Left&,Right&&) -> string_cat_expr<Left&,Right>;
|
||||||
|
template<class Left, class Right>
|
||||||
|
string_cat_expr(const Left&,Right&&) -> string_cat_expr<const Left&,Right>;
|
||||||
|
template<class Left, class Right>
|
||||||
|
string_cat_expr(Left&&,Right&) -> string_cat_expr<Left,Right&>;
|
||||||
|
template<class Left, class Right>
|
||||||
|
string_cat_expr(Left&&,const Right&) -> string_cat_expr<Left,const Right&>;
|
||||||
|
|
||||||
class static_string : public string_base
|
class static_string : public string_base
|
||||||
{
|
{
|
||||||
@ -155,11 +169,11 @@ namespace rexy{
|
|||||||
|
|
||||||
|
|
||||||
namespace detail{
|
namespace detail{
|
||||||
std::true_type is_string_helper(string_expr);
|
std::true_type is_string_helper(string_expr*);
|
||||||
std::false_type is_string_helper(...);
|
std::false_type is_string_helper(...);
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_string{
|
struct is_string{
|
||||||
static constexpr bool value = std::is_same<std::true_type,decltype(is_string_helper(std::declval<T>()))>::value;
|
static constexpr bool value = std::is_same<std::true_type,decltype(is_string_helper(std::declval<typename std::decay<T>::type*>()))>::value;
|
||||||
};
|
};
|
||||||
std::true_type is_string_base(string_base*);
|
std::true_type is_string_base(string_base*);
|
||||||
std::false_type is_string_base(...);
|
std::false_type is_string_base(...);
|
||||||
@ -167,13 +181,6 @@ namespace rexy{
|
|||||||
struct is_concrete_string{
|
struct is_concrete_string{
|
||||||
static constexpr bool value = std::is_same<std::true_type,decltype(is_string_base(std::declval<typename std::decay<T>::type*>()))>::value;
|
static constexpr bool value = std::is_same<std::true_type,decltype(is_string_base(std::declval<typename std::decay<T>::type*>()))>::value;
|
||||||
};
|
};
|
||||||
template<class... Args>
|
|
||||||
std::true_type is_tuple_helper(std::tuple<Args...>);
|
|
||||||
std::false_type is_tuple_helper(...);
|
|
||||||
template<class T>
|
|
||||||
struct is_tuple{
|
|
||||||
static constexpr bool value = std::is_same<std::true_type,decltype(is_tuple_helper(std::declval<T>()))>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
//check for member function 'length'
|
//check for member function 'length'
|
||||||
template<class T>
|
template<class T>
|
||||||
@ -200,6 +207,41 @@ namespace rexy{
|
|||||||
void operator()(const string_base& str);
|
void operator()(const string_base& str);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
template<class Str1, class Str2, std::enable_if_t<detail::is_concrete_string<Str1>::value &&
|
||||||
|
detail::is_concrete_string<Str2>::value,int> = 0>
|
||||||
|
bool operator==(Str1&& left, Str2&& right){
|
||||||
|
return left.valid() && right.valid() && left.length() == right.length() && !strcmp(left.get(), right.get());
|
||||||
|
}
|
||||||
|
template<class Str1, class Str2, std::enable_if_t<detail::is_concrete_string<Str1>::value &&
|
||||||
|
detail::is_concrete_string<Str2>::value,int> = 0>
|
||||||
|
bool operator!=(Str1&& left, Str2&& right){
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Left, class Right, std::enable_if_t<detail::is_string<Left>::value &&
|
||||||
|
detail::is_string<Right>::value,int> = 0>
|
||||||
|
constexpr auto operator+(Left&& l, Right&& r){
|
||||||
|
return string_cat_expr(std::forward<Left>(l), std::forward<Right>(r));
|
||||||
|
}
|
||||||
|
template<class Right, std::enable_if_t<detail::is_string<Right>::value,int> = 0>
|
||||||
|
constexpr auto operator+(const char* left, Right&& right){
|
||||||
|
return string_cat_expr(rexy::static_string(left), std::forward<Right>(right));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Left, std::enable_if_t<detail::is_string<Left>::value,int> = 0>
|
||||||
|
constexpr auto operator+(Left&& left, const char* right){
|
||||||
|
return rexy::string_cat_expr(std::forward<Left>(left), rexy::static_string(right));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Left, class Right, std::enable_if_t<detail::is_string<Left>::value &&
|
||||||
|
detail::is_string<Right>::value,int> = 0>
|
||||||
|
decltype(auto) operator+=(Left& l, Right&& r){
|
||||||
|
return l = (l + std::forward<Right>(r));
|
||||||
|
}
|
||||||
|
template<class Left, std::enable_if_t<detail::is_string<Left>::value,int> = 0>
|
||||||
|
decltype(auto) operator+=(Left& l, const char* r){
|
||||||
|
return l = (l + r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <rexy/string_base.tpp>
|
#include <rexy/string_base.tpp>
|
||||||
@ -209,86 +251,6 @@ namespace{
|
|||||||
return rexy::static_string(str, len);
|
return rexy::static_string(str, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<class Str1, class Str2, typename std::enable_if<rexy::detail::is_concrete_string<Str1>::value&&rexy::detail::is_concrete_string<Str2>::value,void>::type* = nullptr>
|
|
||||||
bool operator==(Str1&& left, Str2&& right){
|
|
||||||
return left && right && left.length() == right.length() && !strcmp(left.get(), right.get());
|
|
||||||
}
|
|
||||||
template<class Str1, class Str2, typename std::enable_if<rexy::detail::is_concrete_string<Str1>::value&&rexy::detail::is_concrete_string<Str2>::value,void>::type* = nullptr>
|
|
||||||
bool operator!=(Str1&& left, Str2&& right){
|
|
||||||
return !(left == right);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Right, typename std::enable_if<rexy::detail::is_string<Right>::value && std::is_rvalue_reference<Right&&>::value,void>::type* = nullptr>
|
|
||||||
constexpr auto operator+(const char* left, Right&& right){
|
|
||||||
return rexy::string_cat_expr<rexy::static_string,typename std::remove_reference<Right>::type>(rexy::static_string(left), std::move(right));
|
|
||||||
}
|
|
||||||
template<class Right, typename std::enable_if<rexy::detail::is_string<Right>::value && !std::is_rvalue_reference<Right&&>::value,void>::type* = nullptr>
|
|
||||||
constexpr auto operator+(const char* left, Right&& right){
|
|
||||||
return rexy::string_cat_expr<rexy::static_string,decltype(std::forward<Right>(right))>(rexy::static_string(left), std::forward<Right>(right));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Left, typename std::enable_if<rexy::detail::is_string<Left>::value && std::is_rvalue_reference<Left&&>::value,void>::type* = nullptr>
|
|
||||||
constexpr auto operator+(Left&& left, const char* right){
|
|
||||||
return rexy::string_cat_expr<typename std::remove_reference<Left>::type,rexy::static_string>(std::move(left), rexy::static_string(right));
|
|
||||||
}
|
|
||||||
template<class Left, typename std::enable_if<rexy::detail::is_string<Left>::value && !std::is_rvalue_reference<Left&&>::value,void>::type* = nullptr>
|
|
||||||
constexpr auto operator+(Left&& left, const char* right){
|
|
||||||
return rexy::string_cat_expr<decltype(std::forward<Left>(left)),rexy::static_string>(std::forward<Left>(left), rexy::static_string(right));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Left,
|
|
||||||
class Right,
|
|
||||||
typename std::enable_if<
|
|
||||||
rexy::detail::is_string<Left>::value &&
|
|
||||||
rexy::detail::is_string<Right>::value &&
|
|
||||||
std::is_rvalue_reference<Left&&>::value &&
|
|
||||||
std::is_rvalue_reference<Right&&>::value,
|
|
||||||
void>::type* = nullptr>
|
|
||||||
constexpr auto operator+(Left&& l, Right&& r){
|
|
||||||
return rexy::string_cat_expr<typename std::remove_reference<Left>::type,typename std::remove_reference<Right>::type>(std::move(l), std::move(r));
|
|
||||||
}
|
|
||||||
template<class Left,
|
|
||||||
class Right,
|
|
||||||
typename std::enable_if<
|
|
||||||
rexy::detail::is_string<Left>::value &&
|
|
||||||
rexy::detail::is_string<Right>::value &&
|
|
||||||
!std::is_rvalue_reference<Left&&>::value &&
|
|
||||||
!std::is_rvalue_reference<Right&&>::value,
|
|
||||||
void>::type* = nullptr>
|
|
||||||
constexpr auto operator+(Left&& l, Right&& r){
|
|
||||||
return rexy::string_cat_expr<decltype(std::forward<Left>(l)),decltype(std::forward<Right>(r))>(std::forward<Left>(l), std::forward<Right>(r));
|
|
||||||
}
|
|
||||||
template<class Left,
|
|
||||||
class Right,
|
|
||||||
typename std::enable_if<
|
|
||||||
rexy::detail::is_string<Left>::value &&
|
|
||||||
rexy::detail::is_string<Right>::value &&
|
|
||||||
std::is_rvalue_reference<Left&&>::value &&
|
|
||||||
!std::is_rvalue_reference<Right&&>::value,
|
|
||||||
void>::type* = nullptr>
|
|
||||||
constexpr auto operator+(Left&& l, Right&& r){
|
|
||||||
return rexy::string_cat_expr<typename std::remove_reference<Left>::type,decltype(std::forward<Right>(r))>(std::move(l), std::forward<Right>(r));
|
|
||||||
}
|
|
||||||
template<class Left,
|
|
||||||
class Right,
|
|
||||||
typename std::enable_if<
|
|
||||||
rexy::detail::is_string<Left>::value &&
|
|
||||||
rexy::detail::is_string<Right>::value &&
|
|
||||||
!std::is_rvalue_reference<Left&&>::value &&
|
|
||||||
std::is_rvalue_reference<Right&&>::value,
|
|
||||||
void>::type* = nullptr>
|
|
||||||
constexpr auto operator+(Left&& l, Right&& r){
|
|
||||||
return rexy::string_cat_expr<decltype(std::forward<Left>(l)),typename std::remove_reference<Right>::type>(std::forward<Left>(l), std::move(r));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Left, class Right, typename std::enable_if<rexy::detail::is_string<Left>::value&&rexy::detail::is_string<Right>::value,void>::type* = nullptr>
|
|
||||||
decltype(auto) operator+=(Left& l, Right&& r){
|
|
||||||
return l = (l + std::forward<Right>(r));
|
|
||||||
}
|
|
||||||
template<class Left, typename std::enable_if<rexy::detail::is_string<Left>::value,void>::type* = nullptr>
|
|
||||||
decltype(auto) operator+=(Left& l, const char* r){
|
|
||||||
return l = (l + r);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef REXY_BINARY_HPP
|
#ifdef REXY_BINARY_HPP
|
||||||
#include <rexy/detail/binary_string_conv.hpp>
|
#include <rexy/detail/binary_string_conv.hpp>
|
||||||
|
|||||||
@ -26,17 +26,28 @@
|
|||||||
#include <rexy/detail/util.hpp> //max
|
#include <rexy/detail/util.hpp> //max
|
||||||
|
|
||||||
namespace rexy{
|
namespace rexy{
|
||||||
|
namespace{
|
||||||
|
template<class T, class U = T>
|
||||||
|
constexpr T cx_exchange(T& t, U&& u){
|
||||||
|
T old = std::move(t);
|
||||||
|
t = std::forward<U>(u);
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Allocator>
|
||||||
|
constexpr string_intermediary<Allocator>::string_intermediary(void){}
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
string_intermediary<Allocator>::string_intermediary(char* data, size_t len):
|
string_intermediary<Allocator>::string_intermediary(char* data, size_t len):
|
||||||
string_base(data, len){}
|
string_base(data, len){}
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
string_intermediary<Allocator>::string_intermediary(rexy::steal<char*> data, size_t len):
|
constexpr string_intermediary<Allocator>::string_intermediary(rexy::steal<char*> data, size_t len):
|
||||||
string_base(data.value(), len){}
|
string_base(data.value(), len){}
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
string_intermediary<Allocator>::string_intermediary(char* data, size_t len, size_t cap):
|
constexpr string_intermediary<Allocator>::string_intermediary(char* data, size_t len, size_t cap):
|
||||||
string_base(data, len, cap){}
|
string_base(data, len, cap){}
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
string_intermediary<Allocator>::string_intermediary(rexy::steal<char*> data, size_t len, size_t cap):
|
constexpr string_intermediary<Allocator>::string_intermediary(rexy::steal<char*> data, size_t len, size_t cap):
|
||||||
string_base(data.value(), len, cap){}
|
string_base(data.value(), len, cap){}
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
string_intermediary<Allocator>::string_intermediary(const char* data, size_t len):
|
string_intermediary<Allocator>::string_intermediary(const char* data, size_t len):
|
||||||
@ -78,8 +89,8 @@ namespace rexy{
|
|||||||
string_intermediary<Allocator>::string_intermediary(const string_intermediary& b):
|
string_intermediary<Allocator>::string_intermediary(const string_intermediary& b):
|
||||||
string_base(reinterpret_cast<char*>(b.m_length ? Allocator::copy(b.m_data, b.m_length+1) : nullptr), b.m_length, b.m_cap){}
|
string_base(reinterpret_cast<char*>(b.m_length ? Allocator::copy(b.m_data, b.m_length+1) : nullptr), b.m_length, b.m_cap){}
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
string_intermediary<Allocator>::string_intermediary(string_intermediary&& s):
|
constexpr string_intermediary<Allocator>::string_intermediary(string_intermediary&& s):
|
||||||
string_base(std::exchange(s.m_data, nullptr), s.m_length, s.m_cap){}
|
string_base(cx_exchange(s.m_data, nullptr), s.m_length, s.m_cap){}
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
string_intermediary<Allocator>::string_intermediary(const string_base& b):
|
string_intermediary<Allocator>::string_intermediary(const string_base& b):
|
||||||
@ -204,8 +215,8 @@ namespace rexy{
|
|||||||
m_r(std::forward<U>(r)){}
|
m_r(std::forward<U>(r)){}
|
||||||
template<class Left, class Right>
|
template<class Left, class Right>
|
||||||
constexpr string_cat_expr<Left,Right>::string_cat_expr(const string_cat_expr& s):
|
constexpr string_cat_expr<Left,Right>::string_cat_expr(const string_cat_expr& s):
|
||||||
m_l(std::forward<Left>(s.m_l)),
|
m_l(s.m_l),
|
||||||
m_r(std::forward<Right>(s.m_r)){}
|
m_r(s.m_r){}
|
||||||
template<class Left, class Right>
|
template<class Left, class Right>
|
||||||
constexpr string_cat_expr<Left,Right>::string_cat_expr(string_cat_expr&& s):
|
constexpr string_cat_expr<Left,Right>::string_cat_expr(string_cat_expr&& s):
|
||||||
m_l(std::forward<Left>(s.m_l)),
|
m_l(std::forward<Left>(s.m_l)),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user