diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2014-01-19 21:46:02 -0800 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2014-01-20 14:03:52 -0800 |
commit | 9c1799033d0c17fbefb52a9b2695922f5a715133 (patch) | |
tree | f2859d02f87081a9166e3253c4e7c4973b82fcea /src | |
parent | b9ac1c6033a0b32ca9984f23223d9fc167415b10 (diff) | |
download | tmwa-9c1799033d0c17fbefb52a9b2695922f5a715133.tar.gz tmwa-9c1799033d0c17fbefb52a9b2695922f5a715133.tar.bz2 tmwa-9c1799033d0c17fbefb52a9b2695922f5a715133.tar.xz tmwa-9c1799033d0c17fbefb52a9b2695922f5a715133.zip |
Implement FString from scratch instead of hackishly
Diffstat (limited to 'src')
-rw-r--r-- | src/strings/fstring.cpp | 52 | ||||
-rw-r--r-- | src/strings/fstring.hpp | 22 | ||||
-rw-r--r-- | src/strings/fstring.py | 19 | ||||
-rw-r--r-- | src/strings/fstring.tcc | 20 |
4 files changed, 94 insertions, 19 deletions
diff --git a/src/strings/fstring.cpp b/src/strings/fstring.cpp index 32d19fe..97ef4b0 100644 --- a/src/strings/fstring.cpp +++ b/src/strings/fstring.cpp @@ -1,7 +1,7 @@ #include "fstring.hpp" // strings/fstring.cpp - Functions for fstring.hpp // -// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> +// Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com> // // This file is part of The Mana World (Athena server) // @@ -27,35 +27,77 @@ namespace strings { + uint8_t FString::empty_string_rep[sizeof(Rep) + 1]; + FString::FString() + : owned(reinterpret_cast<Rep *>(&empty_string_rep)) + { + owned->count++; + } + + FString::FString(const FString& r) + : owned(r.owned) + { + owned->count++; + } + FString::FString(FString&& r) + : owned(reinterpret_cast<Rep *>(&empty_string_rep)) + { + std::swap(owned, r.owned); + r.owned->count++; + } + FString& FString::operator = (const FString& r) + { + // order important for self-assign + r.owned->count++; + // owned can be NULL from ctors + // TODO do ctors *properly* (requires gcc 4.7 to stay sane) + if (owned && !owned->count--) + ::operator delete(owned); + owned = r.owned; + return *this; + } + FString& FString::operator = (FString&& r) + { + std::swap(owned, r.owned); + return *this; + } + FString::~FString() { - const char *sadness = ""; - _assign(sadness, sadness); + if (owned && !owned->count--) + ::operator delete(owned); + owned = nullptr; } FString::FString(const MString& s) + : owned(nullptr) { _assign(s.begin(), s.end()); } FString::FString(XPair p) + : owned(nullptr) { _assign(p.begin(), p.end()); } FString::FString(const TString& t) + : owned(nullptr) { *this = XString(t); } FString::FString(const SString& s) + : owned(nullptr) { *this = XString(s); } FString::FString(ZString z) + : owned(nullptr) { *this = XString(z); } FString::FString(XString x) + : owned(nullptr) { const FString *f = x.base(); const char *xb = &*x.begin(); @@ -70,11 +112,11 @@ namespace strings FString::iterator FString::begin() const { - return &_hack2->begin()[0]; + return owned->body; } FString::iterator FString::end() const { - return &_hack2->end()[-1]; + return owned->body + owned->size; } const FString *FString::base() const { diff --git a/src/strings/fstring.hpp b/src/strings/fstring.hpp index b025d74..48da326 100644 --- a/src/strings/fstring.hpp +++ b/src/strings/fstring.hpp @@ -2,7 +2,7 @@ #define TMWA_STRINGS_FSTRING_HPP // strings/fstring.hpp - An owned, reference-counted immutable string. // -// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> +// Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com> // // This file is part of The Mana World (Athena server) // @@ -22,24 +22,34 @@ # include <cstdarg> # include <cstring> -# include <memory> -# include <vector> - # include "base.hpp" namespace strings { /// An owning string that has reached its final contents. /// The storage is NUL-terminated - /// TODO reimplement without std::shared_ptr class FString : public _crtp_string<FString, FString, ZPair> { - std::shared_ptr<std::vector<char>> _hack2; + struct Rep + { + size_t count; + size_t size; + char body[]; + }; + static + uint8_t empty_string_rep[sizeof(Rep) + 1]; + + Rep *owned; template<class It> void _assign(It b, It e); public: FString(); + FString(const FString&); + FString(FString&&); + FString& operator = (const FString&); + FString& operator = (FString&&); + ~FString(); explicit FString(const MString& s); diff --git a/src/strings/fstring.py b/src/strings/fstring.py new file mode 100644 index 0000000..5418300 --- /dev/null +++ b/src/strings/fstring.py @@ -0,0 +1,19 @@ +class FString(object): + ''' print a FString + ''' + __slots__ = ('_value') + name = 'strings::FString' + enabled = True + + def __init__(self, value): + self._value = value + + def children(self): + yield 'count', self._value['owned'].dereference()['count'] + + def to_string(self): + r = self._value['owned'].dereference() + b = r['body'] + b = b.cast(b.type.target().pointer()) + d = r['size'] + return b.lazy_string(length=d) diff --git a/src/strings/fstring.tcc b/src/strings/fstring.tcc index 388aef1..9c5f37b 100644 --- a/src/strings/fstring.tcc +++ b/src/strings/fstring.tcc @@ -17,6 +17,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include "mstring.hpp" + namespace strings { template<class It> @@ -24,22 +26,24 @@ namespace strings { if (b == e) { - // TODO use a special empty object - // return; + *this = FString(); + return; } if (!std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<It>::iterator_category>::value) { // can't use std::distance - _hack2 = std::make_shared<std::vector<char>>(); + MString m; for (; b != e; ++b) - _hack2->push_back(*b); - _hack2->push_back('\0'); - _hack2->shrink_to_fit(); + m += *b; + *this = FString(m); // will recurse return; } size_t diff = std::distance(b, e); - _hack2 = std::make_shared<std::vector<char>>(diff + 1, '\0'); - std::copy(b, e, _hack2->begin()); + owned = static_cast<Rep *>(::operator new(sizeof(Rep) + diff + 1)); + owned->count = 0; + owned->size = diff; + std::copy(b, e, owned->body); + owned->body[diff] = '\0'; } template<size_t n> |