Skip to content

Commit 13f16f2

Browse files
committed
AK: Use a null value for Optional<(Fly)String>s empty value
Akin to LadybirdBrowser/ladybird@2457118
1 parent 87012d3 commit 13f16f2

File tree

4 files changed

+31
-2
lines changed

4 files changed

+31
-2
lines changed

Diff for: AK/FlyString.h

+12
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515

1616
namespace AK {
1717

18+
template<>
19+
struct Traits<FlyString>;
20+
1821
class FlyString {
1922
AK_MAKE_DEFAULT_MOVABLE(FlyString);
2023
AK_MAKE_DEFAULT_COPYABLE(FlyString);
@@ -79,6 +82,12 @@ class FlyString {
7982
return (... || this->operator==(forward<Ts>(strings)));
8083
}
8184

85+
FlyString(Badge<Optional<FlyString>>)
86+
: m_data(nullptr)
87+
{
88+
}
89+
ALWAYS_INLINE constexpr bool is_null(Badge<Traits<FlyString>> badge) { return m_data.is_null(move(badge)); }
90+
8291
private:
8392
explicit FlyString(Detail::StringBase data)
8493
: m_data(move(data))
@@ -91,6 +100,9 @@ class FlyString {
91100
template<>
92101
struct Traits<FlyString> : public DefaultTraits<FlyString> {
93102
static unsigned hash(FlyString const&);
103+
104+
constexpr static auto special_optional_empty_value(Badge<Optional<FlyString>> badge) { return FlyString(move(badge)); }
105+
constexpr static bool optional_has_value(String const& str) { return !str.is_null(Badge<Traits<FlyString>> {}); }
94106
};
95107

96108
template<>

Diff for: AK/String.h

+8
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ class String : public Detail::StringBase {
202202
requires(IsSame<RemoveCVReference<T>, StringView>)
203203
static ErrorOr<String> from_byte_string(T&&) = delete;
204204

205+
constexpr String(Badge<Optional<String>>)
206+
: StringBase(nullptr)
207+
{
208+
}
209+
205210
private:
206211
friend class ::AK::FlyString;
207212

@@ -216,6 +221,9 @@ class String : public Detail::StringBase {
216221
template<>
217222
struct Traits<String> : public DefaultTraits<String> {
218223
static unsigned hash(String const&);
224+
225+
constexpr static auto special_optional_empty_value(Badge<Optional<String>> badge) { return String(move(badge)); }
226+
constexpr static bool optional_has_value(String const& str) { return !str.is_null(Badge<Traits<String>> {}); }
219227
};
220228

221229
template<>

Diff for: AK/StringBase.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ ErrorOr<StringBase> StringBase::substring_from_byte_offset_with_shared_superstri
117117

118118
void StringBase::destroy_string()
119119
{
120-
if (!is_short_string())
120+
if (!is_short_string() && m_raw != 0)
121121
m_data->unref();
122122
}
123123

Diff for: AK/StringBase.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,17 @@ class StringBase {
6969

7070
[[nodiscard]] bool operator==(StringBase const&) const;
7171

72-
[[nodiscard]] ALWAYS_INLINE FlatPtr raw(Badge<FlyString>) const { return bit_cast<FlatPtr>(m_data); }
72+
[[nodiscard]] ALWAYS_INLINE FlatPtr raw(Badge<FlyString>) const { return m_raw; }
73+
template<OneOf<String, FlyString> T>
74+
[[nodiscard]] ALWAYS_INLINE constexpr bool is_null(Badge<Traits<T>>) const { return m_raw; }
7375

7476
protected:
77+
// For Optional
78+
constexpr explicit StringBase(nullptr_t)
79+
: m_raw { 0 }
80+
{
81+
}
82+
7583
template<typename Func>
7684
ErrorOr<void> replace_with_new_string(size_t byte_count, Func&& callback)
7785
{
@@ -124,6 +132,7 @@ class StringBase {
124132
union {
125133
ShortString m_short_string;
126134
Detail::StringData const* m_data { nullptr };
135+
FlatPtr m_raw;
127136
};
128137
};
129138

0 commit comments

Comments
 (0)