summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shared_string.hh32
-rw-r--r--src/unit_tests.cc4
2 files changed, 34 insertions, 2 deletions
diff --git a/src/shared_string.hh b/src/shared_string.hh
index 8af9820c..782f1674 100644
--- a/src/shared_string.hh
+++ b/src/shared_string.hh
@@ -14,6 +14,9 @@ struct StringStorage : UseMemoryDomain<MemoryDomain::SharedString>
int refcount;
int length;
+ StringStorage() = default;
+ constexpr StringStorage(int refcount, int length) : refcount(refcount), length(length) {}
+
[[gnu::always_inline]]
char* data() { return reinterpret_cast<char*>(this + 1); }
[[gnu::always_inline]]
@@ -40,8 +43,17 @@ struct StringStorage : UseMemoryDomain<MemoryDomain::SharedString>
StringStorage::operator delete(s, sizeof(StringStorage) + s->length + 1);
}
- friend void inc_ref_count(StringStorage* s, void*) { ++s->refcount; }
- friend void dec_ref_count(StringStorage* s, void*) { if (--s->refcount == 0) StringStorage::destroy(s); }
+ friend void inc_ref_count(StringStorage* s, void*)
+ {
+ if (s->refcount != -1)
+ ++s->refcount;
+ }
+
+ friend void dec_ref_count(StringStorage* s, void*)
+ {
+ if (s->refcount != -1 and --s->refcount == 0)
+ StringStorage::destroy(s);
+ }
};
inline RefPtr<StringStorage> operator"" _ss(const char* ptr, size_t len)
@@ -49,6 +61,22 @@ inline RefPtr<StringStorage> operator"" _ss(const char* ptr, size_t len)
return StringStorage::create({ptr, (int)len});
}
+template<size_t len>
+struct StaticStringStorage : StringStorage
+{
+ template<size_t... I> constexpr
+ StaticStringStorage(const char (&literal)[len], IndexSequence<I...>)
+ : StringStorage{-1, len}, data{literal[I]...} {}
+
+ const char data[len];
+};
+
+template<size_t len>
+constexpr StaticStringStorage<len> static_storage(const char (&literal)[len])
+{
+ return { literal, make_index_sequence<len>() };
+}
+
class SharedString : public StringView
{
public:
diff --git a/src/unit_tests.cc b/src/unit_tests.cc
index ec9bb64c..f7ec5eab 100644
--- a/src/unit_tests.cc
+++ b/src/unit_tests.cc
@@ -105,6 +105,8 @@ void test_utf8()
kak_assert(utf8::codepoint(str.begin() + 2, str.end()) == 0x00EF);
}
+constexpr auto ss_static_str = static_storage("yeehaa");
+
void test_string()
{
kak_assert(String("youpi ") + "matin" == "youpi matin");
@@ -137,6 +139,8 @@ void test_string()
kak_assert(subsequence_match("tchou kanaky", "knk"));
kak_assert(subsequence_match("tchou kanaky", "tchou kanaky"));
kak_assert(not subsequence_match("tchou kanaky", "tchou kanaky"));
+
+ kak_assert(ss_static_str.refcount == -1);
}
void test_keys()