summaryrefslogtreecommitdiff
path: root/src/include/rc_string.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/rc_string.hpp')
-rw-r--r--src/include/rc_string.hpp116
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;
+ };
+}