8
8
#include " utf8.hh"
9
9
#include " vector.hh"
10
10
11
- #include < string>
11
+ #include < string.h >
12
12
#include < climits>
13
13
14
14
namespace Kakoune
@@ -94,9 +94,6 @@ constexpr ByteCount strlen(const char* s)
94
94
class String : public StringOps <String, char >
95
95
{
96
96
public:
97
- using Content = std::basic_string<char , std::char_traits<char >,
98
- Allocator<char , MemoryDomain::String>>;
99
-
100
97
String () {}
101
98
String (const char * content) : m_data(content, (size_t )(int )strlen(content)) {}
102
99
String (const char * content, ByteCount len) : m_data(content, (size_t )(int )len) {}
@@ -109,30 +106,78 @@ public:
109
106
String (const char * begin, const char * end) : m_data(begin, end-begin) {}
110
107
111
108
[[gnu::always_inline]]
112
- char * data () { return & m_data[ 0 ] ; }
109
+ char * data () { return m_data. data () ; }
113
110
114
111
[[gnu::always_inline]]
115
112
const char * data () const { return m_data.data (); }
116
113
117
114
[[gnu::always_inline]]
118
- ByteCount length () const { return m_data.length (); }
115
+ ByteCount length () const { return m_data.size (); }
119
116
120
117
[[gnu::always_inline]]
121
- const char * c_str () const { return m_data.c_str (); }
118
+ const char * c_str () const { return m_data.data (); }
122
119
123
120
[[gnu::always_inline]]
124
121
void append (const char * data, ByteCount count) { m_data.append (data, (size_t )(int )count); }
125
122
126
123
void clear () { m_data.clear (); }
127
124
128
- void push_back (char c) { m_data.push_back (c ); }
129
- void resize (ByteCount size) { m_data.resize ((size_t )(int )size); }
125
+ void push_back (char c) { m_data.append (&c, 1 ); }
126
+ void force_size (ByteCount size) { m_data.force_size ((size_t )(int )size); }
130
127
void reserve (ByteCount size) { m_data.reserve ((size_t )(int )size); }
131
128
132
129
static const String ms_empty;
133
130
131
+ union Data
132
+ {
133
+ using Alloc = Allocator<char , MemoryDomain::String>;
134
+
135
+ struct Long
136
+ {
137
+ char * ptr;
138
+ size_t size;
139
+ size_t capacity;
140
+ } l;
141
+
142
+ struct Short
143
+ {
144
+ static constexpr size_t capacity = sizeof (Long) - 2 ;
145
+ char string[capacity+1 ];
146
+ unsigned char size;
147
+ } s;
148
+
149
+ Data () { set_empty (); }
150
+ Data (const char * data, size_t size, size_t capacity);
151
+ Data (const char * data, size_t size) : Data (data, size, size) {}
152
+ Data (const Data& other) : Data{other.data (), other.size ()} {}
153
+
154
+ ~Data () { release (); }
155
+ Data (Data&& other) noexcept ;
156
+ Data& operator =(const Data& other);
157
+ Data& operator =(Data&& other) noexcept ;
158
+
159
+ bool is_long () const { return (s.size & 1 ) == 0 ; }
160
+ size_t size () const { return is_long () ? l.size : (s.size >> 1 ); }
161
+ size_t capacity () const { return is_long () ? l.capacity : Short::capacity; }
162
+
163
+ const char * data () const { return is_long () ? l.ptr : s.string ; }
164
+ char * data () { return is_long () ? l.ptr : s.string ; }
165
+
166
+ template <bool copy = true >
167
+ void reserve (size_t new_capacity);
168
+ void force_size (size_t new_size);
169
+ void append (const char * str, size_t len);
170
+ void clear ();
171
+
172
+ private:
173
+ void release ();
174
+ void set_empty () { s.size = 1 ; }
175
+ void set_size (size_t size);
176
+ void set_short (const char * data, size_t size);
177
+ };
178
+
134
179
private:
135
- Content m_data;
180
+ Data m_data;
136
181
};
137
182
138
183
class StringView : public StringOps <StringView, const char >
@@ -162,12 +207,12 @@ public:
162
207
if (*end == ' \0 ' )
163
208
unowned = begin;
164
209
else
165
- owned = String::Content (begin, end);
210
+ owned = String::Data (begin, end - begin );
166
211
}
167
- operator const char *() const { return unowned ? unowned : owned.c_str (); }
212
+ operator const char *() const { return unowned ? unowned : owned.data (); }
168
213
169
214
private:
170
- String::Content owned;
215
+ String::Data owned;
171
216
const char * unowned = nullptr ;
172
217
173
218
};
0 commit comments