diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2014-08-11 22:52:18 -0700 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2014-08-25 17:58:12 -0700 |
commit | add7ff74ca25ca2c9cc591abc484f8e6d38b2c39 (patch) | |
tree | c62ef1510966effdf81bec6710125b75783ff512 /src/strings/rstring.cpp | |
parent | 54df2e07fc4cc0bd8557e4152be15353ecf53d0d (diff) | |
download | tmwa-add7ff74ca25ca2c9cc591abc484f8e6d38b2c39.tar.gz tmwa-add7ff74ca25ca2c9cc591abc484f8e6d38b2c39.tar.bz2 tmwa-add7ff74ca25ca2c9cc591abc484f8e6d38b2c39.tar.xz tmwa-add7ff74ca25ca2c9cc591abc484f8e6d38b2c39.zip |
Optimize string literals in refcounted strings
Diffstat (limited to 'src/strings/rstring.cpp')
-rw-r--r-- | src/strings/rstring.cpp | 77 |
1 files changed, 36 insertions, 41 deletions
diff --git a/src/strings/rstring.cpp b/src/strings/rstring.cpp index 3e5a46d..e74d1d5 100644 --- a/src/strings/rstring.cpp +++ b/src/strings/rstring.cpp @@ -36,45 +36,46 @@ namespace tmwa { namespace strings { - static_assert(sizeof(RString) == sizeof(const char *), "RString"); - - uint8_t RString::empty_string_rep[sizeof(Rep) + 1]; - RString::RString() - : owned(reinterpret_cast<Rep *>(&empty_string_rep)) + : u{.begin= ""}, maybe_end(u.begin) + { + } + RString::RString(LString l) + : u{.begin= &*l.begin()}, maybe_end(&*l.end()) { - owned->count++; } RString::RString(const RString& r) - : owned(r.owned) + : u(r.u), maybe_end(r.maybe_end) { - owned->count++; + if (!maybe_end) + u.owned->count++; } RString::RString(RString&& r) - : owned(reinterpret_cast<Rep *>(&empty_string_rep)) + : RString() { - std::swap(owned, r.owned); - r.owned->count++; + *this = std::move(r); } RString& RString::operator = (const RString& r) { // order important for self-assign - r.owned->count++; - // owned can be nullptr from ctors - // TODO do ctors *properly* (requires gcc 4.7 to stay sane) - if (owned && !owned->count--) - ::operator delete(owned); - owned = r.owned; + if (!r.maybe_end) + r.u.owned->count++; + if (!maybe_end && !u.owned->count--) + ::operator delete(u.owned); + u = r.u; + maybe_end = r.maybe_end; return *this; } RString& RString::operator = (RString&& r) { - std::swap(owned, r.owned); + std::swap(u, r.u); + std::swap(maybe_end, r.maybe_end); return *this; } + RString::RString(AString a) - : owned(nullptr) + : RString() { if (RString *r = const_cast<RString *>(a.base())) { @@ -87,41 +88,36 @@ namespace strings } RString::~RString() { - if (owned && !owned->count--) - ::operator delete(owned); - owned = nullptr; + if (!maybe_end && !u.owned->count--) + ::operator delete(u.owned); } RString::RString(const MString& s) - : owned(nullptr) + : RString(s.begin(), s.end()) { - _assign(s.begin(), s.end()); } RString::RString(XPair p) - : owned(nullptr) + : RString(p.begin(), p.end()) { - _assign(p.begin(), p.end()); } RString::RString(const TString& t) - : owned(nullptr) + : RString(XString(t)) { - *this = XString(t); } RString::RString(const SString& s) - : owned(nullptr) + : RString(XString(s)) { - *this = XString(s); } RString::RString(ZString z) - : owned(nullptr) + : RString(XString(z)) { - *this = XString(z); } RString::RString(XString x) - : owned(nullptr) + : RString() { + // long term this stuff will change again const RString *f = x.base(); const char *xb = &*x.begin(); const char *xe = &*x.end(); @@ -130,21 +126,20 @@ namespace strings if (f && xb == fb && xe == fe) *this = *f; else - _assign(x.begin(), x.end()); - } - RString::RString(LString l) - : owned(nullptr) - { - *this = XString(l); + *this = RString(x.begin(), x.end()); } RString::iterator RString::begin() const { - return owned->body; + if (maybe_end) + return u.begin; + return u.owned->body; } RString::iterator RString::end() const { - return owned->body + owned->size; + if (maybe_end) + return maybe_end; + return u.owned->body + u.owned->size; } const RString *RString::base() const { |