Fix some issues with rvalue refs in string expressions
This commit is contained in:
parent
cf4485bab9
commit
145a77c3a6
@ -145,9 +145,7 @@ namespace raii{
|
||||
|
||||
string_intermediary& operator=(const string_intermediary& s){
|
||||
string_intermediary tmp(s);
|
||||
std::swap(m_data, tmp.m_data);
|
||||
m_length = tmp.m_length;
|
||||
return *this;
|
||||
return (*this = std::move(tmp));
|
||||
}
|
||||
string_intermediary& operator=(string_intermediary&& s){
|
||||
std::swap(m_data, s.m_data);
|
||||
@ -290,16 +288,15 @@ namespace raii{
|
||||
Right m_r;
|
||||
|
||||
public:
|
||||
template<class T, class U>
|
||||
constexpr string_cat_expr(T&& l, U&& r):
|
||||
constexpr string_cat_expr(Left l, Right r):
|
||||
m_l(std::forward<Left>(l)),
|
||||
m_r(std::forward<Right>(r)){}
|
||||
constexpr string_cat_expr(const string_cat_expr& s):
|
||||
m_l(s.m_l),
|
||||
m_r(s.m_r){}
|
||||
m_l(std::forward<Left>(s.m_l)),
|
||||
m_r(std::forward<Right>(s.m_r)){}
|
||||
constexpr string_cat_expr(string_cat_expr&& s):
|
||||
m_l(s.m_l),
|
||||
m_r(s.m_r){}
|
||||
m_l(std::forward<Left>(s.m_l)),
|
||||
m_r(std::forward<Right>(s.m_r)){}
|
||||
|
||||
constexpr size_t length(void)const{
|
||||
return _llen() + _rlen();
|
||||
@ -360,18 +357,69 @@ bool operator!=(Str1&& left, Str2&& right){
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
template<class Right, typename std::enable_if<raii::detail::is_string<Right>::value,void>::type* = nullptr>
|
||||
template<class Right, typename std::enable_if<raii::detail::is_string<Right>::value && std::is_rvalue_reference<Right&&>::value,void>::type* = nullptr>
|
||||
constexpr auto operator+(const char* left, Right&& right){
|
||||
return raii::string_cat_expr<const char*,typename std::remove_reference<Right>::type>(left, std::move(right));
|
||||
}
|
||||
template<class Right, typename std::enable_if<raii::detail::is_string<Right>::value && !std::is_rvalue_reference<Right&&>::value,void>::type* = nullptr>
|
||||
constexpr auto operator+(const char* left, Right&& right){
|
||||
return raii::string_cat_expr<const char*,decltype(std::forward<Right>(right))>(left, std::forward<Right>(right));
|
||||
}
|
||||
template<class Left, typename std::enable_if<raii::detail::is_string<Left>::value,void>::type* = nullptr>
|
||||
|
||||
template<class Left, typename std::enable_if<raii::detail::is_string<Left>::value && std::is_rvalue_reference<Left&&>::value,void>::type* = nullptr>
|
||||
constexpr auto operator+(Left&& left, const char* right){
|
||||
return raii::string_cat_expr<typename std::remove_reference<Left>::type,const char*>(std::move(left), right);
|
||||
}
|
||||
template<class Left, typename std::enable_if<raii::detail::is_string<Left>::value && !std::is_rvalue_reference<Left&&>::value,void>::type* = nullptr>
|
||||
constexpr auto operator+(Left&& left, const char* right){
|
||||
return raii::string_cat_expr<decltype(std::forward<Left>(left)),const char*>(std::forward<Left>(left), right);
|
||||
}
|
||||
template<class Left, class Right, typename std::enable_if<raii::detail::is_string<Left>::value&&raii::detail::is_string<Right>::value,void>::type* = nullptr>
|
||||
|
||||
template<class Left,
|
||||
class Right,
|
||||
typename std::enable_if<
|
||||
raii::detail::is_string<Left>::value &&
|
||||
raii::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 raii::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<
|
||||
raii::detail::is_string<Left>::value &&
|
||||
raii::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 raii::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<
|
||||
raii::detail::is_string<Left>::value &&
|
||||
raii::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 raii::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<
|
||||
raii::detail::is_string<Left>::value &&
|
||||
raii::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 raii::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<raii::detail::is_string<Left>::value&&raii::detail::is_string<Right>::value,void>::type* = nullptr>
|
||||
decltype(auto) operator+=(Left& l, Right&& r){
|
||||
return l = (l + std::forward<Right>(r));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user