summaryrefslogtreecommitdiff
path: root/src/strings
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2014-02-08 15:09:25 -0800
committerBen Longbons <b.r.longbons@gmail.com>2014-02-08 16:18:22 -0800
commit730e5dde39333cb2f63c72a7d7152bee5c4dbb05 (patch)
tree510ef3e0ad46ecf1f2bee1fa42f26e6377b51686 /src/strings
parent7a15a3efe85837d52d950cc9f895eadcc9eb6be1 (diff)
downloadtmwa-730e5dde39333cb2f63c72a7d7152bee5c4dbb05.tar.gz
tmwa-730e5dde39333cb2f63c72a7d7152bee5c4dbb05.tar.bz2
tmwa-730e5dde39333cb2f63c72a7d7152bee5c4dbb05.tar.xz
tmwa-730e5dde39333cb2f63c72a7d7152bee5c4dbb05.zip
Implement AString
Diffstat (limited to 'src/strings')
-rw-r--r--src/strings/all.hpp3
-rw-r--r--src/strings/astring.cpp229
-rw-r--r--src/strings/astring.hpp98
-rw-r--r--src/strings/astring.py24
-rw-r--r--src/strings/astring.tcc76
-rw-r--r--src/strings/base.hpp2
-rw-r--r--src/strings/base.tcc2
-rw-r--r--src/strings/base_test.cpp4
-rw-r--r--src/strings/fwd.hpp6
-rw-r--r--src/strings/rstring.cpp (renamed from src/strings/fstring.cpp)83
-rw-r--r--src/strings/rstring.hpp (renamed from src/strings/fstring.hpp)67
-rw-r--r--src/strings/rstring.py (renamed from src/strings/fstring.py)6
-rw-r--r--src/strings/rstring.tcc (renamed from src/strings/fstring.tcc)14
-rw-r--r--src/strings/sstring.cpp45
-rw-r--r--src/strings/sstring.hpp16
-rw-r--r--src/strings/strings2_test.cpp106
-rw-r--r--src/strings/strings_test.cpp29
-rw-r--r--src/strings/tstring.cpp31
-rw-r--r--src/strings/tstring.hpp11
-rw-r--r--src/strings/vstring.hpp5
-rw-r--r--src/strings/vstring.tcc12
-rw-r--r--src/strings/xstring.cpp11
-rw-r--r--src/strings/xstring.hpp13
-rw-r--r--src/strings/zstring.cpp11
-rw-r--r--src/strings/zstring.hpp15
-rw-r--r--src/strings/zstring.tcc2
26 files changed, 740 insertions, 181 deletions
diff --git a/src/strings/all.hpp b/src/strings/all.hpp
index 7fd543f..46d5366 100644
--- a/src/strings/all.hpp
+++ b/src/strings/all.hpp
@@ -21,7 +21,8 @@
# include "base.hpp"
# include "mstring.hpp"
-# include "fstring.hpp"
+# include "rstring.hpp"
+# include "astring.hpp"
# include "tstring.hpp"
# include "sstring.hpp"
# include "zstring.hpp"
diff --git a/src/strings/astring.cpp b/src/strings/astring.cpp
new file mode 100644
index 0000000..f7cfa2e
--- /dev/null
+++ b/src/strings/astring.cpp
@@ -0,0 +1,229 @@
+#include "astring.hpp"
+// strings/astring.cpp - Functions for astring.hpp
+//
+// Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com>
+//
+// This file is part of The Mana World (Athena server)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// 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"
+#include "tstring.hpp"
+#include "sstring.hpp"
+#include "zstring.hpp"
+#include "xstring.hpp"
+#include "vstring.hpp"
+
+namespace strings
+{
+ static_assert(sizeof(AString) == 256, "AString");
+
+ static
+ void acpy(char (&dst)[255], const char (&src)[255])
+ {
+ std::copy(src + 0, src + 255, dst);
+ }
+
+ // TODO dedup all this code once I drop gcc 4.6 support
+ AString::AString()
+ : data{}, special()
+ {
+ new(r_ptr()) RString();
+ special = 255;
+ }
+
+ AString::AString(const AString& a)
+ : data(), special(a.special)
+ {
+ acpy(data, a.data);
+ if (special == 255)
+ new(r_ptr()) RString(*a.r_ptr());
+ }
+ AString::AString(AString&& a)
+ : data(), special(a.special)
+ {
+ acpy(data, a.data);
+ if (special == 255)
+ new(r_ptr()) RString(std::move(*a.r_ptr()));
+ }
+ AString& AString::operator = (const AString& a)
+ {
+ if (this == &a)
+ return *this;
+ if (special == 255)
+ r_ptr()->~RString();
+ acpy(data, a.data);
+ special = a.special;
+ if (special == 255)
+ new(r_ptr()) RString(*a.r_ptr());
+ return *this;
+ }
+ AString& AString::operator = (AString&& a)
+ {
+ std::swap(data, a.data);
+ std::swap(special, a.special);
+ return *this;
+ }
+ AString::AString(RString r)
+ : data{}, special()
+ {
+ new(r_ptr()) RString(std::move(r));
+ special = 255;
+ }
+ AString::~AString()
+ {
+ if (special == 255)
+ r_ptr()->~RString();
+ }
+
+ AString::AString(const MString& s)
+ : data{}, special()
+ {
+ if (s.size() > 255 || s.size() == 0)
+ {
+ new(r_ptr()) RString(s);
+ special = 255;
+ }
+ else
+ {
+ *std::copy(s.begin(), s.end(), data) = '\0';
+ special = 255 - s.size();
+ }
+ }
+
+ AString::AString(XPair p)
+ : data{}, special()
+ {
+ new(r_ptr()) RString();
+ special = 255;
+ *this = XString(p);
+ }
+
+ AString::AString(const TString& t)
+ : data{}, special()
+ {
+ new(r_ptr()) RString();
+ special = 255;
+ *this = XString(t);
+ }
+ AString::AString(const SString& s)
+ : data{}, special()
+ {
+ new(r_ptr()) RString();
+ special = 255;
+ *this = XString(s);
+ }
+ AString::AString(ZString z)
+ : data{}, special()
+ {
+ new(r_ptr()) RString();
+ special = 255;
+ *this = XString(z);
+ }
+ AString::AString(XString x)
+ : data{}, special()
+ {
+ if (const RString *r = x.base())
+ {
+ if (&*r->begin() == &*x.begin() && &*r->end() == &*x.end())
+ {
+ new(r_ptr()) RString(*r);
+ special = 255;
+ return;
+ }
+ }
+ if (x.size() > 255 || x.size() == 0)
+ {
+ new(r_ptr()) RString(x);
+ special = 255;
+ }
+ else
+ {
+ *std::copy(x.begin(), x.end(), data) = '\0';
+ special = 255 - x.size();
+ }
+ }
+
+ AString::iterator AString::begin() const
+ {
+ if (special == 255)
+ return &*r_ptr()->begin();
+ else
+ return data + 0;
+ }
+ AString::iterator AString::end() const
+ {
+ if (special == 255)
+ return &*r_ptr()->end();
+ else
+ return data + (255 - special);
+ }
+ const RString *AString::base() const
+ {
+ if (special == 255)
+ return r_ptr();
+ else
+ return nullptr;
+ }
+ const char *AString::c_str() const
+ {
+ return &*begin();
+ }
+
+ const char *decay_for_printf(const AString& as)
+ {
+ return as.c_str();
+ }
+
+ int do_vprint(AString& out, const char *fmt, va_list ap)
+ {
+ // TODO try with a fixed-size buffer first, then write
+ // directory into the allocated output?
+ int len;
+ {
+ va_list ap2;
+ va_copy(ap2, ap);
+ len = vsnprintf(nullptr, 0, fmt, ap2);
+ va_end(ap2);
+ }
+ char buffer[len + 1];
+ vsnprintf(buffer, len + 1, fmt, ap);
+
+ out = AString(buffer, buffer + len);
+ return len;
+ }
+
+ AStringConverter::AStringConverter(AString& s)
+ : out(s), mid(nullptr)
+ {}
+
+ AStringConverter::~AStringConverter()
+ {
+ if (mid)
+ {
+ out = ZString(really_construct_from_a_pointer, mid, nullptr);
+ free(mid);
+ }
+ }
+
+ char **AStringConverter::operator &()
+ {
+ return &mid;
+ }
+
+ AStringConverter convert_for_scanf(AString& s)
+ {
+ return AStringConverter(s);
+ }
+} // namespace strings
diff --git a/src/strings/astring.hpp b/src/strings/astring.hpp
new file mode 100644
index 0000000..e682ef0
--- /dev/null
+++ b/src/strings/astring.hpp
@@ -0,0 +1,98 @@
+#ifndef TMWA_STRINGS_ASTRING_HPP
+#define TMWA_STRINGS_ASTRING_HPP
+// strings/astring.hpp - An owned, reference-counted immutable string.
+//
+// Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com>
+//
+// This file is part of The Mana World (Athena server)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// 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 <cstdarg>
+# include <cstring>
+
+# include "base.hpp"
+# include "rstring.hpp"
+
+namespace strings
+{
+ /// An owning string that has reached its final contents.
+ /// The storage is NUL-terminated
+ class AString : public _crtp_string<AString, AString, ZPair>
+ {
+ RString *align[0];
+ char data[255];
+ unsigned char special;
+ RString *r_ptr() { return reinterpret_cast<RString *>(data); }
+ const RString *r_ptr() const { return reinterpret_cast<const RString *>(data); }
+ public:
+ AString();
+ AString(const AString&);
+ AString(AString&&);
+ AString& operator = (const AString&);
+ AString& operator = (AString&&);
+ AString(RString);
+ ~AString();
+
+ explicit AString(const MString& s);
+
+ template<size_t n>
+ AString(char (&s)[n]) = delete;
+
+ template<size_t n>
+ AString(const char (&s)[n]);
+
+ template<class It>
+ AString(It b, It e);
+
+ AString(XPair p);
+ //AString(const AString&)
+ AString(const TString&);
+ AString(const SString&);
+ AString(ZString);
+ AString(XString);
+ template<uint8_t n>
+ AString(const VString<n>& v);
+
+ iterator begin() const;
+ iterator end() const;
+ const RString *base() const;
+ const char *c_str() const;
+ };
+
+ // cxxstdio helpers
+ // I think the conversion will happen automatically. TODO test this.
+ // Nope, it doesn't, since there's a template
+ // Actually, it might now.
+ const char *decay_for_printf(const AString& fs);
+
+ __attribute__((format(printf, 2, 0)))
+ int do_vprint(AString& out, const char *fmt, va_list ap);
+
+ class AStringConverter
+ {
+ AString& out;
+ char *mid;
+ public:
+ AStringConverter(AString& s);
+ ~AStringConverter();
+ char **operator &();
+ };
+
+ AStringConverter convert_for_scanf(AString& s);
+} // namespace strings
+
+# include "astring.tcc"
+
+#endif // TMWA_STRINGS_ASTRING_HPP
diff --git a/src/strings/astring.py b/src/strings/astring.py
new file mode 100644
index 0000000..ec1dafe
--- /dev/null
+++ b/src/strings/astring.py
@@ -0,0 +1,24 @@
+class AString(object):
+ ''' print an AString
+ '''
+ __slots__ = ('_value')
+ name = 'strings::AString'
+ enabled = True
+
+ def __init__(self, value):
+ self._value = value
+
+ def to_string(self):
+ return None
+
+ def children(self):
+ b = self._value['data']
+ s = self._value['special']
+ if s == 255:
+ b = b.cast(gdb.lookup_type('strings::RString').pointer())
+ yield 'allocated', b.dereference()
+ else:
+ b = b.cast(b.type.target().pointer())
+ n = 255
+ d = n - s
+ yield 'contained', b.lazy_string(length=d)
diff --git a/src/strings/astring.tcc b/src/strings/astring.tcc
new file mode 100644
index 0000000..ed07bd9
--- /dev/null
+++ b/src/strings/astring.tcc
@@ -0,0 +1,76 @@
+// strings/astring.tcc - Inline functions for astring.hpp
+//
+// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
+//
+// This file is part of The Mana World (Athena server)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// 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<size_t n>
+ AString::AString(const char (&s)[n])
+ : data{}, special()
+ {
+ XPair x = s;
+ if (x.size() > 255 || x.size() == 0)
+ {
+ new(r_ptr()) RString(x);
+ special = 255;
+ }
+ else
+ {
+ *std::copy(x.begin(), x.end(), data) = '\0';
+ special = 255 - x.size();
+ }
+ }
+
+ template<class It>
+ AString::AString(It b, It e)
+ : data{}, special()
+ {
+ if (!std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<It>::iterator_category>::value)
+ {
+ // can't use std::distance
+ MString m;
+ for (; b != e; ++b)
+ m += *b;
+ *this = AString(m); // will recurse
+ return;
+ }
+ auto d = std::distance(b, e);
+ if (d > 255 || d == 0)
+ {
+ new(r_ptr()) RString(b, e);
+ special = 255;
+ }
+ else
+ {
+ *std::copy(b, e, data) = '\0';
+ special = 255 - d;
+ }
+ }
+
+ template<uint8_t n>
+ AString::AString(const VString<n>& v)
+ : data{}, special()
+ {
+ *std::copy(v.begin(), v.end(), data) = '\0';
+ special = 255 - v.size();
+ if (!v)
+ new(r_ptr()) RString();
+ }
+} // namespace strings
diff --git a/src/strings/base.hpp b/src/strings/base.hpp
index 7461872..c081f70 100644
--- a/src/strings/base.hpp
+++ b/src/strings/base.hpp
@@ -88,7 +88,7 @@ namespace strings
const T& _ref() const;
iterator begin() const;
iterator end() const;
- const FString *base() const;
+ const RString *base() const;
public:
size_t size() const;
reverse_iterator rbegin() const;
diff --git a/src/strings/base.tcc b/src/strings/base.tcc
index 491b4ca..a5a57d0 100644
--- a/src/strings/base.tcc
+++ b/src/strings/base.tcc
@@ -104,7 +104,7 @@ namespace strings
return _ref().end();
}
template<class T, class O, class P>
- const FString *_crtp_string<T, O, P>::base() const
+ const RString *_crtp_string<T, O, P>::base() const
{
return _ref().base();
}
diff --git a/src/strings/base_test.cpp b/src/strings/base_test.cpp
index cb41fa9..3f9900e 100644
--- a/src/strings/base_test.cpp
+++ b/src/strings/base_test.cpp
@@ -4,7 +4,7 @@
#include "vstring.hpp"
#include "xstring.hpp"
-#include "fstring.hpp"
+#include "rstring.hpp"
using namespace strings;
@@ -18,7 +18,7 @@ static_assert(!string_comparison_allowed<_test, VString<1>>::value, "tv");
static_assert(!string_comparison_allowed<_test, _test2>::value, "t2");
static_assert(string_comparison_allowed<VString<1>, XString>::value, "vx");
static_assert(string_comparison_allowed<XString, XString>::value, "xx");
-static_assert(string_comparison_allowed<XString, FString>::value, "xf");
+static_assert(string_comparison_allowed<XString, RString>::value, "xf");
TEST(strings, contains)
{
diff --git a/src/strings/fwd.hpp b/src/strings/fwd.hpp
index a865fc4..f2b4037 100644
--- a/src/strings/fwd.hpp
+++ b/src/strings/fwd.hpp
@@ -28,7 +28,8 @@ namespace strings
{
// owning
class MString;
- class FString;
+ class RString;
+ class AString;
class TString; // C legacy version of SString
class SString; // is this one really worth it?
@@ -46,7 +47,8 @@ namespace strings
} // namespace strings
using strings::MString;
-using strings::FString;
+using strings::RString;
+using strings::AString;
using strings::TString;
using strings::SString;
diff --git a/src/strings/fstring.cpp b/src/strings/rstring.cpp
index 97ef4b0..eb9d88a 100644
--- a/src/strings/fstring.cpp
+++ b/src/strings/rstring.cpp
@@ -1,5 +1,5 @@
-#include "fstring.hpp"
-// strings/fstring.cpp - Functions for fstring.hpp
+#include "rstring.hpp"
+// strings/rstring.cpp - Functions for rstring.hpp
//
// Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com>
//
@@ -27,26 +27,28 @@
namespace strings
{
- uint8_t FString::empty_string_rep[sizeof(Rep) + 1];
+ static_assert(sizeof(RString) == sizeof(const char *), "RString");
- FString::FString()
+ uint8_t RString::empty_string_rep[sizeof(Rep) + 1];
+
+ RString::RString()
: owned(reinterpret_cast<Rep *>(&empty_string_rep))
{
owned->count++;
}
- FString::FString(const FString& r)
+ RString::RString(const RString& r)
: owned(r.owned)
{
owned->count++;
}
- FString::FString(FString&& r)
+ RString::RString(RString&& r)
: owned(reinterpret_cast<Rep *>(&empty_string_rep))
{
std::swap(owned, r.owned);
r.owned->count++;
}
- FString& FString::operator = (const FString& r)
+ RString& RString::operator = (const RString& r)
{
// order important for self-assign
r.owned->count++;
@@ -57,49 +59,61 @@ namespace strings
owned = r.owned;
return *this;
}
- FString& FString::operator = (FString&& r)
+ RString& RString::operator = (RString&& r)
{
std::swap(owned, r.owned);
return *this;
}
- FString::~FString()
+ RString::RString(AString a)
+ : owned(nullptr)
+ {
+ if (RString *r = const_cast<RString *>(a.base()))
+ {
+ *this = std::move(*r);
+ }
+ else
+ {
+ *this = XPair(a);
+ }
+ }
+ RString::~RString()
{
if (owned && !owned->count--)
::operator delete(owned);
owned = nullptr;
}
- FString::FString(const MString& s)
+ RString::RString(const MString& s)
: owned(nullptr)
{
_assign(s.begin(), s.end());
}
- FString::FString(XPair p)
+ RString::RString(XPair p)
: owned(nullptr)
{
_assign(p.begin(), p.end());
}
- FString::FString(const TString& t)
+ RString::RString(const TString& t)
: owned(nullptr)
{
*this = XString(t);
}
- FString::FString(const SString& s)
+ RString::RString(const SString& s)
: owned(nullptr)
{
*this = XString(s);
}
- FString::FString(ZString z)
+ RString::RString(ZString z)
: owned(nullptr)
{
*this = XString(z);
}
- FString::FString(XString x)
+ RString::RString(XString x)
: owned(nullptr)
{
- const FString *f = x.base();
+ const RString *f = x.base();
const char *xb = &*x.begin();
const char *xe = &*x.end();
const char *fb = f ? &*f->begin() : nullptr;
@@ -110,29 +124,29 @@ namespace strings
_assign(x.begin(), x.end());
}
- FString::iterator FString::begin() const
+ RString::iterator RString::begin() const
{
return owned->body;
}
- FString::iterator FString::end() const
+ RString::iterator RString::end() const
{
return owned->body + owned->size;
}
- const FString *FString::base() const
+ const RString *RString::base() const
{
return this;
}
- const char *FString::c_str() const
+ const char *RString::c_str() const
{
return &*begin();
}
- const char *decay_for_printf(const FString& fs)
+ const char *decay_for_printf(const RString& fs)
{
return fs.c_str();
}
- int do_vprint(FString& out, const char *fmt, va_list ap)
+ int do_vprint(RString& out, const char *fmt, va_list ap)
{
int len;
{
@@ -144,30 +158,7 @@ namespace strings
char buffer[len + 1];
vsnprintf(buffer, len + 1, fmt, ap);
- out = FString(buffer, buffer + len);
+ out = RString(buffer, buffer + len);
return len;
}
-
- StringConverter::StringConverter(FString& s)
- : out(s), mid(nullptr)
- {}
-
- StringConverter::~StringConverter()
- {
- if (mid)
- {
- out = ZString(really_construct_from_a_pointer, mid, nullptr);
- free(mid);
- }
- }
-
- char **StringConverter::operator &()
- {
- return &mid;
- }
-
- StringConverter convert_for_scanf(FString& s)
- {
- return StringConverter(s);
- }
} // namespace strings
diff --git a/src/strings/fstring.hpp b/src/strings/rstring.hpp
index 48da326..b79c7f6 100644
--- a/src/strings/fstring.hpp
+++ b/src/strings/rstring.hpp
@@ -1,6 +1,6 @@
-#ifndef TMWA_STRINGS_FSTRING_HPP
-#define TMWA_STRINGS_FSTRING_HPP
-// strings/fstring.hpp - An owned, reference-counted immutable string.
+#ifndef TMWA_STRINGS_RSTRING_HPP
+#define TMWA_STRINGS_RSTRING_HPP
+// strings/rstring.hpp - An owned, reference-counted immutable string.
//
// Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com>
//
@@ -28,7 +28,7 @@ namespace strings
{
/// An owning string that has reached its final contents.
/// The storage is NUL-terminated
- class FString : public _crtp_string<FString, FString, ZPair>
+ class RString : public _crtp_string<RString, RString, ZPair>
{
struct Rep
{
@@ -44,36 +44,37 @@ namespace strings
template<class It>
void _assign(It b, It e);
public:
- FString();
- FString(const FString&);
- FString(FString&&);
- FString& operator = (const FString&);
- FString& operator = (FString&&);
- ~FString();
+ RString();
+ RString(const RString&);
+ RString(RString&&);
+ RString& operator = (const RString&);
+ RString& operator = (RString&&);
+ RString(AString);
+ ~RString();
- explicit FString(const MString& s);
+ explicit RString(const MString& s);
template<size_t n>
- FString(char (&s)[n]) = delete;
+ RString(char (&s)[n]) = delete;
template<size_t n>
- FString(const char (&s)[n]);
+ RString(const char (&s)[n]);
template<class It>
- FString(It b, It e);
-
- FString(XPair p);
- //FString(const FString&)
- FString(const TString&);
- FString(const SString&);
- FString(ZString);
- FString(XString);
+ RString(It b, It e);
+
+ RString(XPair p);
+ //RString(const RString&)
+ RString(const TString&);
+ RString(const SString&);
+ RString(ZString);
+ RString(XString);
template<uint8_t n>
- FString(const VString<n>& v);
+ RString(const VString<n>& v);
iterator begin() const;
iterator end() const;
- const FString *base() const;
+ const RString *base() const;
const char *c_str() const;
};
@@ -81,24 +82,12 @@ namespace strings
// I think the conversion will happen automatically. TODO test this.
// Nope, it doesn't, since there's a template
// Actually, it might now.
- const char *decay_for_printf(const FString& fs);
+ const char *decay_for_printf(const RString& fs);
__attribute__((format(printf, 2, 0)))
- int do_vprint(FString& out, const char *fmt, va_list ap);
-
- class StringConverter
- {
- FString& out;
- char *mid;
- public:
- StringConverter(FString& s);
- ~StringConverter();
- char **operator &();
- };
-
- StringConverter convert_for_scanf(FString& s);
+ int do_vprint(RString& out, const char *fmt, va_list ap);
} // namespace strings
-# include "fstring.tcc"
+# include "rstring.tcc"
-#endif // TMWA_STRINGS_FSTRING_HPP
+#endif // TMWA_STRINGS_RSTRING_HPP
diff --git a/src/strings/fstring.py b/src/strings/rstring.py
index 5418300..f0618d6 100644
--- a/src/strings/fstring.py
+++ b/src/strings/rstring.py
@@ -1,8 +1,8 @@
-class FString(object):
- ''' print a FString
+class RString(object):
+ ''' print a RString
'''
__slots__ = ('_value')
- name = 'strings::FString'
+ name = 'strings::RString'
enabled = True
def __init__(self, value):
diff --git a/src/strings/fstring.tcc b/src/strings/rstring.tcc
index 8072fb0..8b4c0c0 100644
--- a/src/strings/fstring.tcc
+++ b/src/strings/rstring.tcc
@@ -1,4 +1,4 @@
-// strings/fstring.tcc - Inline functions for fstring.hpp
+// strings/rstring.tcc - Inline functions for rstring.hpp
//
// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
//
@@ -22,12 +22,12 @@
namespace strings
{
template<class It>
- void FString::_assign(It b, It e)
+ void RString::_assign(It b, It e)
{
owned = nullptr;
if (b == e)
{
- *this = FString();
+ *this = RString();
return;
}
if (!std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<It>::iterator_category>::value)
@@ -36,7 +36,7 @@ namespace strings
MString m;
for (; b != e; ++b)
m += *b;
- *this = FString(m); // will recurse
+ *this = RString(m); // will recurse
return;
}
size_t diff = std::distance(b, e);
@@ -48,19 +48,19 @@ namespace strings
}
template<size_t n>
- FString::FString(const char (&s)[n])
+ RString::RString(const char (&s)[n])
{
_assign(s, s + strlen(s));
}
template<class It>
- FString::FString(It b, It e)
+ RString::RString(It b, It e)
{
_assign(b, e);
}
template<uint8_t n>
- FString::FString(const VString<n>& v)
+ RString::RString(const VString<n>& v)
{
_assign(v.begin(), v.end());
}
diff --git a/src/strings/sstring.cpp b/src/strings/sstring.cpp
index 99f91ed..fee98f9 100644
--- a/src/strings/sstring.cpp
+++ b/src/strings/sstring.cpp
@@ -27,8 +27,11 @@ namespace strings
SString::SString()
: _s(), _b(), _e()
{}
- SString::SString(FString f)
- : _s(std::move(f)), _b(), _e(_s.size())
+ SString::SString(RString r)
+ : _s(std::move(r)), _b(), _e(_s.size())
+ {}
+ SString::SString(AString a)
+ : _s(std::move(a)), _b(), _e(_s.size())
{}
SString::SString(TString t)
: _s(t._s), _b(0), _e(_s.size())
@@ -39,19 +42,39 @@ namespace strings
}
SString::SString(const XString& x)
{
- const FString *f = x.base();
+ const RString *r = x.base();
const char *xb = &*x.begin();
const char *xe = &*x.end();
- const char *fb = f ? &*f->begin() : nullptr;
- //const char *fe = f ? &*f->end() : nullptr;
- if (f)
- *this = SString(*f, xb - fb, xe - fb);
+ const char *rb = r ? &*r->begin() : nullptr;
+ //const char *re = r ? &*r->end() : nullptr;
+ if (r)
+ *this = SString(*r, xb - rb, xe - rb);
else
- *this = FString(x);
+ *this = RString(x);
}
- SString::SString(FString f, size_t b, size_t e)
- : _s(std::move(f)), _b(b), _e(e)
+ SString::SString(RString r, size_t b, size_t e)
+ : _s(std::move(r)), _b(b), _e(e)
+ {}
+ static
+ RString get_owned_slice(AString a, size_t *b, size_t *e)
+ {
+ if (a.base())
+ {
+ // it's futile
+ return std::move(a);
+ }
+ // have to allocate anyway, so cut first
+ size_t ob = *b;
+ size_t oe = *e;
+ *e -= *b;
+ *b = 0;
+ return a.xpslice(ob, oe);
+ }
+ SString::SString(AString a, size_t b, size_t e)
+ : _s(get_owned_slice(std::move(a), &b, &e))
+ , _b(b)
+ , _e(e)
{}
SString::SString(XPair p)
: _s(p), _b(0), _e(p.size())
@@ -65,7 +88,7 @@ namespace strings
{
return &_s.begin()[_e];
}
- const FString *SString::base() const
+ const RString *SString::base() const
{
return &_s;
}
diff --git a/src/strings/sstring.hpp b/src/strings/sstring.hpp
index 12fb96d..1836d69 100644
--- a/src/strings/sstring.hpp
+++ b/src/strings/sstring.hpp
@@ -1,6 +1,6 @@
#ifndef TMWA_STRINGS_SSTRING_HPP
#define TMWA_STRINGS_SSTRING_HPP
-// strings/sstring.hpp - A full slice of an FString.
+// strings/sstring.hpp - A full slice of an RString.
//
// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
//
@@ -20,19 +20,20 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "base.hpp"
-# include "fstring.hpp"
+# include "rstring.hpp"
namespace strings
{
- /// An owning string that represents a arbitrary slice of an FString.
+ /// An owning string that represents a arbitrary slice of an RString.
/// Not guaranteed to be NUL-terminated.
class SString : public _crtp_string<SString, SString, XPair>
{
- FString _s;
+ RString _s;
size_t _b, _e;
public:
SString();
- SString(FString f);
+ SString(RString f);
+ SString(AString f);
SString(TString t);
//SString(const SString&);
SString(const ZString&);
@@ -45,12 +46,13 @@ namespace strings
SString(const char (&s)[n]);
//template<class It>
//SString(It b, It e) : _s(b, e), _b(0), _e(_s.size()) {}
- SString(FString f, size_t b, size_t e);
+ SString(RString f, size_t b, size_t e);
+ SString(AString f, size_t b, size_t e);
SString(XPair p);
iterator begin() const;
iterator end() const;
- const FString *base() const;
+ const RString *base() const;
};
} // namespace strings
diff --git a/src/strings/strings2_test.cpp b/src/strings/strings2_test.cpp
index 3f8662a..24bfc0c 100644
--- a/src/strings/strings2_test.cpp
+++ b/src/strings/strings2_test.cpp
@@ -6,7 +6,7 @@ TEST(StringTests, traits2)
{
ZString print_non = "\t\e";
ZString print_mix = "n\t";
- FString print_all = "n ";
+ RString print_all = "n ";
EXPECT_FALSE(print_non.has_print());
EXPECT_TRUE(print_mix.has_print());
EXPECT_TRUE(print_all.has_print());
@@ -20,7 +20,7 @@ TEST(StringTests, traits2)
ZString graph_non = " \e";
ZString graph_mix = "n ";
- FString graph_all = "n.";
+ RString graph_all = "n.";
EXPECT_FALSE(graph_non.has_graph());
EXPECT_TRUE(graph_mix.has_graph());
EXPECT_TRUE(graph_all.has_graph());
@@ -30,7 +30,7 @@ TEST(StringTests, traits2)
ZString lower_non = "0A";
ZString lower_mix = "Oa";
- FString lower_all = "oa";
+ RString lower_all = "oa";
EXPECT_FALSE(lower_non.has_lower());
EXPECT_TRUE(lower_mix.has_lower());
EXPECT_TRUE(lower_all.has_lower());
@@ -44,7 +44,7 @@ TEST(StringTests, traits2)
ZString upper_non = "0a";
ZString upper_mix = "oA";
- FString upper_all = "OA";
+ RString upper_all = "OA";
EXPECT_FALSE(upper_non.has_upper());
EXPECT_TRUE(upper_mix.has_upper());
EXPECT_TRUE(upper_all.has_upper());
@@ -58,7 +58,7 @@ TEST(StringTests, traits2)
ZString alpha_non = " 0";
ZString alpha_mix = "n ";
- FString alpha_all = "nA";
+ RString alpha_all = "nA";
EXPECT_FALSE(alpha_non.has_alpha());
EXPECT_TRUE(alpha_mix.has_alpha());
EXPECT_TRUE(alpha_all.has_alpha());
@@ -68,7 +68,7 @@ TEST(StringTests, traits2)
ZString digit2_non = "a9";
ZString digit2_mix = "20";
- FString digit2_all = "01";
+ RString digit2_all = "01";
EXPECT_FALSE(digit2_non.has_digit2());
EXPECT_TRUE(digit2_mix.has_digit2());
EXPECT_TRUE(digit2_all.has_digit2());
@@ -78,7 +78,7 @@ TEST(StringTests, traits2)
ZString digit8_non = "a9";
ZString digit8_mix = "80";
- FString digit8_all = "37";
+ RString digit8_all = "37";
EXPECT_FALSE(digit8_non.has_digit8());
EXPECT_TRUE(digit8_mix.has_digit8());
EXPECT_TRUE(digit8_all.has_digit8());
@@ -88,7 +88,7 @@ TEST(StringTests, traits2)
ZString digit10_non = "az";
ZString digit10_mix = "a9";
- FString digit10_all = "42";
+ RString digit10_all = "42";
EXPECT_FALSE(digit10_non.has_digit10());
EXPECT_TRUE(digit10_mix.has_digit10());
EXPECT_TRUE(digit10_all.has_digit10());
@@ -98,7 +98,7 @@ TEST(StringTests, traits2)
ZString digit16_non = "gz";
ZString digit16_mix = "ao";
- FString digit16_all = "be";
+ RString digit16_all = "be";
EXPECT_FALSE(digit16_non.has_digit16());
EXPECT_TRUE(digit16_mix.has_digit16());
EXPECT_TRUE(digit16_all.has_digit16());
@@ -108,7 +108,7 @@ TEST(StringTests, traits2)
ZString alnum_non = " .";
ZString alnum_mix = "n ";
- FString alnum_all = "n0";
+ RString alnum_all = "n0";
EXPECT_FALSE(alnum_non.has_alnum());
EXPECT_TRUE(alnum_mix.has_alnum());
EXPECT_TRUE(alnum_all.has_alnum());
@@ -116,3 +116,89 @@ TEST(StringTests, traits2)
EXPECT_FALSE(alnum_mix.is_alnum());
EXPECT_TRUE(alnum_all.is_alnum());
}
+
+TEST(StringTests, rempty)
+{
+ const char empty_text[] = "";
+ RString r = empty_text;
+ EXPECT_EQ(r.size(), 0);
+ AString a = empty_text;
+ EXPECT_EQ(r, a);
+ AString r2 = r, r3;
+ RString a2 = a, a3;
+ XString r1 = r2;
+ XString a1 = a2;
+ r3 = r1;
+ a3 = a1;
+ EXPECT_EQ(r, r1);
+ EXPECT_EQ(a, a1);
+ EXPECT_EQ(r, r2);
+ EXPECT_EQ(a, a2);
+ EXPECT_EQ(r, r3);
+ EXPECT_EQ(a, a3);
+ EXPECT_EQ(&*r.begin(), &*r1.begin());
+ EXPECT_EQ(&*a.begin(), &*a1.begin());
+ EXPECT_EQ(&*r.begin(), &*r2.begin());
+ EXPECT_EQ(&*a.begin(), &*a2.begin());
+ EXPECT_EQ(&*r.begin(), &*r3.begin());
+ EXPECT_EQ(&*a.begin(), &*a3.begin());
+}
+TEST(StringTests, rshort)
+{
+ const char short_text[] = "0123456789";
+ RString r = short_text;
+ EXPECT_EQ(r.size(), 10);
+ AString a = short_text;
+ EXPECT_EQ(r, a);
+ AString r2 = r, r3;
+ RString a2 = a, a3;
+ XString r1 = r2;
+ XString a1 = a2;
+ r3 = r1;
+ a3 = a1;
+ EXPECT_EQ(r, r1);
+ EXPECT_EQ(a, a1);
+ EXPECT_EQ(r, r2);
+ EXPECT_EQ(a, a2);
+ EXPECT_EQ(r, r3);
+ EXPECT_EQ(a, a3);
+ EXPECT_EQ(&*r.begin(), &*r1.begin());
+ EXPECT_NE(&*a.begin(), &*a1.begin());
+ EXPECT_EQ(&*r.begin(), &*r2.begin());
+ EXPECT_NE(&*a.begin(), &*a2.begin());
+ EXPECT_EQ(&*r.begin(), &*r3.begin());
+ EXPECT_NE(&*a.begin(), &*a3.begin());
+}
+
+TEST(StringTests, rlong)
+{
+ const char long_text[] =
+ "01234567890123456789012345678901234567890123456789"
+ "0123456789012345678901234567890123456789012345 100"
+ "01234567890123456789012345678901234567890123456789"
+ "0123456789012345678901234567890123456789012345 200"
+ "01234567890123456789012345678901234567890123456789"
+ "0123456789012345678901234567890123456789012345 300";
+ RString r = long_text;
+ EXPECT_EQ(r.size(), 300);
+ AString a = long_text;
+ EXPECT_EQ(r, a);
+ AString r2 = r, r3;
+ RString a2 = a, a3;
+ XString r1 = r2;
+ XString a1 = a2;
+ r3 = r1;
+ a3 = a1;
+ EXPECT_EQ(r, r1);
+ EXPECT_EQ(a, a1);
+ EXPECT_EQ(r, r2);
+ EXPECT_EQ(a, a2);
+ EXPECT_EQ(r, r3);
+ EXPECT_EQ(a, a3);
+ EXPECT_EQ(&*r.begin(), &*r1.begin());
+ EXPECT_EQ(&*a.begin(), &*a1.begin());
+ EXPECT_EQ(&*r.begin(), &*r2.begin());
+ EXPECT_EQ(&*a.begin(), &*a2.begin());
+ EXPECT_EQ(&*r.begin(), &*r3.begin());
+ EXPECT_EQ(&*a.begin(), &*a3.begin());
+}
diff --git a/src/strings/strings_test.cpp b/src/strings/strings_test.cpp
index 82d39d8..55a2ffa 100644
--- a/src/strings/strings_test.cpp
+++ b/src/strings/strings_test.cpp
@@ -21,7 +21,7 @@ TYPED_TEST_P(StringTest, basic)
EXPECT_EQ(0, hi0.size());
__attribute__((unused))
- const FString *base = hi.base();
+ const RString *base = hi.base();
}
TYPED_TEST_P(StringTest, order)
@@ -168,7 +168,8 @@ TYPED_TEST_P(StringTest, convert)
constexpr bool is_zstring = std::is_same<TypeParam, ZString>::value;
typedef typename std::conditional<is_zstring, TString, SString>::type Sstring;
typedef typename std::conditional<is_zstring, ZString, XString>::type Xstring;
- FString f = "f";
+ RString r = "r";
+ AString a = "a";
TString t = "t";
Sstring s = "s";
ZString z = "z";
@@ -177,7 +178,8 @@ TYPED_TEST_P(StringTest, convert)
const char l[] = "l";
VString<5> hi = "hello";
- TypeParam f2 = f;
+ TypeParam r2 = r;
+ TypeParam a2 = a;
TypeParam t2 = t;
TypeParam s2 = s;
TypeParam z2 = z;
@@ -186,7 +188,8 @@ TYPED_TEST_P(StringTest, convert)
TypeParam l2 = l;
TypeParam hi2 = hi;
- EXPECT_EQ(f, f2);
+ EXPECT_EQ(r, r2);
+ EXPECT_EQ(a, a2);
EXPECT_EQ(t, t2);
EXPECT_EQ(s, s2);
EXPECT_EQ(z, z2);
@@ -195,8 +198,9 @@ TYPED_TEST_P(StringTest, convert)
EXPECT_EQ(l, l2);
EXPECT_EQ(hi, hi2);
- TypeParam f3, t3, s3, z3, x3, v3, l3, hi3;
- f3 = f;
+ TypeParam r3, a3, t3, s3, z3, x3, v3, l3, hi3;
+ r3 = r;
+ a3 = a;
t3 = t;
s3 = s;
z3 = z;
@@ -205,7 +209,8 @@ TYPED_TEST_P(StringTest, convert)
l3 = l;
hi3 = hi;
- EXPECT_EQ(f, f3);
+ EXPECT_EQ(r, r3);
+ EXPECT_EQ(a, a3);
EXPECT_EQ(t, t3);
EXPECT_EQ(s, s3);
EXPECT_EQ(z, z3);
@@ -214,7 +219,8 @@ TYPED_TEST_P(StringTest, convert)
EXPECT_EQ(l, l3);
EXPECT_EQ(hi, hi3);
- TypeParam f4(f);
+ TypeParam r4(r);
+ TypeParam a4(a);
TypeParam t4(t);
TypeParam s4(s);
TypeParam z4(z);
@@ -223,7 +229,8 @@ TYPED_TEST_P(StringTest, convert)
TypeParam l4(l);
TypeParam hi4(hi);
- EXPECT_EQ(f, f4);
+ EXPECT_EQ(r, r4);
+ EXPECT_EQ(a, a4);
EXPECT_EQ(t, t4);
EXPECT_EQ(s, s4);
EXPECT_EQ(z, z4);
@@ -237,7 +244,7 @@ REGISTER_TYPED_TEST_CASE_P(StringTest,
basic, order, iterators, xslice, convert);
typedef ::testing::Types<
- FString, TString, SString, ZString, XString, VString<255>
+ RString, AString, TString, SString, ZString, XString, VString<255>
> MostStringTypes;
INSTANTIATE_TYPED_TEST_CASE_P(StringStuff, StringTest, MostStringTypes);
@@ -274,6 +281,6 @@ REGISTER_TYPED_TEST_CASE_P(NulStringTest,
basic);
typedef ::testing::Types<
- FString, TString, ZString, VString<255>
+ RString, AString, TString, ZString, VString<255>
> NulStringTypes;
INSTANTIATE_TYPED_TEST_CASE_P(NulStringStuff, NulStringTest, NulStringTypes);
diff --git a/src/strings/tstring.cpp b/src/strings/tstring.cpp
index 2d13888..8be7112 100644
--- a/src/strings/tstring.cpp
+++ b/src/strings/tstring.cpp
@@ -27,9 +27,24 @@ namespace strings
TString::TString()
: _s(), _o()
{}
- TString::TString(FString b, size_t i)
+ TString::TString(RString b, size_t i)
: _s(std::move(b)), _o(i)
{}
+ static
+ RString get_owned_tlice(AString a, size_t *i)
+ {
+ if (a.base())
+ {
+ return std::move(a);
+ }
+ size_t oi = *i;
+ *i = 0;
+ return a.xslice_t(oi);
+ }
+ TString::TString(AString b, size_t i)
+ : _s(get_owned_tlice(std::move(b), &i))
+ , _o(i)
+ {}
TString::TString(const SString& s)
{
*this = XString(s);
@@ -40,15 +55,15 @@ namespace strings
}
TString::TString(const XString& x)
{
- const FString *f = x.base();
+ const RString *r = x.base();
const char *xb = &*x.begin();
const char *xe = &*x.end();
- const char *fb = f ? &*f->begin() : nullptr;
- const char *fe = f ? &*f->end() : nullptr;
- if (f && xe == fe)
- *this = TString(*f, xb - fb);
+ const char *rb = r ? &*r->begin() : nullptr;
+ const char *re = r ? &*r->end() : nullptr;
+ if (r && xe == re)
+ *this = TString(*r, xb - rb);
else
- *this = FString(x);
+ *this = RString(x);
}
TString::TString(XPair p)
@@ -63,7 +78,7 @@ namespace strings
{
return &*_s.end();
}
- const FString *TString::base() const
+ const RString *TString::base() const
{
return &_s;
}
diff --git a/src/strings/tstring.hpp b/src/strings/tstring.hpp
index 49ec4ab..700ec3d 100644
--- a/src/strings/tstring.hpp
+++ b/src/strings/tstring.hpp
@@ -20,20 +20,21 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "base.hpp"
-# include "fstring.hpp"
+# include "rstring.hpp"
namespace strings
{
- /// An owning string that represents a tail slice of an FString.
+ /// An owning string that represents a tail slice of an RString.
/// Guaranteed to be NUL-terminated.
class TString : public _crtp_string<TString, TString, ZPair>
{
friend class SString;
- FString _s;
+ RString _s;
size_t _o;
public:
TString();
- TString(FString b, size_t i=0);
+ TString(RString b, size_t i=0);
+ TString(AString b, size_t i=0);
//TString(const TString&)
TString(const SString&);
TString(const ZString&);
@@ -50,7 +51,7 @@ namespace strings
iterator begin() const;
iterator end() const;
- const FString *base() const;
+ const RString *base() const;
const char *c_str() const;
};
diff --git a/src/strings/vstring.hpp b/src/strings/vstring.hpp
index c07c32a..183e782 100644
--- a/src/strings/vstring.hpp
+++ b/src/strings/vstring.hpp
@@ -31,7 +31,8 @@ namespace strings
public:
typedef typename _crtp_string<VString<n>, VString<n>, ZPair>::iterator iterator;
VString(XString x);
- VString(FString f);
+ VString(RString f);
+ VString(AString f);
VString(TString t);
VString(SString s);
VString(ZString z);
@@ -48,7 +49,7 @@ namespace strings
iterator begin() const;
iterator end() const;
- const FString *base() const;
+ const RString *base() const;
const char *c_str() const;
};
diff --git a/src/strings/vstring.tcc b/src/strings/vstring.tcc
index 674b21d..69729d4 100644
--- a/src/strings/vstring.tcc
+++ b/src/strings/vstring.tcc
@@ -21,7 +21,8 @@
#include "../common/utils2.hpp"
-#include "fstring.hpp"
+#include "rstring.hpp"
+#include "astring.hpp"
#include "tstring.hpp"
#include "sstring.hpp"
#include "zstring.hpp"
@@ -43,11 +44,16 @@ namespace strings
// poor man's delegated constructors
// needed for gcc 4.6 compatibility
template<uint8_t n>
- VString<n>::VString(FString f)
+ VString<n>::VString(RString f)
{
*this = XString(f);
}
template<uint8_t n>
+ VString<n>::VString(AString a)
+ {
+ *this = XString(a);
+ }
+ template<uint8_t n>
VString<n>::VString(TString t)
{
*this = XString(t);
@@ -109,7 +115,7 @@ namespace strings
return std::end(_data) - _special;
}
template<uint8_t n>
- const FString *VString<n>::base() const
+ const RString *VString<n>::base() const
{
return nullptr;
}
diff --git a/src/strings/xstring.cpp b/src/strings/xstring.cpp
index 107217b..8a604c7 100644
--- a/src/strings/xstring.cpp
+++ b/src/strings/xstring.cpp
@@ -23,7 +23,10 @@ namespace strings
XString::XString()
: _b(""), _e(_b), _base()
{}
- XString::XString(const FString& s)
+ XString::XString(const RString& s)
+ : _b(&*s.begin()), _e(&*s.end()), _base(s.base())
+ {}
+ XString::XString(const AString& s)
: _b(&*s.begin()), _e(&*s.end()), _base(s.base())
{}
XString::XString(const TString& s)
@@ -36,10 +39,10 @@ namespace strings
: _b(&*s.begin()), _e(&*s.end()), _base(s.base())
{}
- XString::XString(const char *b, const char *e, const FString *base_)
+ XString::XString(const char *b, const char *e, const RString *base_)
: _b(b), _e(e), _base(base_)
{}
- XString::XString(decltype(really_construct_from_a_pointer) e, const char *s, const FString *base_)
+ XString::XString(decltype(really_construct_from_a_pointer) e, const char *s, const RString *base_)
{
*this = ZString(e, s, base_);
}
@@ -55,7 +58,7 @@ namespace strings
{
return _e;
}
- const FString *XString::base() const
+ const RString *XString::base() const
{
return _base;
}
diff --git a/src/strings/xstring.hpp b/src/strings/xstring.hpp
index e96ef8a..2766810 100644
--- a/src/strings/xstring.hpp
+++ b/src/strings/xstring.hpp
@@ -25,17 +25,18 @@ namespace strings
{
/// A non-owning string that is not guaranteed to be NUL-terminated.
/// This should be only used as a parameter.
- class XString : public _crtp_string<XString, FString, XPair>
+ class XString : public _crtp_string<XString, AString, XPair>
{
iterator _b, _e;
// optional
- const FString *_base;
+ const RString *_base;
public:
// do I really want this?
XString();
XString(std::nullptr_t) = delete;
// no MString
- XString(const FString& s);
+ XString(const RString& s);
+ XString(const AString& s);
XString(const TString& s);
XString(const SString& s);
XString(const ZString& s);
@@ -46,13 +47,13 @@ namespace strings
template<size_t n>
XString(const char (&s)[n]);
// mostly internal
- XString(const char *b, const char *e, const FString *base_);
- XString(decltype(really_construct_from_a_pointer) e, const char *s, const FString *base_);
+ XString(const char *b, const char *e, const RString *base_);
+ XString(decltype(really_construct_from_a_pointer) e, const char *s, const RString *base_);
XString(XPair p);
iterator begin() const;
iterator end() const;
- const FString *base() const;
+ const RString *base() const;
};
} // namespace strings
diff --git a/src/strings/zstring.cpp b/src/strings/zstring.cpp
index 0de836c..bfc0c96 100644
--- a/src/strings/zstring.cpp
+++ b/src/strings/zstring.cpp
@@ -26,16 +26,19 @@ namespace strings
{
*this = ZString("");
}
- ZString::ZString(const FString& s)
+ ZString::ZString(const RString& s)
+ : _b(&*s.begin()), _e(&*s.end()), _base(s.base())
+ {}
+ ZString::ZString(const AString& s)
: _b(&*s.begin()), _e(&*s.end()), _base(s.base())
{}
ZString::ZString(const TString& s)
: _b(&*s.begin()), _e(&*s.end()), _base(s.base())
{}
- ZString::ZString(const char *b, const char *e, const FString *base_)
+ ZString::ZString(const char *b, const char *e, const RString *base_)
: _b(b), _e(e), _base(base_)
{}
- ZString::ZString(decltype(really_construct_from_a_pointer), const char *s, const FString *base_)
+ ZString::ZString(decltype(really_construct_from_a_pointer), const char *s, const RString *base_)
: _b(s), _e(s + strlen(s)), _base(base_)
{}
@@ -47,7 +50,7 @@ namespace strings
{
return _e;
}
- const FString *ZString::base() const
+ const RString *ZString::base() const
{
return _base;
}
diff --git a/src/strings/zstring.hpp b/src/strings/zstring.hpp
index 72a227c..96aadc0 100644
--- a/src/strings/zstring.hpp
+++ b/src/strings/zstring.hpp
@@ -27,15 +27,16 @@ namespace strings
{
/// A non-owning string that is guaranteed to be NUL-terminated.
/// This should be only used as a parameter.
- class ZString : public _crtp_string<ZString, FString, ZPair>
+ class ZString : public _crtp_string<ZString, AString, ZPair>
{
iterator _b, _e;
// optional
- const FString *_base;
+ const RString *_base;
public:
ZString();
// no MString
- ZString(const FString& s);
+ ZString(const RString& s);
+ ZString(const AString& s);
ZString(const TString& s);
ZString(const SString&) = delete;
//ZString(ZString);
@@ -43,16 +44,16 @@ namespace strings
template<uint8_t n>
ZString(const VString<n>& s);
// dangerous
- ZString(const char *b, const char *e, const FString *base_);
- ZString(decltype(really_construct_from_a_pointer), const char *s, const FString *base_);
+ ZString(const char *b, const char *e, const RString *base_);
+ ZString(decltype(really_construct_from_a_pointer), const char *s, const RString *base_);
template<size_t n>
ZString(char (&s)[n]) = delete;
template<size_t n>
- ZString(const char (&s)[n], const FString *base_=nullptr);
+ ZString(const char (&s)[n], const RString *base_=nullptr);
iterator begin() const;
iterator end() const;
- const FString *base() const;
+ const RString *base() const;
const char *c_str() const;
};
diff --git a/src/strings/zstring.tcc b/src/strings/zstring.tcc
index 1065b7c..fe0e9f3 100644
--- a/src/strings/zstring.tcc
+++ b/src/strings/zstring.tcc
@@ -29,7 +29,7 @@ namespace strings
{}
template<size_t n>
- ZString::ZString(const char (&s)[n], const FString *base_)
+ ZString::ZString(const char (&s)[n], const RString *base_)
: _b(s), _e(s + strlen(s)), _base(base_)
{}
} // namespace strings