diff options
Diffstat (limited to 'src/include/rc_string.hpp')
-rw-r--r-- | src/include/rc_string.hpp | 81 |
1 files changed, 64 insertions, 17 deletions
diff --git a/src/include/rc_string.hpp b/src/include/rc_string.hpp index eec47d80..94b6d9e7 100644 --- a/src/include/rc_string.hpp +++ b/src/include/rc_string.hpp @@ -9,38 +9,37 @@ #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()) { } + static RcString new_interned(const ::std::string& s); + //static new_interned(const char* s); + RcString(const RcString& x): - m_ptr(x.m_ptr), - m_len(x.m_len) + 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(); @@ -51,7 +50,6 @@ public: { this->~RcString(); m_ptr = x.m_ptr; - m_len = x.m_len; if( m_ptr ) *m_ptr += 1; } return *this; @@ -62,27 +60,76 @@ public: { this->~RcString(); m_ptr = x.m_ptr; - m_len = x.m_len; x.m_ptr = nullptr; - x.m_len = 0; } 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 ) + if( m_ptr ) { - return reinterpret_cast<const char*>(m_ptr + 1); + return reinterpret_cast<const char*>(m_ptr + 2); } else { return ""; } } - bool operator==(const RcString& s) const { return *this == s.c_str(); } + + char back() const { + assert(size() > 0 ); + return *(c_str() + size() - 1); + } + + Ordering ord(const RcString& s) const; + 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; + 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; } bool operator==(const char* s) const; - friend ::std::ostream& operator<<(::std::ostream& os, const RcString& x) { - return os << x.c_str(); + bool operator!=(const char* s) const { return !(*this == s); } + 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; + }; +} |