diff --git a/include/raii/string_base.hpp b/include/raii/string_base.hpp index 21b0279..66f9251 100644 --- a/include/raii/string_base.hpp +++ b/include/raii/string_base.hpp @@ -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 - constexpr string_cat_expr(T&& l, U&& r): + constexpr string_cat_expr(Left l, Right r): m_l(std::forward(l)), m_r(std::forward(r)){} constexpr string_cat_expr(const string_cat_expr& s): - m_l(s.m_l), - m_r(s.m_r){} + m_l(std::forward(s.m_l)), + m_r(std::forward(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(s.m_l)), + m_r(std::forward(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::value,void>::type* = nullptr> +template::value && std::is_rvalue_reference::value,void>::type* = nullptr> +constexpr auto operator+(const char* left, Right&& right){ + return raii::string_cat_expr::type>(left, std::move(right)); +} +template::value && !std::is_rvalue_reference::value,void>::type* = nullptr> constexpr auto operator+(const char* left, Right&& right){ return raii::string_cat_expr(right))>(left, std::forward(right)); } -template::value,void>::type* = nullptr> + +template::value && std::is_rvalue_reference::value,void>::type* = nullptr> +constexpr auto operator+(Left&& left, const char* right){ + return raii::string_cat_expr::type,const char*>(std::move(left), right); +} +template::value && !std::is_rvalue_reference::value,void>::type* = nullptr> constexpr auto operator+(Left&& left, const char* right){ return raii::string_cat_expr(left)),const char*>(std::forward(left), right); } -template::value&&raii::detail::is_string::value,void>::type* = nullptr> + +template::value && + raii::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 raii::string_cat_expr::type,typename std::remove_reference::type>(std::move(l), std::move(r)); +} +template::value && + raii::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 raii::string_cat_expr(l)),decltype(std::forward(r))>(std::forward(l), std::forward(r)); } +template::value && + raii::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 raii::string_cat_expr::type,decltype(std::forward(r))>(std::move(l), std::forward(r)); +} +template::value && + raii::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 raii::string_cat_expr(l)),typename std::remove_reference::type>(std::forward(l), std::move(r)); +} + template::value&&raii::detail::is_string::value,void>::type* = nullptr> decltype(auto) operator+=(Left& l, Right&& r){ return l = (l + std::forward(r));