diff --git a/include/rexy/steal.hpp b/include/rexy/steal.hpp index 76a763e..69d0031 100644 --- a/include/rexy/steal.hpp +++ b/include/rexy/steal.hpp @@ -31,7 +31,7 @@ namespace rexy{ public: template - steal(U&& u): + constexpr steal(U&& u): m_val(std::forward(u)){} steal(const steal&) = delete; @@ -39,10 +39,10 @@ namespace rexy{ steal& operator=(const steal&) = delete; steal& operator=(steal&&) = delete; - T&& value(void){ + constexpr T&& value(void){ return std::forward(m_val); } - const T& value(void)const{ + constexpr const T& value(void)const{ return m_val; } }; diff --git a/include/rexy/string_base.hpp b/include/rexy/string_base.hpp index 6c1c6d0..d892fa5 100644 --- a/include/rexy/string_base.hpp +++ b/include/rexy/string_base.hpp @@ -47,7 +47,7 @@ namespace rexy{ constexpr string_base(char* data, size_t len, size_t cap): m_length(len), m_cap(cap), m_data(data){} //Copy ctor (do nothing) - string_base(const string_base&){} + constexpr string_base(const string_base&){} ~string_base(void) = default; public: @@ -63,7 +63,7 @@ namespace rexy{ constexpr operator char*(void){return m_data;} constexpr operator const char*(void)const{return m_data;} //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); const char& operator[](size_t i)const; @@ -78,12 +78,12 @@ namespace rexy{ using allocator_type = Allocator; public: - string_intermediary(void) = default; - string_intermediary(rexy::steal data, size_t len); - string_intermediary(rexy::steal data, size_t len, size_t cap); + constexpr string_intermediary(void); + constexpr string_intermediary(rexy::steal data, size_t len); + constexpr string_intermediary(rexy::steal data, size_t len, size_t cap); [[deprecated]] string_intermediary(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(rexy::steal); string_intermediary(size_t len); @@ -91,7 +91,7 @@ namespace rexy{ //normal copy and move ctors string_intermediary(const string_intermediary& b); - string_intermediary(string_intermediary&& s); + constexpr string_intermediary(string_intermediary&& s); string_intermediary(const string_base& b); @@ -137,6 +137,20 @@ namespace rexy{ constexpr const Left& left(void)const; constexpr const Right& right(void)const; }; + template + string_cat_expr(Left&, Right&) -> string_cat_expr; + template + string_cat_expr(const Left&, const Right&) -> string_cat_expr; + template + string_cat_expr(Left&&,Right&&) -> string_cat_expr; + template + string_cat_expr(Left&,Right&&) -> string_cat_expr; + template + string_cat_expr(const Left&,Right&&) -> string_cat_expr; + template + string_cat_expr(Left&&,Right&) -> string_cat_expr; + template + string_cat_expr(Left&&,const Right&) -> string_cat_expr; class static_string : public string_base { @@ -155,11 +169,11 @@ namespace rexy{ namespace detail{ - std::true_type is_string_helper(string_expr); + std::true_type is_string_helper(string_expr*); std::false_type is_string_helper(...); template struct is_string{ - static constexpr bool value = std::is_same()))>::value; + static constexpr bool value = std::is_same::type*>()))>::value; }; std::true_type is_string_base(string_base*); std::false_type is_string_base(...); @@ -167,13 +181,6 @@ namespace rexy{ struct is_concrete_string{ static constexpr bool value = std::is_same::type*>()))>::value; }; - template - std::true_type is_tuple_helper(std::tuple); - std::false_type is_tuple_helper(...); - template - struct is_tuple{ - static constexpr bool value = std::is_same()))>::value; - }; //check for member function 'length' template @@ -200,6 +207,41 @@ namespace rexy{ void operator()(const string_base& str); }; } + template::value && + detail::is_concrete_string::value,int> = 0> + bool operator==(Str1&& left, Str2&& right){ + return left.valid() && right.valid() && left.length() == right.length() && !strcmp(left.get(), right.get()); + } + template::value && + detail::is_concrete_string::value,int> = 0> + bool operator!=(Str1&& left, Str2&& right){ + return !(left == right); + } + + template::value && + detail::is_string::value,int> = 0> + constexpr auto operator+(Left&& l, Right&& r){ + return string_cat_expr(std::forward(l), std::forward(r)); + } + template::value,int> = 0> + constexpr auto operator+(const char* left, Right&& right){ + return string_cat_expr(rexy::static_string(left), std::forward(right)); + } + + template::value,int> = 0> + constexpr auto operator+(Left&& left, const char* right){ + return rexy::string_cat_expr(std::forward(left), rexy::static_string(right)); + } + + template::value && + detail::is_string::value,int> = 0> + decltype(auto) operator+=(Left& l, Right&& r){ + return l = (l + std::forward(r)); + } + template::value,int> = 0> + decltype(auto) operator+=(Left& l, const char* r){ + return l = (l + r); + } } #include @@ -209,86 +251,6 @@ namespace{ return rexy::static_string(str, len); } } -template::value&&rexy::detail::is_concrete_string::value,void>::type* = nullptr> -bool operator==(Str1&& left, Str2&& right){ - return left && right && left.length() == right.length() && !strcmp(left.get(), right.get()); -} -template::value&&rexy::detail::is_concrete_string::value,void>::type* = nullptr> -bool operator!=(Str1&& left, Str2&& right){ - return !(left == right); -} - -template::value && std::is_rvalue_reference::value,void>::type* = nullptr> -constexpr auto operator+(const char* left, Right&& right){ - return rexy::string_cat_expr::type>(rexy::static_string(left), std::move(right)); -} -template::value && !std::is_rvalue_reference::value,void>::type* = nullptr> -constexpr auto operator+(const char* left, Right&& right){ - return rexy::string_cat_expr(right))>(rexy::static_string(left), std::forward(right)); -} - -template::value && std::is_rvalue_reference::value,void>::type* = nullptr> -constexpr auto operator+(Left&& left, const char* right){ - return rexy::string_cat_expr::type,rexy::static_string>(std::move(left), rexy::static_string(right)); -} -template::value && !std::is_rvalue_reference::value,void>::type* = nullptr> -constexpr auto operator+(Left&& left, const char* right){ - return rexy::string_cat_expr(left)),rexy::static_string>(std::forward(left), rexy::static_string(right)); -} - -template::value && - rexy::detail::is_string::value && - std::is_rvalue_reference::value && - std::is_rvalue_reference::value, - void>::type* = nullptr> -constexpr auto operator+(Left&& l, Right&& r){ - return rexy::string_cat_expr::type,typename std::remove_reference::type>(std::move(l), std::move(r)); -} -template::value && - rexy::detail::is_string::value && - !std::is_rvalue_reference::value && - !std::is_rvalue_reference::value, - void>::type* = nullptr> -constexpr auto operator+(Left&& l, Right&& r){ - return rexy::string_cat_expr(l)),decltype(std::forward(r))>(std::forward(l), std::forward(r)); -} -template::value && - rexy::detail::is_string::value && - std::is_rvalue_reference::value && - !std::is_rvalue_reference::value, - void>::type* = nullptr> -constexpr auto operator+(Left&& l, Right&& r){ - return rexy::string_cat_expr::type,decltype(std::forward(r))>(std::move(l), std::forward(r)); -} -template::value && - rexy::detail::is_string::value && - !std::is_rvalue_reference::value && - std::is_rvalue_reference::value, - void>::type* = nullptr> -constexpr auto operator+(Left&& l, Right&& r){ - return rexy::string_cat_expr(l)),typename std::remove_reference::type>(std::forward(l), std::move(r)); -} - -template::value&&rexy::detail::is_string::value,void>::type* = nullptr> -decltype(auto) operator+=(Left& l, Right&& r){ - return l = (l + std::forward(r)); -} -template::value,void>::type* = nullptr> -decltype(auto) operator+=(Left& l, const char* r){ - return l = (l + r); -} #ifdef REXY_BINARY_HPP #include diff --git a/include/rexy/string_base.tpp b/include/rexy/string_base.tpp index fce2717..7f9147f 100644 --- a/include/rexy/string_base.tpp +++ b/include/rexy/string_base.tpp @@ -26,17 +26,28 @@ #include //max namespace rexy{ + namespace{ + template + constexpr T cx_exchange(T& t, U&& u){ + T old = std::move(t); + t = std::forward(u); + return old; + } + } + + template + constexpr string_intermediary::string_intermediary(void){} template string_intermediary::string_intermediary(char* data, size_t len): string_base(data, len){} template - string_intermediary::string_intermediary(rexy::steal data, size_t len): + constexpr string_intermediary::string_intermediary(rexy::steal data, size_t len): string_base(data.value(), len){} template - string_intermediary::string_intermediary(char* data, size_t len, size_t cap): + constexpr string_intermediary::string_intermediary(char* data, size_t len, size_t cap): string_base(data, len, cap){} template - string_intermediary::string_intermediary(rexy::steal data, size_t len, size_t cap): + constexpr string_intermediary::string_intermediary(rexy::steal data, size_t len, size_t cap): string_base(data.value(), len, cap){} template string_intermediary::string_intermediary(const char* data, size_t len): @@ -78,8 +89,8 @@ namespace rexy{ string_intermediary::string_intermediary(const string_intermediary& b): string_base(reinterpret_cast(b.m_length ? Allocator::copy(b.m_data, b.m_length+1) : nullptr), b.m_length, b.m_cap){} template - string_intermediary::string_intermediary(string_intermediary&& s): - string_base(std::exchange(s.m_data, nullptr), s.m_length, s.m_cap){} + constexpr string_intermediary::string_intermediary(string_intermediary&& s): + string_base(cx_exchange(s.m_data, nullptr), s.m_length, s.m_cap){} template string_intermediary::string_intermediary(const string_base& b): @@ -204,8 +215,8 @@ namespace rexy{ m_r(std::forward(r)){} template constexpr string_cat_expr::string_cat_expr(const string_cat_expr& s): - m_l(std::forward(s.m_l)), - m_r(std::forward(s.m_r)){} + m_l(s.m_l), + m_r(s.m_r){} template constexpr string_cat_expr::string_cat_expr(string_cat_expr&& s): m_l(std::forward(s.m_l)),