@@ -94,7 +94,7 @@ class varint
94
94
}
95
95
};
96
96
97
- static constinit char sz_empty[ 1 ] = { ' \0 ' };
97
+ static constinit char sz_empty = { ' \0 ' };
98
98
99
99
} // (anon)
100
100
@@ -130,21 +130,24 @@ struct String::Impl
130
130
}
131
131
};
132
132
133
- auto
133
+ void
134
134
String::
135
135
allocate (
136
- std::string_view s) ->
137
- Impl*
136
+ std::string_view s,
137
+ Impl*& impl,
138
+ char const *& psz)
138
139
{
139
140
std::allocator<Impl> alloc;
140
- varint<std::size_t > uv (s.size ());
141
+ varint<std::size_t > uv (s.size ());
142
+ auto const varlen = uv.get ().size ();
141
143
auto n =
142
144
sizeof (Impl) + // header
143
- uv. get (). size () + // size (varint)
145
+ varlen + // size (varint)
144
146
s.size () + // string data
145
147
1 + // null term '\0'
146
148
(sizeof (Impl) - 1 ); // round up to nearest sizeof(Impl)
147
- return new (alloc.allocate (n / sizeof (Impl))) Impl (s, uv);
149
+ impl = new (alloc.allocate (n / sizeof (Impl))) Impl (s, uv);
150
+ psz = reinterpret_cast <char const *>(impl + 1 ) + varlen;
148
151
}
149
152
150
153
void
@@ -155,9 +158,10 @@ deallocate(
155
158
std::allocator<Impl> alloc;
156
159
auto const s = impl->get ();
157
160
varint<std::size_t > uv (s.size ());
161
+ auto const varlen = uv.get ().size ();
158
162
auto n =
159
163
sizeof (Impl) + // header
160
- uv. get (). size () + // size (varint)
164
+ varlen + // size (varint)
161
165
s.size () + // string data
162
166
1 + // null term '\0'
163
167
(sizeof (Impl) - 1 ); // round up to nearest sizeof(Impl)
@@ -170,7 +174,7 @@ deallocate(
170
174
String::
171
175
~String ()
172
176
{
173
- if (! impl_ )
177
+ if (is_literal () )
174
178
return ;
175
179
if (--impl_->refs > 0 )
176
180
return ;
@@ -179,7 +183,8 @@ String::
179
183
180
184
String::
181
185
String () noexcept
182
- : psz_(&sz_empty[0 ])
186
+ : len_(len(0 ))
187
+ , psz_(&sz_empty)
183
188
{
184
189
}
185
190
@@ -197,15 +202,16 @@ String(
197
202
: impl_(other.impl_)
198
203
, psz_(other.psz_)
199
204
{
200
- if (impl_ )
205
+ if (! is_literal () )
201
206
++impl_->refs ;
202
207
}
203
208
204
209
String::
205
210
String (
206
211
std::string_view s)
207
- : impl_(allocate(s))
208
212
{
213
+ allocate (s, impl_, psz_);
214
+ MRDOX_ASSERT (! is_literal ());
209
215
}
210
216
211
217
String&
@@ -228,21 +234,14 @@ operator=(
228
234
return *this ;
229
235
}
230
236
231
- bool
232
- String::
233
- empty () const noexcept
234
- {
235
- if (impl_)
236
- return impl_->get ().size () == 0 ;
237
- return psz_[0 ] == ' \0 ' ;
238
- }
239
-
240
237
std::string_view
241
238
String::
242
239
get () const noexcept
243
240
{
244
- if (psz_)
245
- return std::string_view (psz_);
241
+ if (is_literal ())
242
+ return std::string_view (psz_,
243
+ (len_ & ((std::size_t (-1 ) >> 1 ) & ~std::size_t (1 ))) |
244
+ (len_ >> (sizeof (std::size_t )*8 - 1 )));
246
245
return impl_->get ();
247
246
}
248
247
0 commit comments