diff options
Diffstat (limited to 'src/include/rc_string.hpp')
-rw-r--r-- | src/include/rc_string.hpp | 116 |
1 files changed, 92 insertions, 24 deletions
diff --git a/src/include/rc_string.hpp b/src/include/rc_string.hpp index 914228c6..0d6ab155 100644 --- a/src/include/rc_string.hpp +++ b/src/include/rc_string.hpp @@ -9,67 +9,135 @@ #include <cstring> #include <ostream> +#include "../common.hpp" class RcString { unsigned int* m_ptr; - unsigned int m_len; public: RcString(): - m_ptr(nullptr), - m_len(0) + m_ptr(nullptr) {} RcString(const char* s, unsigned int len); RcString(const char* s): RcString(s, ::std::strlen(s)) { } - RcString(const ::std::string& s): + explicit RcString(const ::std::string& s): RcString(s.data(), s.size()) { } - RcString(const RcString& x); + static RcString new_interned(const ::std::string& s); + static RcString new_interned(const char* s); + + RcString(const RcString& x): + m_ptr(x.m_ptr) + { + if( m_ptr ) *m_ptr += 1; + } RcString(RcString&& x): - m_ptr(x.m_ptr), - m_len(x.m_len) + m_ptr(x.m_ptr) { x.m_ptr = nullptr; - x.m_len = 0; } ~RcString(); RcString& operator=(const RcString& x) { - if( !(&x != this) ) throw ""; - - this->~RcString(); - new (this) RcString(x); - + if( &x != this ) + { + this->~RcString(); + m_ptr = x.m_ptr; + if( m_ptr ) *m_ptr += 1; + } return *this; } RcString& operator=(RcString&& x) { - if( !(&x != this) ) throw ""; - - this->~RcString(); - new (this) RcString( ::std::move(x) ); + if( &x != this ) + { + this->~RcString(); + m_ptr = x.m_ptr; + x.m_ptr = nullptr; + } return *this; } + const char* begin() const { return c_str(); } + const char* end() const { return c_str() + size(); } + size_t size() const { return m_ptr ? m_ptr[1] : 0; } const char* c_str() const { - if( m_len > 0 ) { - return reinterpret_cast<const char*>(m_ptr + 1); + if( m_ptr ) + { + return reinterpret_cast<const char*>(m_ptr + 2); } - else { + else + { return ""; } } - bool operator==(const RcString& s) const { return *this == s.c_str(); } - bool operator==(const char* s) const; - friend ::std::ostream& operator<<(::std::ostream& os, const RcString& x) { - return os << x.c_str(); + + char back() const { + assert(size() > 0 ); + return *(c_str() + size() - 1); + } + + Ordering ord(const char* s, size_t l) const; + Ordering ord(const RcString& s) const { + if( m_ptr == s.m_ptr ) + return OrdEqual; + return ord(s.c_str(), s.size()); + } + bool operator==(const RcString& s) const { + if(s.size() != this->size()) + return false; + return this->ord(s) == OrdEqual; + } + bool operator!=(const RcString& s) const { + if(s.size() != this->size()) + return true; + return this->ord(s) != OrdEqual; + } + bool operator<(const RcString& s) const { return this->ord(s) == OrdLess; } + bool operator>(const RcString& s) const { return this->ord(s) == OrdGreater; } + + Ordering ord(const std::string& s) const { return ord(s.data(), s.size()); } + bool operator==(const std::string& s) const { return this->ord(s) == OrdEqual; } + bool operator!=(const std::string& s) const { return this->ord(s) != OrdEqual; } + bool operator<(const std::string& s) const { return this->ord(s) == OrdLess; } + bool operator>(const std::string& s) const { return this->ord(s) == OrdGreater; } + + Ordering ord(const char* s) const; + bool operator==(const char* s) const { return this->ord(s) == OrdEqual; } + bool operator!=(const char* s) const { return this->ord(s) != OrdEqual; } + + friend ::std::ostream& operator<<(::std::ostream& os, const RcString& x); + + friend bool operator==(const char* a, const RcString& b) { + return b == a; + } + friend bool operator!=(const char* a, const RcString& b) { + return b != a; + } + + int compare(size_t o, size_t l, const char* s) const { + assert(o <= this->size()); + return memcmp(this->c_str() + o, s, l); } }; + +namespace std { + static inline bool operator==(const string& a, const ::RcString& b) { + return b == a; + } + static inline bool operator!=(const string& a, const ::RcString& b) { + return b != a; + } + template<> struct hash<RcString> + { + size_t operator()(const RcString& s) const noexcept; + }; +} |