File Coverage

t/string_test.h
Criterion Covered Total %
statement 2155 2155 100.0
branch 7877 16574 47.5
condition n/a
subroutine n/a
pod n/a
total 10032 18729 53.5


line stmt bran cond sub pod time code
1             #pragma once
2             #include "test.h"
3             #include
4             #include
5              
6             namespace test {
7              
8             using namespace panda;
9              
10             template
11             struct test_string {
12             using Allocator = typename test::Allocator;
13             using String = panda::basic_string, Allocator>;
14             using String2 = panda::basic_string, test::Allocator>;
15             using StdString = std::basic_string;
16             using ExternalShared = typename String::ExternalShared;
17             template using AnyString = panda::basic_string, A>;
18              
19             static const size_t MAX_SSO_CHARS = String::MAX_SSO_CHARS;
20             static const size_t BUF_CHARS = (sizeof(size_t) + sizeof(uint32_t)) / sizeof(T);
21             static const size_t EBUF_CHARS = 4*sizeof(void*)/sizeof(T);
22             static const size_t CHAR_SIZE = sizeof(T);
23             static const T LITERAL[38];
24             static const size_t LITERAL_LEN = sizeof(LITERAL)/sizeof(T)-1;
25             static const T EMPTY[1];
26              
27 37           static size_t slen (const T* src) {
28 37           size_t cnt = 0;
29 37 50         while (*src++) ++cnt;
30 37           return cnt;
31             }
32              
33 548           template static void REQUIRE_STR (const AnyString& str, const T* src, size_t len, size_t cap, size_t shcap) {
34 548 50         REQUIRE(str.length() == len);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
35 548 50         CHECK(std::basic_string(str.data(), len) == std::basic_string(src, len));
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
36 548 50         CHECK(str.capacity() == cap);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
37 548 50         CHECK(str.shared_capacity() == shcap);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
38 548           }
39 210           template static void REQUIRE_STR (const AnyString& str, const T* src, size_t len, size_t cap) { REQUIRE_STR(str, src, len, cap, cap); }
40 74           template static void REQUIRE_STR (const AnyString& str, const T* src, size_t len) { REQUIRE_STR(str, src, len, len); }
41 74           template static void REQUIRE_STR (const AnyString& str, const T* src) { REQUIRE_STR(str, src, slen(src)); }
42 886           template static void REQUIRE_STR (const AnyString& str, StdString src, size_t cap, size_t shcap) { REQUIRE_STR(str, src.data(), src.size(), cap, shcap); }
43 315 50         template static void REQUIRE_STR (const AnyString& str, StdString src, size_t cap) { REQUIRE_STR(str, src, cap, cap); }
    50          
44 133 50         template static void REQUIRE_STR (const AnyString& str, StdString src) { REQUIRE_STR(str, src, src.size()); }
    50          
45 71 50         template static void REQUIRE_STRM (const AnyString& str, StdString src) { REQUIRE_STR(str, src, str.capacity(), str.shared_capacity()); }
46              
47 529           static void CHECK_ALLOCS (int allocated_cnt = 0, int allocated = 0, int deallocated_cnt = 0, int deallocated = 0, int reallocated_cnt = 0, int reallocated = 0, int ext_deallocated_cnt = 0, int ext_deallocated = 0, int ext_shbuf_deallocated = 0) {
48 529           auto stat = get_allocs();
49 529 50         CHECK(stat.allocated_cnt == allocated_cnt);
    50          
    50          
    50          
    50          
    0          
    0          
50 529 50         CHECK(stat.allocated == allocated);
    50          
    50          
    50          
    50          
    0          
    0          
51 529 50         CHECK(stat.deallocated_cnt == deallocated_cnt);
    50          
    50          
    50          
    50          
    0          
    0          
52 529 50         CHECK(stat.deallocated == deallocated);
    50          
    50          
    50          
    50          
    0          
    0          
53 529 50         CHECK(stat.reallocated_cnt == reallocated_cnt);
    50          
    50          
    50          
    50          
    0          
    0          
54 529 50         CHECK(stat.reallocated == reallocated);
    50          
    50          
    50          
    50          
    0          
    0          
55 529 50         CHECK(stat.ext_deallocated_cnt == ext_deallocated_cnt);
    50          
    50          
    50          
    50          
    0          
    0          
56 529 50         CHECK(stat.ext_deallocated == ext_deallocated);
    50          
    50          
    50          
    50          
    0          
    0          
57 529 50         CHECK(stat.ext_shbuf_deallocated == ext_shbuf_deallocated);
    50          
    50          
    50          
    50          
    0          
    0          
58 529           }
59              
60 1151           static StdString mstr (const char* data, size_t count = 1) {
61 1151           StdString ret;
62 17633 100         for (size_t i = 0; i < count; ++i) {
63 16482           const char* ptr = data;
64 41109 100         while (*ptr) ret += (T)*ptr++;
    50          
65             }
66 1151           return ret;
67             }
68              
69             // temporary return value, only immediate use, no assigments!
70 565           static const T* cstr (const char* data, size_t count = 1) {
71             static T dest[100000];
72 1130 50         auto s = mstr(data, count);
73 565 50         s.copy(dest, s.size());
74 565           dest[s.size()] = (T)0;
75 565           return dest;
76             }
77              
78             // temporary return value, only immediate use, no assigments!
79 4           static basic_string_view svstr (const char* data, size_t count = 1) {
80 4           return basic_string_view(cstr(data, count));
81             }
82              
83 112           static T* extstr (StdString src, size_t cap = 0) {
84 112 50         if (cap < src.size()) cap = src.size();
85 112           T* ext = (T*)malloc(cap * sizeof(T));
86 112           std::memcpy(ext, src.data(), cap * sizeof(T));
87 112           return ext;
88             }
89              
90 4           static ExternalShared* shared_buf_alloc () {
91 4           return (ExternalShared*)panda::DynamicMemoryPool::instance()->allocate(sizeof(ExternalShared));
92             }
93              
94 78 50         template static U create_external (StdString exp, size_t cap) { return U(extstr(exp), exp.size(), cap, &Allocator::ext_free); }
    50          
95 78 50         template static U create_external (StdString exp) { return create_external(exp, exp.size()); }
    50          
96 2           template static U create_external_cbuf (StdString exp, size_t cap) { return U(extstr(exp), exp.size(), cap, &Allocator::ext_free, shared_buf_alloc(), &Allocator::shared_buf_free); }
97 1 50         template static U create_external_cbuf (StdString exp) { return create_external_cbuf(exp, exp.size()); }
98              
99 10 50         static void assign_external (String& s, StdString exp, size_t cap) { s.assign(extstr(exp), exp.size(), cap, &Allocator::ext_free); }
100 10 50         static void assign_external (String& s, StdString exp) { assign_external(s, exp, exp.size()); }
101 2 50         static void assign_external_cbuf (String& s, StdString exp, size_t cap) { s.assign(extstr(exp), exp.size(), cap, &Allocator::ext_free, shared_buf_alloc(), &Allocator::shared_buf_free); }
102 2 50         static void assign_external_cbuf (String& s, StdString exp) { assign_external_cbuf(s, exp, exp.size()); }
103              
104 11           static void test_ctor () {
105 22 50         auto defexp = mstr("this string is definitely longer than max sso chars");
106 11           auto defsz = BUF_CHARS + defexp.size();
107              
108 12 50         SECTION("empty") {
    50          
    50          
    50          
    100          
109             {
110 2           String s;
111 1 50         REQUIRE_STR(s, EMPTY);
112             }
113 1 50         CHECK_ALLOCS();
114             };
115              
116 12 50         SECTION("literal") {
    50          
    50          
    50          
    100          
117             {
118 2           String s(LITERAL);
119 1 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
120             }
121 1 50         CHECK_ALLOCS();
122             };
123              
124              
125 12 50         SECTION("sso") {
    50          
    50          
    50          
    100          
126 2           StdString cur;
127              
128 7 100         while (cur.size() <= MAX_SSO_CHARS) {
129 12 50         String s(cur.data(), cur.size());
130 6 50         REQUIRE_STR(s, cur, MAX_SSO_CHARS);
    50          
131 6 50         if (cur.size() == defexp.size()) throw "should not happen";
132 6 50         cur += defexp[cur.size()];
133             }
134 1 50         CHECK_ALLOCS();
135              
136 1           auto sz = BUF_CHARS + cur.size();
137             {
138 2 50         String s(cur.data(), cur.size());
139 1 50         REQUIRE_STR(s, cur);
    50          
140 1 50         CHECK_ALLOCS(1, sz);
141             }
142 1 50         CHECK_ALLOCS(0, 0, 1, sz);
143             }
144              
145              
146 12 50         SECTION("internal with len") {
    50          
    50          
    50          
    100          
147             {
148 2 50         String s(defexp.data(), defexp.size());
149 1 50         REQUIRE_STR(s, defexp);
    50          
150             }
151 1 50         CHECK_ALLOCS(1, defsz, 1, defsz);
152             }
153              
154 12 50         SECTION("internal without len") {
    50          
    50          
    50          
    100          
155             {
156 2 50         String s(defexp.c_str());
157 1 50         REQUIRE_STR(s, defexp);
    50          
158             }
159 1 50         CHECK_ALLOCS(1, defsz, 1, defsz);
160             }
161              
162 12 50         SECTION("external") {
    50          
    50          
    50          
    100          
163             {
164 2 50         String s(extstr(defexp), defexp.size(), defexp.size(), &Allocator::ext_free);
    50          
165 1 50         REQUIRE_STR(s, defexp);
    50          
166             }
167 1 50         CHECK_ALLOCS(1, EBUF_CHARS, 1, EBUF_CHARS, 0, 0, 1, defexp.size());
168             }
169              
170 12 50         SECTION("external with custom buf") {
    50          
    50          
    50          
    100          
171             {
172 2 50         String s(extstr(defexp), defexp.size(), defexp.size(), &Allocator::ext_free, shared_buf_alloc(), &Allocator::shared_buf_free);
    50          
    50          
173 1 50         REQUIRE_STR(s, defexp);
    50          
174 1 50         CHECK_ALLOCS();
175             }
176 1 50         CHECK_ALLOCS(0, 0, 0, 0, 0, 0, 1, defexp.size(), 1);
177             }
178              
179 13 50         SECTION("fill") {
    50          
    50          
    50          
    100          
180 3 50         SECTION("sso") {
    50          
    50          
    50          
    100          
181             {
182 2 50         auto exp = mstr("aa");
183 2 50         String s(exp.size(), (T)'a');
184 1 50         REQUIRE_STR(s, exp, MAX_SSO_CHARS);
    50          
185             }
186 1 50         CHECK_ALLOCS();
187             };
188 3 50         SECTION("internal") {
    50          
    50          
    50          
    100          
189 2 50         auto exp = mstr("B", 50);
190             {
191 2 50         String s(exp.size(), (T)'B');
192 1 50         REQUIRE_STR(s, exp);
    50          
193             }
194 1           auto sz = BUF_CHARS + exp.size();
195 1 50         CHECK_ALLOCS(1, sz, 1, sz);
196             };
197             };
198              
199 13 50         SECTION("new capacity") {
    50          
    50          
    50          
    100          
200 3 50         SECTION("sso") {
    50          
    50          
    50          
    100          
201             {
202 2 50         String s(2);
203 1 50         REQUIRE_STR(s, EMPTY, 0, MAX_SSO_CHARS);
204             }
205 1 50         CHECK_ALLOCS();
206             };
207 3 50         SECTION("internal") {
    50          
    50          
    50          
    100          
208             {
209 2 50         String s(50);
210 1 50         REQUIRE_STR(s, EMPTY, 0, 50);
211             }
212 1           auto sz = BUF_CHARS + 50;
213 1 50         CHECK_ALLOCS(1, sz, 1, sz);
214             };
215             };
216 11           }
217              
218             template
219 10           static void test_copy_ctor () {
220 12 50         SECTION("from empty") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
221             {
222 4           FString src;
223 4 50         String s(src);
    50          
224 2 50         REQUIRE_STR(src, EMPTY);
    50          
225 2 50         REQUIRE_STR(s, EMPTY);
    50          
226 2 50         REQUIRE(src.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
227             }
228 2 50         CHECK_ALLOCS();
    50          
229             }
230 12 50         SECTION("from literal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
231             {
232 4           FString src(LITERAL);
233 4 50         String s(src);
    50          
234 2 50         REQUIRE_STR(src, LITERAL, LITERAL_LEN, 0);
    50          
235 2 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
    50          
236 2 50         REQUIRE(src.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
237             }
238 2 50         CHECK_ALLOCS();
    50          
239             }
240 12 50         SECTION("from sso") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
241             {
242 4 50         auto exp = mstr("bu");
    50          
243 4 50         FString src(exp.c_str());
    50          
244 4 50         String s(src);
    50          
245 2 50         REQUIRE_STR(src, exp, MAX_SSO_CHARS);
    50          
    50          
    50          
246 2 50         REQUIRE_STR(s, exp, MAX_SSO_CHARS);
    50          
    50          
    50          
247 2 50         REQUIRE(src.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
248             }
249 2 50         CHECK_ALLOCS();
    50          
250             }
251 12 50         SECTION("from internal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
252 4 50         auto exp = mstr("bu", 50);
    50          
253 2           auto sz = BUF_CHARS + exp.size();
254             {
255 4 50         FString src(exp.c_str());
    50          
256 2 50         CHECK_ALLOCS(1, sz);
    50          
257             {
258 4 50         String s(src);
    50          
259 2 50         REQUIRE_STR(src, exp, 0, exp.size());
    50          
    50          
    50          
260 2 50         REQUIRE_STR(s, exp, 0, exp.size());
    50          
    50          
    50          
261 2 50         CHECK_ALLOCS();
    50          
262 2 50         REQUIRE(src.use_count() == 2);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
263             }
264 2 50         CHECK_ALLOCS();
    50          
265             }
266 2 50         CHECK_ALLOCS(0, 0, 1, sz);
    50          
267             }
268 12 50         SECTION("from external") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
269 4 50         auto exp = mstr("c", 50);
    50          
270             {
271 4 50         FString src(extstr(exp), exp.size(), exp.size(), &Allocator::ext_free);
    50          
    50          
    50          
272 2 50         CHECK_ALLOCS(1, EBUF_CHARS);
    50          
273             {
274 4 50         String s(src);
    50          
275 2 50         REQUIRE_STR(src, exp, 0, exp.size());
    50          
    50          
    50          
276 2 50         REQUIRE_STR(s, exp, 0, exp.size());
    50          
    50          
    50          
277 2 50         CHECK_ALLOCS();
    50          
278 2 50         REQUIRE(src.use_count() == 2);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
279             }
280 2 50         CHECK_ALLOCS();
    50          
281             }
282 2 50         CHECK_ALLOCS(0, 0, 1, EBUF_CHARS, 0, 0, 1, exp.size());
    50          
283             }
284 10           }
285              
286             template
287 10           static void test_move_ctor () {
288 12 50         SECTION("from empty") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
289             {
290 4           FString src;
291 4 50         String s(std::move(src));
    50          
292 2 50         REQUIRE_STR(src, EMPTY);
    50          
293 2 50         REQUIRE_STR(s, EMPTY);
    50          
294             }
295 2 50         CHECK_ALLOCS();
    50          
296             }
297 12 50         SECTION("from literal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
298             {
299 4           FString src(LITERAL);
300 4 50         String s(std::move(src));
    50          
301 2 50         REQUIRE_STR(src, EMPTY);
    50          
302 2 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
    50          
303             }
304 2 50         CHECK_ALLOCS();
    50          
305             }
306 12 50         SECTION("from sso") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
307             {
308 4 50         auto exp = mstr("bu");
    50          
309 4 50         FString src(exp.c_str());
    50          
310 4 50         String s(std::move(src));
    50          
311 2 50         REQUIRE_STR(src, EMPTY);
    50          
312 2 50         REQUIRE_STR(s, exp, MAX_SSO_CHARS);
    50          
    50          
    50          
313             }
314 2 50         CHECK_ALLOCS();
    50          
315             }
316 12 50         SECTION("from internal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
317 4 50         auto exp = mstr("bu", 50);
    50          
318 2           auto sz = BUF_CHARS + exp.size();
319             {
320 4 50         FString src(exp.data(), exp.size());
    50          
321 2 50         CHECK_ALLOCS(1,sz);
    50          
322 4 50         String s(std::move(src));
    50          
323 2 50         REQUIRE_STR(src, EMPTY);
    50          
324 2 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
325 2 50         CHECK_ALLOCS();
    50          
326             }
327 2 50         CHECK_ALLOCS(0,0,1,sz);
    50          
328             }
329 12 50         SECTION("from external") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
330 4 50         auto exp = mstr("c", 50);
    50          
331             {
332 4 50         FString src(extstr(exp), exp.size(), exp.size(), &Allocator::ext_free);
    50          
    50          
    50          
333 2 50         CHECK_ALLOCS(1,EBUF_CHARS);
    50          
334 4 50         String s(std::move(src));
    50          
335 2 50         REQUIRE_STR(src, EMPTY);
    50          
336 2 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
337 2 50         CHECK_ALLOCS();
    50          
338             }
339 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp.size());
    50          
340             }
341 10           }
342              
343             template
344 12           static void test_copy_ctor_offset () {
345 14 50         SECTION("from literal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
346             {
347 4 50         auto exp = StdString(LITERAL).substr(2, 25);
    50          
    50          
    50          
348 4           FString src(LITERAL);
349 4 50         String s(src, 2, 25);
    50          
350 2 50         REQUIRE_STR(src, LITERAL, LITERAL_LEN, 0);
    50          
351 2 50         REQUIRE_STR(s, exp, 0);
    50          
    50          
    50          
352             }
353 2 50         CHECK_ALLOCS();
    50          
354             }
355 14 50         SECTION("from sso") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
356             {
357 4 50         auto exp = mstr("bu");
    50          
358 4 50         FString src(exp.c_str());
    50          
359 4 50         String s(src, 1, 1);
    50          
360 2 50         REQUIRE_STR(src, exp, MAX_SSO_CHARS);
    50          
    50          
    50          
361 2 50         REQUIRE_STR(s, mstr("u"), MAX_SSO_CHARS-1);
    50          
    50          
    50          
362             }
363 2 50         CHECK_ALLOCS();
    50          
364             }
365 14 50         SECTION("from internal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
366 4 50         auto exp = mstr("bu", 50);
    50          
367 2           auto sz = BUF_CHARS + exp.size();
368             {
369 4 50         FString src(exp.c_str());
    50          
370 2 50         CHECK_ALLOCS(1, sz);
    50          
371 4 50         String s(src, 9, 5);
    50          
372 2 50         REQUIRE_STR(src, exp, 0, exp.size());
    50          
    50          
    50          
373 2 50         REQUIRE_STR(s, mstr("ububu"), 0, exp.size()-9);
    50          
    50          
    50          
374 2 50         CHECK_ALLOCS();
    50          
375             }
376 2 50         CHECK_ALLOCS(0,0,1,sz);
    50          
377             }
378 14 50         SECTION("from external") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
379 4 50         auto exp = mstr("c", 50);
    50          
380             {
381 4 50         FString src(extstr(exp), exp.size(), exp.size(), &Allocator::ext_free);
    50          
    50          
    50          
382 2 50         CHECK_ALLOCS(1, EBUF_CHARS);
    50          
383 4 50         String s(src, 10, 30);
    50          
384 2 50         REQUIRE_STR(src, exp, 0, exp.size());
    50          
    50          
    50          
385 2 50         REQUIRE_STR(s, mstr("c", 30), 0, exp.size()-10);
    50          
    50          
    50          
386 2 50         CHECK_ALLOCS();
    50          
387             }
388 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp.size());
    50          
389             }
390 16 50         SECTION("out of bounds") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
391 8 50         auto exp = mstr("hello");
    50          
392 8 50         FString src(exp.c_str());
    50          
393 6 50         SECTION("too big length acts as npos") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
394 4 50         String s(src, 3, 10);
    50          
395 2 50         REQUIRE_STRM(s, mstr("lo"));
    50          
    50          
    50          
396             }
397 6 50         SECTION("too big offset throws exception") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
398 2 50         REQUIRE_THROWS(String(src, 6, 10));
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
399             }
400             }
401 12           }
402              
403 1           static void test_substr () {
404 2 50         auto exp = mstr("hello world, hello world!");
405 2 50         String src(exp.c_str());
406 2 50         String s = src.substr(0, 5);
407 1 50         REQUIRE_STR(s, mstr("hello"), 0, exp.size());
    50          
408 1 50         s = src.substr(6);
    50          
409 1 50         REQUIRE_STR(s, mstr("world, hello world!"), 0, exp.size()-6);
    50          
410 1 50         s = src.substr(4, 3);
    50          
411 1 50         REQUIRE_STR(s, mstr("o w"), 0, exp.size()-4);
    50          
412 1 50         REQUIRE_STR(src, exp, 0, exp.size());
    50          
413 1           }
414              
415 4           static void test_clear () {
416 5 50         SECTION("literal") {
    50          
    50          
    50          
    100          
417             {
418 2           String s(LITERAL);
419 1           s.clear();
420 1 50         REQUIRE_STR(s, EMPTY);
421             }
422 1 50         CHECK_ALLOCS();
423             }
424 5 50         SECTION("sso") {
    50          
    50          
    50          
    100          
425             {
426 2 50         auto exp = mstr("bu");
427 2 50         String s(exp.c_str());
428 1           s.clear();
429 1 50         REQUIRE_STR(s, EMPTY, 0, MAX_SSO_CHARS);
430             }
431 1 50         CHECK_ALLOCS();
432             }
433 5 50         SECTION("internal") {
    50          
    50          
    50          
    100          
434 2 50         auto exp = mstr("bu", 50);
435             {
436 2 50         String s(exp.c_str());
437 1           get_allocs();
438 1           s.clear();
439 1 50         REQUIRE_STR(s, EMPTY, 0, exp.size());
440             }
441 1 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+exp.size());
442             }
443 5 50         SECTION("external") {
    50          
    50          
    50          
    100          
444 2 50         auto exp = mstr("c", 50);
445             {
446 2 50         String s(extstr(exp), exp.size(), exp.size(), &Allocator::ext_free);
    50          
447 1           get_allocs();
448 1           s.clear();
449 1 50         CHECK_ALLOCS();
450 1 50         REQUIRE_STR(s, EMPTY, 0, exp.size());
451             }
452 1 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp.size());
453             };
454 4           }
455              
456 20           struct AssignLiteral { template static void op (String& s, const T (&val)[U]) { s.assign(val); } };
457 20           struct OpAssignLiteral { template static void op (String& s, const T (&val)[U]) { s = val; } };
458 48           struct AssignPtr { static void op (String& s, const T* val) { s.assign(val); } };
459 48           struct OpAssignPtr { static void op (String& s, const T* val) { s = val; } };
460             struct AssignCopy {
461 12           static void op (String& s, const String& val) { s.assign(val); }
462 8           static void op (String& s, const String2& val) { s.assign(val); }
463             };
464             struct OpAssignCopy {
465 12           static void op (String& s, const String& val) { s = val; }
466 8           static void op (String& s, const String2& val) { s = val; }
467             };
468             struct AssignMove {
469 12           static void op (String& s, String& val) { s.assign(std::move(val)); }
470 8           static void op (String& s, String2& val) { s.assign(std::move(val)); }
471             };
472             struct OpAssignMove {
473 12           static void op (String& s, String& val) { s = std::move(val); }
474 8           static void op (String& s, String2& val) { s = std::move(val); }
475             };
476              
477             template
478 20           static void test_assign_literal () {
479 24 50         SECTION("from empty") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
480             {
481 8           String s;
482 4 50         U::op(s, LITERAL);
    50          
483 4 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
    50          
484             }
485 4 50         CHECK_ALLOCS();
    50          
486             }
487 24 50         SECTION("from literal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
488             {
489 4           const T exp[] = {'h', 'e', 'l', 'l', 'o', 0};
490 4           const size_t exp_len = sizeof(exp) / sizeof(T) - 1;
491 8           String s(exp);
492 4 50         REQUIRE_STR(s, exp, exp_len, 0);
    50          
493 4 50         U::op(s, LITERAL);
    50          
494 4 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
    50          
495             }
496 4 50         CHECK_ALLOCS();
    50          
497             }
498 24 50         SECTION("from sso") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
499             {
500 8 50         auto exp = mstr("bu");
    50          
501 8 50         String s(exp.c_str());
    50          
502 4 50         U::op(s, LITERAL);
    50          
503 4 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
    50          
504             }
505 4 50         CHECK_ALLOCS();
    50          
506             }
507 24 50         SECTION("from internal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
508             {
509 8 50         auto exp = mstr("a", 50);
    50          
510 4           auto sz = BUF_CHARS + exp.size();
511 8 50         String s(exp.c_str());
    50          
512 4 50         CHECK_ALLOCS(1,sz);
    50          
513 4 50         U::op(s, LITERAL);
    50          
514 4 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
    50          
515 4 50         CHECK_ALLOCS(0,0,1,sz);
    50          
516             }
517 4 50         CHECK_ALLOCS();
    50          
518             }
519 24 50         SECTION("from external") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
520             {
521 8 50         auto exp = mstr("c", 50);
    50          
522 8 50         String s(extstr(exp), exp.size(), exp.size(), &Allocator::ext_free);
    50          
    50          
    50          
523 4 50         CHECK_ALLOCS(1, EBUF_CHARS);
    50          
524 4 50         U::op(s, LITERAL);
    50          
525 4 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
    50          
526 4 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp.size());
    50          
527             }
528 4 50         CHECK_ALLOCS();
    50          
529             }
530 20           }
531              
532             template
533 28           static void test_assign_ptr () {
534 36 50         SECTION("from literal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
535 16 50         auto exp = mstr("0", 50);
    50          
536 16           String s(LITERAL);
537 12 50         SECTION("no len") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
538 4 50         U::op(s, exp.c_str());
    50          
539 4 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
540 4 50         CHECK_ALLOCS(1,BUF_CHARS+exp.size());
    50          
541 4 50         s = EMPTY;
    50          
542 4 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+exp.size());
    50          
543             }
544 12 50         SECTION("with len") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
545 4 50         s.assign(exp.data(), 40);
    50          
546 4 50         CHECK_ALLOCS(1,BUF_CHARS+40);
    50          
547 4 50         REQUIRE_STR(s, exp.data(), 40, 40);
    50          
548 4 50         s = EMPTY;
    50          
549 4 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+40);
    50          
550             }
551              
552             }
553 32 50         SECTION("from sso") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
554 8 50         auto exp = mstr("1", 50);
    50          
555 8 50         String s(cstr("yt"));
    50          
    50          
    50          
556 4 50         U::op(s, exp.c_str());
    50          
557 4 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
558 4 50         CHECK_ALLOCS(1,BUF_CHARS+exp.size());
    50          
559 4 50         s = EMPTY;
    50          
560 4 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+exp.size());
    50          
561             }
562 32 50         SECTION("from internal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
563 8 50         auto exp = mstr("1", 50);
    50          
564 8 50         String s(cstr("2", 50));
    50          
    50          
    50          
565 4           get_allocs();
566 4 50         U::op(s, exp.c_str());
    50          
567 4 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
568 4 50         CHECK_ALLOCS(); //no allocs for sufficient capacity
    50          
569 4 50         U::op(s, cstr("so"));
    50          
    50          
    50          
570 4 50         REQUIRE_STR(s, mstr("so"), 50); // didnt become sso
    50          
    50          
    50          
571 4 50         CHECK_ALLOCS();
    50          
572 4 50         exp = mstr("3", 60);
    50          
573 4 50         U::op(s, exp.c_str());
    50          
574 4 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
575 4 50         CHECK_ALLOCS(1, BUF_CHARS+60, 1, BUF_CHARS+50); //extended storage
    50          
576 4 50         s = EMPTY;
    50          
577 4 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+60);
    50          
578             }
579 32 50         SECTION("from external") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
580 8 50         auto exp = mstr("4", 50);
    50          
581 8 50         String s(extstr(mstr("5", 50)), 50, 50, &Allocator::ext_free);
    50          
    50          
    50          
582 4           get_allocs();
583 4 50         U::op(s, exp.c_str());
    50          
584 4 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
585 4 50         CHECK_ALLOCS(); //no allocs for sufficient capacity
    50          
586 4 50         exp = mstr("bt");
    50          
587 4 50         U::op(s, exp.c_str());
    50          
588 4 50         REQUIRE_STR(s, exp, 50); // didnt become sso
    50          
    50          
    50          
589 4 50         exp = mstr("6", 70);
    50          
590 4 50         U::op(s, exp.c_str());
    50          
591 4 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
592 4 50         CHECK_ALLOCS(1, BUF_CHARS+70, 1, EBUF_CHARS, 0, 0, 1, 50); //extended storage moved to internal
    50          
593 4 50         s = EMPTY;
    50          
594 4 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+70);
    50          
595             }
596 36 50         SECTION("from cow") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
597 16 50         auto exp = mstr("1", 40);
    50          
598 12 50         SECTION("from internal cow") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
599 8 50         String tmp(cstr("2", 50));
    50          
    50          
    50          
600 8 50         String s(tmp);
    50          
601 4           get_allocs();
602 4 50         U::op(s, exp.c_str());
    50          
603 4 50         REQUIRE_STR(s, exp); //string detached
    50          
    50          
    50          
604 4 50         CHECK_ALLOCS(1, BUF_CHARS+40); //string detached
    50          
605              
606 4 50         s = tmp;
    50          
607 4           get_allocs();
608 4 50         U::op(s, cstr("qw"));
    50          
    50          
    50          
609 4 50         REQUIRE_STR(s, mstr("qw"), MAX_SSO_CHARS); //string detached to sso
    50          
    50          
    50          
610             }
611 12 50         SECTION("from external cow") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
612 8 50         String tmp(extstr(mstr("2", 50)), 50, 50, &Allocator::ext_free);
    50          
    50          
    50          
613 8 50         String s(tmp);
    50          
614 4           get_allocs();
615 4 50         U::op(s, exp.c_str());
    50          
616 4 50         REQUIRE_STR(s, exp); //string detached
    50          
    50          
    50          
617 4 50         CHECK_ALLOCS(1, BUF_CHARS+40); //string detached
    50          
618              
619 4 50         s = tmp;
    50          
620 4           get_allocs();
621 4 50         U::op(s, cstr("qw"));
    50          
    50          
    50          
622 4 50         REQUIRE_STR(s, mstr("qw"), MAX_SSO_CHARS); //string detached to sso
    50          
    50          
    50          
623             }
624             }
625 28           get_allocs();
626 28           }
627              
628 10           static void test_assign_external () {
629 12 50         SECTION("from literal") {
    50          
    50          
    50          
    100          
630 4 50         auto exp = mstr("0", 50);
631 4           String s(LITERAL);
632 2 50         assign_external(s, exp);
    50          
633 2 50         REQUIRE_STR(s, exp);
    50          
634 2 50         CHECK_ALLOCS(1, EBUF_CHARS);
635 2 50         s = EMPTY;
636 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,50);
637             }
638 12 50         SECTION("from sso") {
    50          
    50          
    50          
    100          
639 4 50         auto exp = mstr("1", 50);
640 4 50         String s(cstr("yt"));
    50          
641 2 50         assign_external(s, exp);
    50          
642 2 50         REQUIRE_STR(s, exp);
    50          
643 2 50         CHECK_ALLOCS(1, EBUF_CHARS);
644 2 50         s = EMPTY;
645 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,50);
646             }
647 12 50         SECTION("from internal") {
    50          
    50          
    50          
    100          
648 4 50         auto exp = mstr("1", 50);
649 4 50         String s(cstr("2", 60));
    50          
650 2           get_allocs();
651 2 50         assign_external(s, exp);
    50          
652 2 50         REQUIRE_STR(s, exp);
    50          
653 2 50         CHECK_ALLOCS(1, EBUF_CHARS, 1, BUF_CHARS + 60);
654 2 50         s = EMPTY;
655 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,50);
656             }
657 12 50         SECTION("from external") {
    50          
    50          
    50          
    100          
658 4 50         auto exp = mstr("4", 50);
659             //refcnt = 1
660 4 50         String s = create_external<>(mstr("abcd"));
    50          
661 2           get_allocs();
662 2 50         assign_external(s, exp);
    50          
663 2 50         REQUIRE_STR(s, exp);
    50          
664 2 50         CHECK_ALLOCS(0,0,0,0,0,0,1,4); //this case is optimized to reuse ExternalBuffer instead of dropping and creating a new one
665 2 50         s = EMPTY;
666 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,50);
667              
668             // refcnt = 2
669 2 50         s = create_external<>(mstr("abcd"));
    50          
    50          
670 4 50         String tmp(s);
671 2           get_allocs();
672 2 50         assign_external(s, exp);
    50          
673 2 50         REQUIRE_STR(s, exp);
    50          
674 2 50         CHECK_ALLOCS(1,EBUF_CHARS);
675 2 50         tmp = EMPTY;
676 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,4);
677 2 50         s = EMPTY;
678 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,50);
679             }
680 12 50         SECTION("with custom buf") {
    50          
    50          
    50          
    100          
681 4 50         auto exp = mstr("4", 50);
682 4 50         String s = create_external<>(mstr("abcd"));
    50          
683 2           get_allocs();
684 2 50         assign_external_cbuf(s, exp);
    50          
685 2 50         REQUIRE_STR(s, exp);
    50          
686 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,4);
687 2 50         s = EMPTY;
688 2 50         CHECK_ALLOCS(0,0,0,0,0,0,1,50,1);
689             }
690 10           }
691              
692 2           static void test_assign_fill () {
693 4           String s;
694 2 50         s.assign(2, (T)'a');
695 2 50         REQUIRE_STR(s, mstr("aa"), MAX_SSO_CHARS);
    50          
696 2 50         CHECK_ALLOCS();
697 2 50         s = String(cstr("a", 50));
    50          
    50          
698 2           get_allocs();
699 2 50         s.assign(10, (T)'b');
700 2 50         REQUIRE_STR(s, mstr("bbbbbbbbbb"), 50);
    50          
701 2 50         CHECK_ALLOCS();
702              
703 2 50         s = EMPTY;
704 2           get_allocs();
705 2           }
706              
707 2           static void test_assign_char () {
708 4           String s;
709 2 50         s = (T)'A';
710 2 50         REQUIRE_STR(s, mstr("A"), MAX_SSO_CHARS);
    50          
711 2 50         s = (T)'B';
712 2 50         REQUIRE_STR(s, mstr("B"), MAX_SSO_CHARS);
    50          
713 2           }
714              
715             template
716 20           static void test_assign_copy () {
717 24 50         SECTION("literal<->literal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
718 8           FString src(LITERAL);
719 8           String s;
720 4 50         U::op(s, src);
    50          
    50          
    50          
721 4 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
    50          
    50          
    50          
722 4 50         REQUIRE_STR(src, LITERAL, LITERAL_LEN, 0);
    50          
    50          
    50          
723 4 50         s = EMPTY;
    50          
    50          
    50          
724 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
725             }
726 24 50         SECTION("sso<->sso") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
727 8 50         auto exp = mstr("bu");
    50          
    50          
    50          
728 8 50         FString src(exp.c_str());
    50          
    50          
    50          
729 8 50         String s(cstr("du"));
    50          
    50          
    50          
    50          
    50          
    50          
    50          
730 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
731 4 50         U::op(s, src);
    50          
    50          
    50          
732 4 50         REQUIRE_STR(s, exp, MAX_SSO_CHARS);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
733 4 50         REQUIRE_STR(src, exp, MAX_SSO_CHARS);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
734 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
735 4 50         s = EMPTY;
    50          
    50          
    50          
736 4 50         src = EMPTY;
    50          
    50          
    50          
737 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
738             }
739 24 50         SECTION("internal<->internal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
740 8 50         auto exp = mstr("q", 50);
    50          
    50          
    50          
741 8 50         FString src(exp.c_str());
    50          
    50          
    50          
742 8 50         String s(cstr("d", 30));
    50          
    50          
    50          
    50          
    50          
    50          
    50          
743 4           get_allocs();
744 4 50         U::op(s, src);
    50          
    50          
    50          
745 4 50         REQUIRE_STR(s, exp, 0, exp.size());
    50          
    50          
    50          
    50          
    50          
    50          
    50          
746 4 50         REQUIRE_STR(src, exp, 0, exp.size());
    50          
    50          
    50          
    50          
    50          
    50          
    50          
747 4 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+30);
    50          
    50          
    50          
748 4 50         s = EMPTY;
    50          
    50          
    50          
749 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
750 4 50         src = EMPTY;
    50          
    50          
    50          
751 4 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+50);
    50          
    50          
    50          
752             }
753 24 50         SECTION("external<->external") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
754 8 50         auto exp = mstr("q", 50);
    50          
    50          
    50          
755 8 50         FString src = create_external(exp);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
756 8 50         String s = create_external<>(mstr("d", 30));
    50          
    50          
    50          
    50          
    50          
    50          
    50          
757 4           get_allocs();
758 4 50         U::op(s, src);
    50          
    50          
    50          
759 4 50         REQUIRE_STR(s, exp, 0, exp.size());
    50          
    50          
    50          
    50          
    50          
    50          
    50          
760 4 50         REQUIRE_STR(src, exp, 0, exp.size());
    50          
    50          
    50          
    50          
    50          
    50          
    50          
761 4 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,30);
    50          
    50          
    50          
762 4 50         s = EMPTY;
    50          
    50          
    50          
763 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
764 4 50         src = EMPTY;
    50          
    50          
    50          
765 4 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,50);
    50          
    50          
    50          
766             }
767 24 50         SECTION("same object") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
768 8 50         auto exp = mstr("q", 50);
    50          
    50          
    50          
769 8 50         String s(exp.c_str());
    50          
    50          
    50          
770 4           get_allocs();
771 4 50         U::op(s, s);
    50          
    50          
    50          
772 4 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
773 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
774 4 50         s = EMPTY;
    50          
    50          
    50          
775 4 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+50);
    50          
    50          
    50          
776             }
777 20           }
778              
779             template
780 4           static void test_assign_offset () {
781 6 50         SECTION("internal<->internal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
782 4 50         auto exp = mstr("q", 50);
    50          
783 4 50         FString src(exp.c_str());
    50          
784 4 50         String s(cstr("d", 30));
    50          
    50          
    50          
785 2           get_allocs();
786 2 50         s.assign(src, 10, 30);
    50          
787 2 50         REQUIRE_STR(s, mstr("q", 30), 0, 40);
    50          
    50          
    50          
788 2 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+30);
    50          
789 2 50         s = EMPTY;
    50          
790 2 50         CHECK_ALLOCS();
    50          
791 2 50         src = EMPTY;
    50          
792 2 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+50);
    50          
793             }
794 6 50         SECTION("same object") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
795 4 50         auto exp = mstr("x", 50);
    50          
796 4 50         String s = create_external<>(exp);
    50          
    50          
    50          
797 2           get_allocs();
798 2 50         s.assign(s, 10, 30);
    50          
799 2 50         REQUIRE_STR(s, mstr("x", 30), 40);
    50          
    50          
    50          
800 2 50         CHECK_ALLOCS();
    50          
801 2 50         s = EMPTY;
    50          
802 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,50);
    50          
803             }
804 4           }
805              
806             template
807 20           static void test_assign_move () {
808 24 50         SECTION("literal<->literal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
809 8           FString src(LITERAL);
810 8           String s;
811 4 50         U::op(s, src);
    50          
    50          
    50          
812 4 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
    50          
    50          
    50          
813 4 50         REQUIRE_STR(src, EMPTY);
    50          
    50          
    50          
814 4 50         s = EMPTY;
    50          
    50          
    50          
815 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
816             }
817 24 50         SECTION("sso<->sso") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
818 8 50         auto exp = mstr("bu");
    50          
    50          
    50          
819 8 50         FString src(exp.c_str());
    50          
    50          
    50          
820 8 50         String s(cstr("du"));
    50          
    50          
    50          
    50          
    50          
    50          
    50          
821 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
822 4 50         U::op(s, src);
    50          
    50          
    50          
823 4 50         REQUIRE_STR(s, exp, MAX_SSO_CHARS);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
824 4 50         REQUIRE_STR(src, EMPTY);
    50          
    50          
    50          
825 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
826 4 50         s = EMPTY;
    50          
    50          
    50          
827 4 50         src = EMPTY;
    50          
    50          
    50          
828 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
829             }
830 24 50         SECTION("internal<->internal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
831 8 50         auto exp = mstr("q", 50);
    50          
    50          
    50          
832 8 50         FString src(exp.c_str());
    50          
    50          
    50          
833 8 50         String s(cstr("d", 30));
    50          
    50          
    50          
    50          
    50          
    50          
    50          
834 4           get_allocs();
835 4 50         U::op(s, src);
    50          
    50          
    50          
836 4 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
837 4 50         REQUIRE_STR(src, EMPTY);
    50          
    50          
    50          
838 4 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+30);
    50          
    50          
    50          
839 4 50         s = EMPTY;
    50          
    50          
    50          
840 4 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+50);
    50          
    50          
    50          
841 4 50         src = EMPTY;
    50          
    50          
    50          
842 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
843             }
844 24 50         SECTION("external<->external") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
845 8 50         auto exp = mstr("q", 50);
    50          
    50          
    50          
846 8 50         FString src = create_external(exp);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
847 8 50         String s = create_external<>(mstr("d", 30));
    50          
    50          
    50          
    50          
    50          
    50          
    50          
848 4           get_allocs();
849 4 50         U::op(s, src);
    50          
    50          
    50          
850 4 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
851 4 50         REQUIRE_STR(src, EMPTY);
    50          
    50          
    50          
852 4 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,30);
    50          
    50          
    50          
853 4 50         s = EMPTY;
    50          
    50          
    50          
854 4 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,50);
    50          
    50          
    50          
855 4 50         src = EMPTY;
    50          
    50          
    50          
856 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
857             }
858 24 50         SECTION("same object") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
859 8 50         auto exp = mstr("q", 50);
    50          
    50          
    50          
860 8 50         String s(exp.c_str());
    50          
    50          
    50          
861 4           get_allocs();
862 4 50         U::op(s, s);
    50          
    50          
    50          
863 4 50         REQUIRE_STR(s, exp);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
864 4 50         CHECK_ALLOCS();
    50          
    50          
    50          
865 4 50         s = EMPTY;
    50          
    50          
    50          
866 4 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+50);
    50          
    50          
    50          
867             }
868 20           }
869              
870             template
871 106           static void test_assign () {
872 126 50         SECTION("literal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
873 20 50         SECTION("method") { test_assign_literal(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
874 20 50         SECTION("operator") { test_assign_literal(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
875             }
876 134 50         SECTION("ptr") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
877 28 50         SECTION("method") { test_assign_ptr(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
878 28 50         SECTION("operator") { test_assign_ptr(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
879             }
880 106 50         SECTION("external") { test_assign_external(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
881 106 50         SECTION("fill") { test_assign_fill(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
882 106 50         SECTION("char") { test_assign_char(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
883 126 50         SECTION("copy") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
884 20 50         SECTION("method") { test_assign_copy(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
885 20 50         SECTION("operator") { test_assign_copy(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
886             }
887 106 50         SECTION("offset") { test_assign_offset(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
888 126 50         SECTION("move") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
889 20 50         SECTION("method") { test_assign_move(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
890 20 50         SECTION("operator") { test_assign_move(); }
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
891             }
892 106           }
893              
894 6           static void test_offset () {
895 7 50         SECTION("from literal") {
    50          
    50          
    50          
    100          
896 2 50         auto exp = StdString(LITERAL).substr(2, 25);
    50          
897 2           String s(LITERAL);
898 1 50         s.offset(2, 25);
899 1 50         REQUIRE_STR(s, exp, 0);
    50          
900 1 50         s = EMPTY;
901 1 50         CHECK_ALLOCS();
902             }
903 7 50         SECTION("from sso") {
    50          
    50          
    50          
    100          
904 2 50         auto exp = mstr("bu");
905 2 50         String s(exp.c_str());
906 1 50         s.offset(1, 1);
907 1 50         REQUIRE_STR(s, mstr("u"), MAX_SSO_CHARS-1);
    50          
908 1 50         s = EMPTY;
909 1 50         CHECK_ALLOCS();
910             }
911 7 50         SECTION("from internal") {
    50          
    50          
    50          
    100          
912 2 50         auto exp = mstr("bu", 50);
913 2 50         String s(exp.c_str());
914 1 50         s.offset(9, 5);
915 1 50         REQUIRE_STR(s, mstr("ububu"), 100-9);
    50          
916 1 50         s = EMPTY;
917 1           auto sz = BUF_CHARS + 100;
918 1 50         CHECK_ALLOCS(1,sz,1,sz);
919             }
920 7 50         SECTION("from external") {
    50          
    50          
    50          
    100          
921 2 50         auto exp = mstr("c", 50);
922 2 50         String s = create_external<>(exp);
    50          
923 1 50         s.offset(10, 30);
924 1 50         REQUIRE_STR(s, mstr("c", 30), exp.size()-10);
    50          
925 1 50         s = EMPTY;
926 1 50         CHECK_ALLOCS(1, EBUF_CHARS, 1, EBUF_CHARS, 0, 0, 1, exp.size());
927             }
928 8 50         SECTION("out of bounds") {
    50          
    50          
    50          
    100          
929 4 50         auto exp = mstr("hello");
930 4 50         String s(exp.c_str());
931 3 50         SECTION("too big length acts as npos") {
    50          
    50          
    50          
    100          
932 1 50         s.offset(3, 10);
933 1 50         REQUIRE_STRM(s, mstr("lo"));
    50          
934             };
935 3 50         SECTION("too big offset throws exception") {
    50          
    50          
    50          
    100          
936 1 50         REQUIRE_THROWS(s.offset(6,10));
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
937             }
938             }
939 6           }
940              
941             template
942 20           static void test_swap () {
943 22 50         SECTION("literal<->literal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
944 4           String s1;
945 4           FString s2(LITERAL);
946 2           s1.swap(s2);
947 2 50         REQUIRE_STR(s1, LITERAL, LITERAL_LEN, 0);
    50          
948 2 50         REQUIRE_STR(s2, EMPTY);
    50          
949 2 50         s1 = EMPTY; s2 = EMPTY;
    50          
    50          
    50          
950 2 50         CHECK_ALLOCS();
    50          
951             }
952 22 50         SECTION("literal<->sso") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
953 4 50         auto exp = mstr("eb");
    50          
954 4           String s1(LITERAL);
955 4 50         FString s2(exp.c_str());
    50          
956 2           s1.swap(s2);
957 2 50         REQUIRE_STR(s1, exp, MAX_SSO_CHARS);
    50          
    50          
    50          
958 2 50         REQUIRE_STR(s2, LITERAL, LITERAL_LEN, 0);
    50          
959 2 50         s1 = EMPTY; s2 = EMPTY;
    50          
    50          
    50          
960 2 50         CHECK_ALLOCS();
    50          
961             }
962 22 50         SECTION("literal<->internal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
963 4 50         auto exp = mstr("eb", 50);
    50          
964 4           String s1(LITERAL);
965 4 50         FString s2(exp.c_str());
    50          
966 2           get_allocs();
967 2           s1.swap(s2);
968 2 50         REQUIRE_STR(s1, exp);
    50          
    50          
    50          
969 2 50         REQUIRE_STR(s2, LITERAL, LITERAL_LEN, 0);
    50          
970 2 50         s2 = EMPTY;
    50          
971 2 50         CHECK_ALLOCS();
    50          
972 2 50         s1 = EMPTY;
    50          
973 2 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+exp.size());
    50          
974             }
975 22 50         SECTION("literal<->external") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
976 4 50         auto exp = mstr("be", 50);
    50          
977 4           String s1(LITERAL);
978 4 50         FString s2 = create_external(exp);
    50          
    50          
    50          
979 2           get_allocs();
980 2           s1.swap(s2);
981 2 50         REQUIRE_STR(s1, exp);
    50          
    50          
    50          
982 2 50         REQUIRE_STR(s2, LITERAL, LITERAL_LEN, 0);
    50          
983 2 50         s2 = EMPTY;
    50          
984 2 50         CHECK_ALLOCS();
    50          
985 2 50         s1 = EMPTY;
    50          
986 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp.size());
    50          
987             }
988 22 50         SECTION("sso<->sso") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
989 4 50         auto exp1 = mstr("eb");
    50          
990 4 50         auto exp2 = mstr("ta");
    50          
991 4 50         String s1(exp1.c_str());
    50          
992 4 50         FString s2(exp2.c_str());
    50          
993 2           s1.swap(s2);
994 2 50         REQUIRE_STR(s1, exp2, MAX_SSO_CHARS);
    50          
    50          
    50          
995 2 50         REQUIRE_STR(s2, exp1, MAX_SSO_CHARS);
    50          
    50          
    50          
996 2 50         s1 = EMPTY; s2 = EMPTY;
    50          
    50          
    50          
997 2 50         CHECK_ALLOCS();
    50          
998             }
999 22 50         SECTION("sso<->internal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1000 4 50         auto exp1 = mstr("eb");
    50          
1001 4 50         auto exp2 = mstr("ta", 50);
    50          
1002 4 50         String s1(exp1.c_str());
    50          
1003 4 50         FString s2(exp2.c_str());
    50          
1004 2           get_allocs();
1005 2           s1.swap(s2);
1006 2 50         REQUIRE_STR(s1, exp2);
    50          
    50          
    50          
1007 2 50         REQUIRE_STR(s2, exp1, MAX_SSO_CHARS);
    50          
    50          
    50          
1008 2 50         s2 = EMPTY;
    50          
1009 2 50         CHECK_ALLOCS();
    50          
1010 2 50         s1 = EMPTY;
    50          
1011 2 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+exp2.size());
    50          
1012             }
1013 22 50         SECTION("sso<->external") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1014 4 50         auto exp1 = mstr("eb");
    50          
1015 4 50         auto exp2 = mstr("ta", 50);
    50          
1016 4 50         String s1(exp1.c_str());
    50          
1017 4 50         FString s2 = create_external(exp2);
    50          
    50          
    50          
1018 2           get_allocs();
1019 2           s1.swap(s2);
1020 2 50         REQUIRE_STR(s1, exp2);
    50          
    50          
    50          
1021 2 50         REQUIRE_STR(s2, exp1, MAX_SSO_CHARS);
    50          
    50          
    50          
1022 2 50         s2 = EMPTY;
    50          
1023 2 50         CHECK_ALLOCS();
    50          
1024 2 50         s1 = EMPTY;
    50          
1025 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp2.size());
    50          
1026             }
1027 22 50         SECTION("internal<->internal") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1028 4 50         auto exp1 = mstr("eb", 100);
    50          
1029 4 50         auto exp2 = mstr("ta", 50);
    50          
1030 4 50         String s1(exp1.c_str());
    50          
1031 4 50         FString s2(exp2.c_str());
    50          
1032 2 50         CHECK_ALLOCS(2, BUF_CHARS*2 + exp1.size() + exp2.size());
    50          
1033 2           s1.swap(s2);
1034 2 50         CHECK_ALLOCS();
    50          
1035 2 50         REQUIRE_STR(s1, exp2);
    50          
    50          
    50          
1036 2 50         REQUIRE_STR(s2, exp1);
    50          
    50          
    50          
1037 2 50         s1 = EMPTY;
    50          
1038 2 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+exp2.size());
    50          
1039 2 50         s2 = EMPTY;
    50          
1040 2 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+exp1.size());
    50          
1041             }
1042 22 50         SECTION("internal<->external") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1043 4 50         auto exp1 = mstr("eb", 100);
    50          
1044 4 50         auto exp2 = mstr("ta", 50);
    50          
1045 4 50         String s1(exp1.c_str());
    50          
1046 4 50         FString s2 = create_external(exp2);
    50          
    50          
    50          
1047 2 50         CHECK_ALLOCS(2, EBUF_CHARS + BUF_CHARS + exp1.size());
    50          
1048 2           s1.swap(s2);
1049 2 50         REQUIRE_STR(s1, exp2);
    50          
    50          
    50          
1050 2 50         REQUIRE_STR(s2, exp1);
    50          
    50          
    50          
1051 2 50         s1 = EMPTY;
    50          
1052 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp2.size());
    50          
1053 2 50         s2 = EMPTY;
    50          
1054 2 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+exp1.size());
    50          
1055             }
1056 22 50         SECTION("external<->external") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1057 4 50         auto exp1 = mstr("eb", 100);
    50          
1058 4 50         auto exp2 = mstr("ta", 50);
    50          
1059 4 50         String s1 = create_external<>(exp1);
    50          
    50          
    50          
1060 4 50         FString s2 = create_external(exp2);
    50          
    50          
    50          
1061 2 50         CHECK_ALLOCS(2, EBUF_CHARS*2);
    50          
1062 2           s1.swap(s2);
1063 2 50         REQUIRE_STR(s1, exp2);
    50          
    50          
    50          
1064 2 50         REQUIRE_STR(s2, exp1);
    50          
    50          
    50          
1065 2 50         s1 = EMPTY;
    50          
1066 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp2.size());
    50          
1067 2 50         s2 = EMPTY;
    50          
1068 2 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp1.size());
    50          
1069             }
1070 20           }
1071              
1072 1           static void test_copy () {
1073 2 50         String s(cstr("the password for my bank account is w74mnds320ft but i won't tell you the login)"));
    50          
1074             T t[500];
1075             size_t cnt;
1076              
1077 1 50         cnt = s.copy(t, 0);
1078 1 50         REQUIRE(cnt == 0);
    50          
    50          
    50          
    50          
    0          
    0          
1079              
1080 1 50         cnt = s.copy(t, 10);
1081 1 50         REQUIRE(cnt == 10);
    50          
    50          
    50          
    50          
    0          
    0          
1082 1 50         REQUIRE_STRM(String(t, cnt), mstr("the passwo"));
    50          
    50          
1083              
1084 1 50         cnt = s.copy(t, 20, 15);
1085 1 50         REQUIRE(cnt == 20);
    50          
    50          
    50          
    50          
    0          
    0          
1086 1 50         REQUIRE_STRM(String(t, cnt), mstr("r my bank account is"));
    50          
    50          
1087              
1088 1 50         cnt = s.copy(t, 20, 70); //too much count
1089 1 50         REQUIRE(cnt == 10);
    50          
    50          
    50          
    50          
    0          
    0          
1090 1 50         REQUIRE_STRM(String(t, cnt), mstr("the login)"));
    50          
    50          
1091              
1092 1 50         cnt = s.copy(t, String::npos, 60); //count=npos
1093 1 50         REQUIRE(cnt == 20);
    50          
    50          
    50          
    50          
    0          
    0          
1094 1 50         REQUIRE_STRM(String(t, cnt), mstr(" tell you the login)"));
    50          
    50          
1095              
1096 1 50         REQUIRE_THROWS(s.copy(t, 10, 90)); //too much offset
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
1097 1           }
1098              
1099 1           static void test_bool_empty () {
1100 2           String s;
1101 1 50         REQUIRE(s.empty());
    50          
    50          
    50          
    0          
    0          
1102 1 50         REQUIRE(!s);
    50          
    50          
    50          
    0          
    0          
1103 1 50         s = 'a';
1104 1 50         REQUIRE(!s.empty());
    50          
    50          
    50          
    0          
    0          
1105 1 50         REQUIRE(s);
    50          
    50          
    50          
    0          
    0          
1106 1           }
1107              
1108 1           static void test_use_count () {
1109 2           String s1(LITERAL);
1110 2 50         String s2(s1);
1111 1 50         REQUIRE(s1.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1112 1 50         REQUIRE(s2.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1113              
1114 1 50         s1 = cstr("ab");
    50          
1115 1 50         s2 = s1;
1116 1 50         REQUIRE(s1.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1117 1 50         REQUIRE(s2.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1118              
1119 1 50         s1 = cstr("a", 50);
    50          
1120 1 50         REQUIRE(s1.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1121 1 50         s2 = s1;
1122 1 50         REQUIRE(s1.use_count() == 2);
    50          
    50          
    50          
    50          
    0          
    0          
1123 1 50         REQUIRE(s2.use_count() == 2);
    50          
    50          
    50          
    50          
    0          
    0          
1124              
1125 1 50         s1 = create_external<>(mstr("b", 50));
    50          
    50          
1126 1 50         REQUIRE(s1.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1127 1 50         s2 = s1;
1128 1 50         REQUIRE(s1.use_count() == 2);
    50          
    50          
    50          
    50          
    0          
    0          
1129 1 50         REQUIRE(s2.use_count() == 2);
    50          
    50          
    50          
    50          
    0          
    0          
1130 1           }
1131              
1132 4           static void test_detach () {
1133 4           get_allocs();
1134 5 50         SECTION("literal") {
    50          
    50          
    50          
    100          
1135 2           String s(LITERAL);
1136 1 50         s.buf();
1137 1 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, LITERAL_LEN);
1138 1 50         CHECK_ALLOCS(1, BUF_CHARS + LITERAL_LEN);
1139             };
1140 5 50         SECTION("sso") {
    50          
    50          
    50          
    100          
1141 2 50         String s(cstr("ab"));
    50          
1142 1 50         s.buf();
1143 1 50         CHECK_ALLOCS();
1144 1 50         REQUIRE_STR(s, mstr("ab"), MAX_SSO_CHARS);
    50          
1145             };
1146 5 50         SECTION("internal") {
    50          
    50          
    50          
    100          
1147 2 50         auto exp = mstr("q", 50);
1148 2 50         String s(exp.c_str());
1149 1           get_allocs();
1150 1 50         s.buf();
1151 1 50         CHECK_ALLOCS();
1152 2 50         String s2(s);
1153 1 50         REQUIRE(s.use_count() == 2);
    50          
    50          
    50          
    50          
    0          
    0          
1154 1 50         REQUIRE(s2.use_count() == 2);
    50          
    50          
    50          
    50          
    0          
    0          
1155 1 50         s.buf();
1156 1 50         CHECK_ALLOCS(1, BUF_CHARS + exp.size()); //cow - detached
1157 1 50         REQUIRE_STR(s, exp);
    50          
1158 1 50         REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1159 1 50         REQUIRE(s2.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1160             };
1161 5 50         SECTION("external") {
    50          
    50          
    50          
    100          
1162 2 50         auto exp = mstr("q", 50);
1163 2 50         String s = create_external<>(exp);
    50          
1164 1           get_allocs();
1165 1 50         s.buf();
1166 1 50         CHECK_ALLOCS();
1167 2 50         String s2(s);
1168 1 50         REQUIRE(s.use_count() == 2);
    50          
    50          
    50          
    50          
    0          
    0          
1169 1 50         REQUIRE(s2.use_count() == 2);
    50          
    50          
    50          
    50          
    0          
    0          
1170 1 50         s.buf();
1171 1 50         CHECK_ALLOCS(1, BUF_CHARS + exp.size()); //cow - detached
1172 1 50         REQUIRE_STR(s, exp);
    50          
1173 1 50         REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1174 1 50         REQUIRE(s2.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1175             };
1176 4           }
1177              
1178 5           static void test_at_front_back () {
1179 10 50         String s(cstr("0123456789", 5));
    50          
1180 10 50         String tmp(s);
1181 5           get_allocs();
1182              
1183 6 50         SECTION("front") {
    50          
    50          
    50          
    100          
1184 1 50         REQUIRE(s.front() == (T)'0');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1185 1 50         REQUIRE(s.use_count() == 2); // not detached
    50          
    50          
    50          
    50          
    0          
    0          
1186 1 50         s.front() = (T)'9';
    50          
1187 1 50         REQUIRE_STRM(String(s, 0, 10), mstr("9123456789"));
    50          
    50          
1188 1 50         REQUIRE(s.use_count() == 1); //string detached
    50          
    50          
    50          
    50          
    0          
    0          
1189             }
1190              
1191 6 50         SECTION("at") {
    50          
    50          
    50          
    100          
1192 1 50         REQUIRE(s.at(1) == (T)'1');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1193 1 50         REQUIRE(s.at(2) == (T)'2');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1194 1 50         REQUIRE_THROWS(s.at(1000));
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
1195 1 50         REQUIRE(s.use_count() == 2); // not detached
    50          
    50          
    50          
    50          
    0          
    0          
1196 1 50         s.at(1) = (T)'8';
    50          
1197 1 50         REQUIRE_STRM(String(s, 0, 10), mstr("0823456789"));
    50          
    50          
1198 1 50         REQUIRE(s.use_count() == 1); //string detached
    50          
    50          
    50          
    50          
    0          
    0          
1199 1 50         s.at(0) = s.at(1);
    50          
    50          
1200 1 50         REQUIRE_STRM(String(s, 0, 10), mstr("8823456789"));
    50          
    50          
1201             }
1202              
1203 6 50         SECTION("op[]") {
    50          
    50          
    50          
    100          
1204 1 50         REQUIRE(s[3] == (T)'3');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1205 1 50         REQUIRE(s.use_count() == 2); // not detached
    50          
    50          
    50          
    50          
    0          
    0          
1206 1 50         s[2] = (T)'7';
    50          
1207 1 50         REQUIRE_STRM(String(s, 0, 10), mstr("0173456789"));
    50          
    50          
1208 1 50         REQUIRE(s.use_count() == 1); //string detached
    50          
    50          
    50          
    50          
    0          
    0          
1209             }
1210              
1211 6 50         SECTION("back") {
    50          
    50          
    50          
    100          
1212 1 50         REQUIRE(s.back() == (T)'9');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1213 1 50         REQUIRE(s.use_count() == 2); // not detached
    50          
    50          
    50          
    50          
    0          
    0          
1214 1 50         s.back() = (T)'0';
    50          
1215 1 50         REQUIRE_STRM(String(s, 40, 10), mstr("0123456780"));
    50          
    50          
1216 1 50         REQUIRE(s.use_count() == 1); //string detached
    50          
    50          
    50          
    50          
    0          
    0          
1217             }
1218              
1219 6 50         SECTION("pop_back") {
    50          
    50          
    50          
    100          
1220 2 50         auto exp = StdString(LITERAL).substr(0, LITERAL_LEN-1);
    50          
1221 2           String s(LITERAL);
1222 1           s.pop_back();
1223 1 50         REQUIRE_STR(s, exp, 0);
    50          
1224 1 50         s = EMPTY;
1225 1 50         CHECK_ALLOCS();
1226             }
1227 5           }
1228              
1229 7           static void test_iterator () {
1230 14 50         String s(cstr("0123456789", 5));
    50          
1231 14 50         String tmp(s);
1232 7           get_allocs();
1233              
1234 8 50         SECTION("begin + mutations") {
    50          
    50          
    50          
    100          
1235 1 50         auto it = s.begin();
1236 1 50         REQUIRE(*it++ == (T)'0');
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1237 1 50         REQUIRE(*it++ == (T)'1');
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1238 1 50         REQUIRE(*(it += 2) == (T)'4');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1239 1 50         REQUIRE(*(it -= 1) == (T)'3');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1240              
1241 1 50         REQUIRE(s.use_count() == 2); // not detached
    50          
    50          
    50          
    50          
    0          
    0          
1242 1 50         *it = (T)'x';
    50          
1243 1 50         REQUIRE(s.use_count() == 1); // detached
    50          
    50          
    50          
    50          
    0          
    0          
1244 1 50         REQUIRE_STRM(String(s, 0, 10), mstr("012x456789"));
    50          
    50          
1245             }
1246 8 50         SECTION("end") {
    50          
    50          
    50          
    100          
1247 1 50         auto it = s.end();
1248 1 50         REQUIRE(*(--it) == (T)'9');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1249 1 50         REQUIRE(*(--it) == (T)'8');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1250 1 50         std::advance(it, -2);
1251 1 50         REQUIRE(*it == (T)'6');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1252             }
1253              
1254 8 50         SECTION("diffence & eq & ne") {
    50          
    50          
    50          
    100          
1255 1 50         auto b = s.begin();
1256 1 50         auto e = s.end();
1257 1 50         REQUIRE(b == b);
    50          
    50          
    50          
    50          
    0          
    0          
1258 1 50         REQUIRE(e == e);
    50          
    50          
    50          
    50          
    0          
    0          
1259 1 50         REQUIRE(b != e);
    50          
    50          
    50          
    50          
    0          
    0          
1260 1 50         REQUIRE(size_t(e - b) == s.length());
    50          
    50          
    50          
    50          
    0          
    0          
1261             }
1262              
1263 8 50         SECTION("ordening relations") {
    50          
    50          
    50          
    100          
1264 1 50         auto b = s.begin();
1265 1 50         auto e = s.end();
1266 1 50         REQUIRE(b >= b);
    50          
    50          
    50          
    50          
    0          
    0          
1267 1 50         REQUIRE(!(b > b));
    50          
    50          
    50          
    0          
    0          
1268 1 50         REQUIRE(e > b);
    50          
    50          
    50          
    50          
    0          
    0          
1269 1 50         REQUIRE(b < e);
    50          
    50          
    50          
    50          
    0          
    0          
1270 1 50         REQUIRE(b <= e);
    50          
    50          
    50          
    50          
    0          
    0          
1271 1 50         REQUIRE(e <= e);
    50          
    50          
    50          
    50          
    0          
    0          
1272 1 50         REQUIRE(!(e < e ));
    50          
    50          
    50          
    0          
    0          
1273             }
1274              
1275 8 50         SECTION("global -+ operators") {
    50          
    50          
    50          
    100          
1276 1 50         auto b = s.begin();
1277 1 50         auto e = s.end();
1278              
1279 1 50         REQUIRE(*(b + 1) == (T)'1');
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1280 1 50         REQUIRE(*(2 + b) == (T)'2');
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1281 1 50         REQUIRE(*(e - 1) == (T)'9');
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1282 1 50         REQUIRE(*(2 - e) == (T)'8');
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1283             }
1284              
1285 8 50         SECTION("as const iterator") {
    50          
    50          
    50          
    100          
1286 1 50         auto b = s.begin();
1287 1 50         auto cb = (const T*)b;
1288 1 50         REQUIRE(*cb++ == (T)'0');
    50          
    50          
    50          
    50          
    0          
    0          
1289 1 50         REQUIRE(*cb++ == (T)'1');
    50          
    50          
    50          
    50          
    0          
    0          
1290             }
1291              
1292 8 50         SECTION("plus and as const iterator") {
    50          
    50          
    50          
    100          
1293 1 50         auto b = s.begin() + 2;
    50          
1294 1 50         auto cb = (const T*)b;
1295 1 50         REQUIRE(*cb++ == (T)'2');
    50          
    50          
    50          
    50          
    0          
    0          
1296 1 50         REQUIRE(*cb++ == (T)'3');
    50          
    50          
    50          
    50          
    0          
    0          
1297             }
1298 7           }
1299              
1300 4           static void test_erase () {
1301 4           get_allocs();
1302 5 50         SECTION("literal") {
    50          
    50          
    50          
    100          
1303 2           String s(LITERAL);
1304 1 50         s.erase(11);
1305 1 50         REQUIRE_STR(s, mstr("hello world"), 0);
    50          
1306 1 50         CHECK_ALLOCS();
1307 1 50         s.erase(0, 6);
1308 1 50         REQUIRE_STR(s, mstr("world"), 0);
    50          
1309 1 50         CHECK_ALLOCS();
1310 1 50         s.erase(1, 3);
1311 1 50         REQUIRE_STR(s, mstr("wd"), MAX_SSO_CHARS);
    50          
1312 1 50         CHECK_ALLOCS();
1313             }
1314             if (CHAR_SIZE == 1) {
1315             SECTION("sso") {
1316             String s(cstr("motherfuck"));
1317             s.erase(8);
1318             REQUIRE_STR(s, mstr("motherfu"), MAX_SSO_CHARS);
1319             s.erase(0, 2);
1320             REQUIRE_STR(s, mstr("therfu"), MAX_SSO_CHARS-2);
1321             s.erase(1, 2);
1322             REQUIRE_STR(s, mstr("trfu"), MAX_SSO_CHARS-4);
1323             s = EMPTY;
1324             CHECK_ALLOCS();
1325             }
1326             }
1327 5 50         SECTION("internal") {
    50          
    50          
    50          
    100          
1328 2 50         auto exp = mstr("0123456789", 7);
1329 2 50         String s(exp.c_str());
1330 1           get_allocs();
1331 1 50         s.erase(65);
1332 1 50         REQUIRE_STR(s, mstr("01234567890123456789012345678901234567890123456789012345678901234"), 70);
    50          
1333 1 50         s.erase(0, 5);
1334 1 50         REQUIRE_STR(s, mstr("567890123456789012345678901234567890123456789012345678901234"), 65);
    50          
1335 1 50         s.erase(5, 5);
1336 1 50         REQUIRE_STR(s, mstr("5678956789012345678901234567890123456789012345678901234"), 60); //head moved
    50          
1337 1 50         s.erase(45, 5);
1338 1 50         REQUIRE_STR(s, mstr("56789567890123456789012345678901234567890123401234"), 60); //tail moved
    50          
1339 1 50         CHECK_ALLOCS();
1340 2 50         String s2(s);
1341 1 50         REQUIRE_STR(s2, mstr("56789567890123456789012345678901234567890123401234"), 0, 60);
    50          
1342 1 50         s.erase(45);
1343 1 50         REQUIRE_STR(s, mstr("567895678901234567890123456789012345678901234"), 0, 60); // still cow
    50          
1344 1 50         s.erase(0, 5);
1345 1 50         REQUIRE_STR(s, mstr("5678901234567890123456789012345678901234"), 0, 55); // still cow
    50          
1346 1 50         CHECK_ALLOCS();
1347 1 50         REQUIRE(s.use_count() == 2); // cow
    50          
    50          
    50          
    50          
    0          
    0          
1348 1 50         s.erase(5, 5);
1349 1 50         REQUIRE_STR(s, mstr("56789567890123456789012345678901234")); // detached
    50          
1350 1 50         REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1351 1 50         CHECK_ALLOCS(1,BUF_CHARS+35);
1352             }
1353 5 50         SECTION("external") {
    50          
    50          
    50          
    100          
1354 2 50         auto exp = mstr("0123456789", 5);
1355 2 50         String s(exp.c_str());
1356 1           get_allocs();
1357 1 50         s.erase(45);
1358 1 50         REQUIRE_STR(s, mstr("012345678901234567890123456789012345678901234"), 50);
    50          
1359 1 50         s.erase(0, 5);
1360 1 50         REQUIRE_STR(s, mstr("5678901234567890123456789012345678901234"), 45);
    50          
1361 1 50         s.erase(5, 5);
1362 1 50         REQUIRE_STR(s, mstr("56789567890123456789012345678901234"), 40); //head moved
    50          
1363 1 50         s.erase(25, 5);
1364 1 50         REQUIRE_STR(s, mstr("567895678901234567890123401234"), 40); //tail moved
    50          
1365 1 50         CHECK_ALLOCS();
1366 2 50         String s2(s);
1367 1 50         REQUIRE_STR(s2, mstr("567895678901234567890123401234"), 0, 40);
    50          
1368 1 50         s.erase(25);
1369 1 50         REQUIRE_STR(s, mstr("5678956789012345678901234"), 0, 40); // still cow
    50          
1370 1 50         s.erase(0, 5);
1371 1 50         REQUIRE_STR(s, mstr("56789012345678901234"), 0, 35); // still cow
    50          
1372 1 50         CHECK_ALLOCS();
1373 1 50         REQUIRE(s.use_count() == 2);
    50          
    50          
    50          
    50          
    0          
    0          
1374 1 50         s.erase(1, 18);
1375 1 50         REQUIRE_STR(s, mstr("54"), MAX_SSO_CHARS); // detached
    50          
1376 1 50         REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
1377             }
1378 5 50         SECTION("offset exceed") {
    50          
    50          
    50          
    100          
1379 2           String s(LITERAL);
1380 1 50         REQUIRE_THROWS(s.erase(100));
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
1381             }
1382 4           }
1383              
1384             template
1385 2           static void test_compare () {
1386 4 50         String s1(cstr("keyword"));
    50          
    50          
    50          
1387 4 50         FString s2(cstr("abcword"));
    50          
    50          
    50          
1388 4 50         FString s3(cstr("keyword1"));
    50          
    50          
    50          
1389 4 50         FString s4(cstr("keyword"));
    50          
    50          
    50          
1390 4 50         FString s5(cstr("word"));
    50          
    50          
    50          
1391 2           get_allocs();
1392              
1393 2 50         REQUIRE(s1.compare(0, 7, s2, 0, 7) > 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1394 2 50         REQUIRE(s1.compare(0, 7, s3, 0, 8) < 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1395 2 50         REQUIRE(s1.compare(0, 7, s4, 0, 7) == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1396 2 50         REQUIRE(s1.compare(0, 7, s5, 0, 4) < 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1397 2 50         REQUIRE(s1.compare(0, 7, s3, 0, 7) == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1398 2 50         REQUIRE(s1.compare(3, 4, s5, 0, 4) == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1399 2 50         REQUIRE(s1.compare(3, 4, s2, 3, 4) == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1400              
1401 2 50         REQUIRE_THROWS(s1.compare(8, 7, s2, 0, 7)); //offset exceeded
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
1402 2 50         REQUIRE_THROWS(s1.compare(0, 7, s2, 8, 7)); //offset exceeded
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
1403              
1404 2 50         REQUIRE(s1.compare(0, 10, s4, 0, 7) == 0); //len exceeded
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1405 2 50         REQUIRE(s1.compare(0, 10, s4, 0, 11) == 0); //len exceeded
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1406              
1407 2 50         REQUIRE_FALSE(s1 == s3);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1408 2 50         REQUIRE(s1 == s4);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1409              
1410 2 50         REQUIRE(s1 != s3);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1411 2 50         REQUIRE_FALSE(s1 != s4);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1412              
1413 2 50         REQUIRE(s1 > s2);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1414 2 50         REQUIRE_FALSE(s1 > s3);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1415 2 50         REQUIRE_FALSE(s1 > s4);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1416              
1417 2 50         REQUIRE(s1 >= s2);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1418 2 50         REQUIRE_FALSE(s1 >= s3);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1419 2 50         REQUIRE(s1 >= s4);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1420              
1421 2 50         REQUIRE_FALSE(s1 < s2);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1422 2 50         REQUIRE(s1 < s3);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1423 2 50         REQUIRE_FALSE(s1 < s4);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1424              
1425 2 50         REQUIRE_FALSE(s1 <= s2);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1426 2 50         REQUIRE(s1 <= s3);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1427 2 50         REQUIRE(s1 <= s4);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1428              
1429 2 50         CHECK_ALLOCS();
    50          
1430 2           }
1431              
1432             template
1433 12           static void test_find () {
1434 12           auto npos = String::npos;
1435 24 50         String s(cstr("jopa noviy god"));
    50          
    50          
    50          
1436 14 50         SECTION("find") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1437 2 50         REQUIRE(s.find(FString(cstr("o"))) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1438 2 50         REQUIRE(s.find(FString(cstr("jopa"))) == 0);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1439 2 50         REQUIRE(s.find(FString(cstr("noviy"))) == 5);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1440 2 50         REQUIRE(s.find(FString(cstr("god"))) == 11);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1441 2 50         REQUIRE(s.find(FString(cstr("o")), 2) == 6);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1442 2 50         REQUIRE(s.find(FString(EMPTY), 0) == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1443 2 50         REQUIRE(s.find(FString(EMPTY), 13) == 13);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1444 2 50         REQUIRE(s.find(FString(EMPTY), 14) == 14);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1445 2 50         REQUIRE(s.find(FString(EMPTY), 15) == npos);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1446 2 50         REQUIRE(s.find(FString(cstr("o")), 14) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1447 2 50         REQUIRE(s.find(FString(cstr("god")), 11) == 11);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1448 2 50         REQUIRE(s.find(FString(cstr("god")), 12) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1449             }
1450 14 50         SECTION("rfind") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1451 2 50         REQUIRE(s.rfind(FString(cstr("o"))) == 12);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1452 2 50         REQUIRE(s.rfind(FString(cstr("o")), 99999) == 12);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1453 2 50         REQUIRE(s.rfind(FString(cstr("jopa"))) == 0);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1454 2 50         REQUIRE(s.rfind(FString(cstr("jopa")), 0) == 0);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1455 2 50         REQUIRE(s.rfind(FString(cstr("noviy"))) == 5);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1456 2 50         REQUIRE(s.rfind(FString(cstr("o")), 11) == 6);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1457 2 50         REQUIRE(s.rfind(FString(EMPTY), 0) == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1458 2 50         REQUIRE(s.rfind(FString(EMPTY), 13) == 13);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1459 2 50         REQUIRE(s.rfind(FString(EMPTY), 14) == 14);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1460 2 50         REQUIRE(s.rfind(FString(EMPTY), 15) == 14);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1461 2 50         REQUIRE(s.rfind(FString(cstr("o")), 0) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1462 2 50         REQUIRE(s.rfind(FString(cstr("god")), 11) == 11);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1463 2 50         REQUIRE(s.rfind(FString(cstr("god")), 10) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1464             }
1465 14 50         SECTION("find_first_of") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1466 2 50         REQUIRE(s.find_first_of(FString(cstr("o"))) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1467 2 50         REQUIRE(s.find_first_of(FString(cstr("o")), 2) == 6);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1468 2 50         REQUIRE(s.find_first_of(FString(cstr("o")), 14) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1469 2 50         REQUIRE(s.find_first_of(FString(EMPTY), 0) == npos);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1470 2 50         REQUIRE(s.find_first_of(FString(EMPTY), 15) == npos);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1471 2 50         REQUIRE(s.find_first_of(FString(cstr("pnv"))) == 2);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1472 2 50         REQUIRE(s.find_first_of(FString(cstr("pnv")), 3) == 5);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1473 2 50         REQUIRE(s.find_first_of(FString(cstr("pnv")), 6) == 7);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1474 2 50         REQUIRE(s.find_first_of(FString(cstr("pnv")), 8) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1475             }
1476 14 50         SECTION("find_first_not_of") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1477 2 50         REQUIRE(s.find_first_not_of(FString(cstr("o"))) == 0);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1478 2 50         REQUIRE(s.find_first_not_of(FString(cstr("j"))) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1479 2 50         REQUIRE(s.find_first_not_of(FString(cstr("o")), 1) == 2);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1480 2 50         REQUIRE(s.find_first_not_of(FString(cstr("d")), 13) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1481 2 50         REQUIRE(s.find_first_not_of(FString(EMPTY), 0) == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1482 2 50         REQUIRE(s.find_first_not_of(FString(EMPTY), 15) == npos);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1483 2 50         REQUIRE(s.find_first_not_of(FString(cstr("jopa nviy"))) == 11);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1484 2 50         REQUIRE(s.find_first_not_of(FString(cstr("og ")), 10) == 13);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1485 2 50         REQUIRE(s.find_first_not_of(FString(cstr("ogd ")), 10) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1486             }
1487 14 50         SECTION("find_last_of") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1488 2 50         REQUIRE(s.find_last_of(FString(cstr("o"))) == 12);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1489 2 50         REQUIRE(s.find_last_of(FString(cstr("o")), 9999) == 12);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1490 2 50         REQUIRE(s.find_last_of(FString(cstr("o")), 10) == 6);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1491 2 50         REQUIRE(s.find_last_of(FString(cstr("o")), 1) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1492 2 50         REQUIRE(s.find_last_of(FString(cstr("o")), 0) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1493 2 50         REQUIRE(s.find_last_of(FString(EMPTY), 0) == npos);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1494 2 50         REQUIRE(s.find_last_of(FString(EMPTY), 15) == npos);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1495 2 50         REQUIRE(s.find_last_of(FString(cstr("pnv"))) == 7);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1496 2 50         REQUIRE(s.find_last_of(FString(cstr("pnv")), 6) == 5);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1497 2 50         REQUIRE(s.find_last_of(FString(cstr("pnv")), 4) == 2);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1498 2 50         REQUIRE(s.find_last_of(FString(cstr("pnv")), 1) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1499             }
1500 14 50         SECTION("find_last_not_of") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1501 2 50         REQUIRE(s.find_last_not_of(FString(cstr("o"))) == 13);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1502 2 50         REQUIRE(s.find_last_not_of(FString(cstr("d"))) == 12);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1503 2 50         REQUIRE(s.find_last_not_of(FString(cstr("d")), 9999) == 12);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1504 2 50         REQUIRE(s.find_last_not_of(FString(cstr("d")), 12) == 12);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1505 2 50         REQUIRE(s.find_last_not_of(FString(cstr("o")), 12) == 11);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1506 2 50         REQUIRE(s.find_last_not_of(FString(cstr("j")), 0) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1507 2 50         REQUIRE(s.find_last_not_of(FString(EMPTY), 0) == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1508 2 50         REQUIRE(s.find_last_not_of(FString(EMPTY), 13) == 13);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1509 2 50         REQUIRE(s.find_last_not_of(FString(EMPTY), 14) == 13);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1510 2 50         REQUIRE(s.find_last_not_of(FString(EMPTY), 15) == 13);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1511 2 50         REQUIRE(s.find_last_not_of(FString(cstr("nviy god"))) == 3);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1512 2 50         REQUIRE(s.find_last_not_of(FString(cstr("jpa ")), 4) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1513 2 50         REQUIRE(s.find_last_not_of(FString(cstr("jopa ")), 4) == npos);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1514             }
1515 12           }
1516              
1517 17           static void test_reserve () {
1518 17           get_allocs();
1519 20 50         SECTION("literal") {
    50          
    50          
    50          
    100          
1520 3           get_allocs();
1521 6           String s(LITERAL);
1522 4 50         SECTION(">len") {
    50          
    50          
    50          
    100          
1523 1 50         s.reserve(100);
1524 1 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 100);
1525 1 50         CHECK_ALLOCS(1, BUF_CHARS+100);
1526             }
1527 4 50         SECTION("
    50          
    50          
    50          
    100          
1528 1 50         s.reserve(LITERAL_LEN-1);
1529 1 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, LITERAL_LEN);
1530 1 50         CHECK_ALLOCS(1, BUF_CHARS+LITERAL_LEN);
1531             }
1532 4 50         SECTION("=0") {
    50          
    50          
    50          
    100          
1533 1 50         s.reserve(0);
1534 1 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, LITERAL_LEN);
1535 1 50         CHECK_ALLOCS(1, BUF_CHARS+LITERAL_LEN);
1536             }
1537             }
1538             if (CHAR_SIZE == 1) {
1539             SECTION("sso") {
1540             get_allocs();
1541             auto exp = mstr("hello");
1542             SECTION("<= max sso") {
1543             String s(exp.c_str());
1544             s.reserve(0);
1545             REQUIRE_STR(s, exp, MAX_SSO_CHARS);
1546             CHECK_ALLOCS();
1547             s.reserve(MAX_SSO_CHARS);
1548             REQUIRE_STR(s, exp, MAX_SSO_CHARS);
1549             CHECK_ALLOCS();
1550             }
1551             SECTION("> max sso") {
1552             String s(exp.c_str());
1553             s.reserve(MAX_SSO_CHARS+1);
1554             REQUIRE_STR(s, exp, MAX_SSO_CHARS+1);
1555             CHECK_ALLOCS(1, BUF_CHARS+MAX_SSO_CHARS+1);
1556             }
1557             SECTION("offset, <= capacity") {
1558             String s((mstr("hi")+exp).c_str());
1559             s.offset(2);
1560             REQUIRE_STR(s, exp, MAX_SSO_CHARS-2);
1561             s.reserve(MAX_SSO_CHARS-2);
1562             REQUIRE_STR(s, exp, MAX_SSO_CHARS-2);
1563             CHECK_ALLOCS();
1564             }
1565             SECTION("offset, > capacity, <= max sso") {
1566             String s((mstr("hi")+exp).c_str());
1567             s.offset(2);
1568             REQUIRE_STR(s, exp, MAX_SSO_CHARS-2);
1569             s.reserve(MAX_SSO_CHARS);
1570             REQUIRE_STR(s, exp, MAX_SSO_CHARS);
1571             CHECK_ALLOCS(); // string should has been moved to the beginning, no allocs
1572             }
1573             }
1574             }
1575 24 50         SECTION("internal") {
    50          
    50          
    50          
    100          
1576 14 50         auto exp = mstr("abcde", 10);
1577 14 50         String s(exp.c_str());
1578 7           get_allocs();
1579 8 50         SECTION("detach cow") {
    50          
    50          
    50          
    100          
1580 2 50         String s2(s);
1581 1 50         s.reserve(exp.size()-1);
1582 1 50         REQUIRE_STR(s, exp);
    50          
1583 1 50         REQUIRE(s.use_count() == 1); // detached
    50          
    50          
    50          
    50          
    0          
    0          
1584 1 50         CHECK_ALLOCS(1, BUF_CHARS+exp.size());
1585 1 50         s = s2;
1586 1           get_allocs();
1587 1 50         s.offset(10, 30);
1588 2 50         auto tmp = exp.substr(10, 30);
1589 1 50         s.reserve(0);
1590 1 50         REQUIRE_STR(s, tmp);
    50          
1591 1 50         REQUIRE(s.use_count() == 1); // detached
    50          
    50          
    50          
    50          
    0          
    0          
1592 1 50         CHECK_ALLOCS(1, BUF_CHARS+tmp.size()); // detached with minimum required capacity
1593 1 50         s = s2;
1594 1           get_allocs();
1595 1 50         s.offset(10, 30);
1596 1 50         s.reserve(100);
1597 1 50         REQUIRE_STR(s, tmp, 100);
    50          
1598 1 50         REQUIRE(s.use_count() == 1); // detached
    50          
    50          
    50          
    50          
    0          
    0          
1599 1 50         CHECK_ALLOCS(1, BUF_CHARS+100);
1600             }
1601 8 50         SECTION("<= max capacity") {
    50          
    50          
    50          
    100          
1602 1 50         s.reserve(0);
1603 1 50         s.reserve(exp.size());
1604 1 50         REQUIRE_STR(s, exp);
    50          
1605 1 50         CHECK_ALLOCS();
1606             }
1607 8 50         SECTION("> max capacity") {
    50          
    50          
    50          
    100          
1608 1 50         s.reserve(exp.size()*2);
1609 1 50         REQUIRE_STR(s, exp, exp.size()*2);
    50          
1610 1 50         CHECK_ALLOCS(0,0,0,0,1,exp.size());
1611             }
1612 8 50         SECTION("offset, <= capacity") {
    50          
    50          
    50          
    100          
1613 1 50         s.offset(10);
1614 1 50         s.reserve(40);
1615 1 50         REQUIRE_STR(s, exp.substr(10));
    50          
1616 1 50         CHECK_ALLOCS();
1617             }
1618 8 50         SECTION("offset, > capacity, <= max capacity") {
    50          
    50          
    50          
    100          
1619 1 50         s.offset(10);
1620 1 50         s.reserve(50);
1621 1 50         REQUIRE_STR(s, exp.substr(10), 50);
    50          
1622 1 50         CHECK_ALLOCS(); // str has been moved to the beginning
1623             }
1624 8 50         SECTION("offset, > max capacity") {
    50          
    50          
    50          
    100          
1625 1 50         s.offset(20);
1626 1 50         s.reserve(70);
1627 1 50         REQUIRE_STR(s, exp.substr(20), 70);
    50          
1628 1 50         CHECK_ALLOCS(1, BUF_CHARS+70, 1, BUF_CHARS+50);
1629             }
1630 8 50         SECTION("reserve to sso") {
    50          
    50          
    50          
    100          
1631 2 50         String s2(s);
1632 1 50         s.offset(0, 2);
1633 1 50         s.reserve(2);
1634 1 50         REQUIRE_STR(s, exp.substr(0,2), MAX_SSO_CHARS);
    50          
1635 1 50         CHECK_ALLOCS();
1636             }
1637             }
1638 24 50         SECTION("external") {
    50          
    50          
    50          
    100          
1639 14 50         auto exp = mstr("abcde", 10);
1640 14 50         String s = create_external<>(exp);
    50          
1641 7           get_allocs();
1642 8 50         SECTION("detach cow") {
    50          
    50          
    50          
    100          
1643 2 50         String s2(s);
1644 1 50         s.reserve(exp.size()-1);
1645 1 50         REQUIRE_STR(s, exp);
    50          
1646 1 50         REQUIRE(s.use_count() == 1); // detached
    50          
    50          
    50          
    50          
    0          
    0          
1647 1 50         CHECK_ALLOCS(1, BUF_CHARS+exp.size());
1648 1 50         s = s2;
1649 1           get_allocs();
1650 1 50         s.offset(10, 30);
1651 1 50         s.reserve(0);
1652 2 50         auto tmp = exp.substr(10,30);
1653 1 50         REQUIRE_STR(s, tmp);
    50          
1654 1 50         REQUIRE(s.use_count() == 1); // detached
    50          
    50          
    50          
    50          
    0          
    0          
1655 1 50         CHECK_ALLOCS(1, BUF_CHARS+30); // detached with minimum required capacity
1656 1 50         s = s2;
1657 1           get_allocs();
1658 1 50         s.offset(10, 30);
1659 1 50         s.reserve(100);
1660 1 50         REQUIRE_STR(s, tmp, 100);
    50          
1661 1 50         REQUIRE(s.use_count() == 1); // detached
    50          
    50          
    50          
    50          
    0          
    0          
1662 1 50         CHECK_ALLOCS(1, BUF_CHARS+100);
1663             }
1664 8 50         SECTION("<= max capacity") {
    50          
    50          
    50          
    100          
1665 1 50         s.reserve(0);
1666 1 50         s.reserve(exp.size());
1667 1 50         REQUIRE_STR(s, exp);
    50          
1668 1 50         CHECK_ALLOCS();
1669             }
1670 8 50         SECTION("> max capacity") {
    50          
    50          
    50          
    100          
1671 1 50         s.reserve(exp.size()*2);
1672 1 50         REQUIRE_STR(s, exp, exp.size()*2);
    50          
1673 1 50         CHECK_ALLOCS(1, BUF_CHARS+exp.size()*2, 1, EBUF_CHARS, 0, 0, 1, exp.size());
1674             }
1675 8 50         SECTION("offset, <= capacity") {
    50          
    50          
    50          
    100          
1676 1 50         s.offset(10);
1677 1 50         s.reserve(40);
1678 1 50         REQUIRE_STR(s, exp.substr(10));
    50          
1679 1 50         CHECK_ALLOCS();
1680             }
1681 8 50         SECTION("offset, > capacity, <= max capacity") {
    50          
    50          
    50          
    100          
1682 1 50         s.offset(10);
1683 1 50         s.reserve(50);
1684 1 50         REQUIRE_STR(s, exp.substr(10), 50);
    50          
1685 1 50         CHECK_ALLOCS(); // str has been moved to the beginning
1686             }
1687 8 50         SECTION("offset, > max capacity") {
    50          
    50          
    50          
    100          
1688 1 50         s.offset(20);
1689 1 50         s.reserve(70);
1690 1 50         REQUIRE_STR(s, exp.substr(20), 70);
    50          
1691 1 50         CHECK_ALLOCS(1, BUF_CHARS+70, 1, EBUF_CHARS, 0,0, 1, exp.size());
1692             }
1693 8 50         SECTION("reserve to sso") {
    50          
    50          
    50          
    100          
1694 2 50         String s2(s);
1695 1 50         s.offset(0, 2);
1696 1 50         s.reserve(2);
1697 1 50         REQUIRE_STR(s, exp.substr(0, 2), MAX_SSO_CHARS);
    50          
1698 1 50         CHECK_ALLOCS();
1699             }
1700             }
1701 17           }
1702              
1703 6           static void test_resize () {
1704 6           get_allocs();
1705 8 50         SECTION("literal") {
    50          
    50          
    50          
    100          
1706 4           String s(LITERAL);
1707 3 50         SECTION("less") {
    50          
    50          
    50          
    100          
1708 1 50         s.resize(1);
1709 1 50         REQUIRE_STR(s, StdString(LITERAL, 1), 0);
    50          
1710 1 50         CHECK_ALLOCS();
1711             }
1712 3 50         SECTION("more") {
    50          
    50          
    50          
    100          
1713 1 50         s.resize(LITERAL_LEN+10);
1714 1 50         REQUIRE_STR(s, StdString(LITERAL) + StdString(10, (T)'\0'));
    50          
    50          
    50          
1715 1 50         CHECK_ALLOCS(1, BUF_CHARS + LITERAL_LEN + 10);
1716             }
1717             }
1718             if (CHAR_SIZE == 1) {
1719             SECTION("sso") {
1720             auto exp = mstr("world");
1721             String s(exp.c_str());
1722             SECTION("less") {
1723             s.resize(2);
1724             REQUIRE_STR(s, mstr("wo"), MAX_SSO_CHARS);
1725             CHECK_ALLOCS();
1726             }
1727             SECTION("more") {
1728             s.resize(7, (T)'!');
1729             REQUIRE_STR(s, mstr("world!!"), MAX_SSO_CHARS);
1730             CHECK_ALLOCS();
1731             }
1732             }
1733             }
1734 8 50         SECTION("internal") {
    50          
    50          
    50          
    100          
1735 4 50         auto exp = mstr("a", 50);
1736 4 50         String s(exp.c_str());
1737 2           get_allocs();
1738 3 50         SECTION("less") {
    50          
    50          
    50          
    100          
1739 1 50         s.resize(10);
1740 1 50         REQUIRE_STR(s, mstr("a", 10), exp.size());
    50          
1741 1 50         CHECK_ALLOCS();
1742             }
1743 3 50         SECTION("more") {
    50          
    50          
    50          
    100          
1744 1 50         s.resize(70, (T)'b');
1745 1 50         REQUIRE_STR(s, exp + mstr("b", 20));
    50          
    50          
1746 1 50         CHECK_ALLOCS(0,0,0,0,1,20);
1747             }
1748             }
1749 8 50         SECTION("external") {
    50          
    50          
    50          
    100          
1750 4 50         auto exp = mstr("a", 50);
1751 4 50         String s = create_external<>(exp);
    50          
1752 2           get_allocs();
1753 3 50         SECTION("less") {
    50          
    50          
    50          
    100          
1754 1 50         s.resize(10);
1755 1 50         REQUIRE_STR(s, mstr("a", 10), exp.size());
    50          
1756 1 50         CHECK_ALLOCS();
1757             }
1758 3 50         SECTION("more") {
    50          
    50          
    50          
    100          
1759 1 50         s.offset(40);
1760 1 50         s.resize(20, (T)'b');
1761 1 50         REQUIRE_STR(s, mstr("a", 10) + mstr("b", 10), 50);
    50          
    50          
    50          
1762 1 50         CHECK_ALLOCS(); // because offset has been eliminated
1763             }
1764             }
1765 6           }
1766              
1767 6           static void test_shrink_to_fit () {
1768 6           get_allocs();
1769 7 50         SECTION("literal") {
    50          
    50          
    50          
    100          
1770 2 50         auto s = String(LITERAL).substr(2,5);
1771 1 50         s.shrink_to_fit();
1772 1 50         REQUIRE(s.capacity() == 0); // noop
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1773 1 50         CHECK_ALLOCS();
1774             }
1775 7 50         SECTION("sso") {
    50          
    50          
    50          
    100          
1776 2 50         String s(cstr("ab"));
    50          
1777 1           s.pop_back();
1778 1 50         s.shrink_to_fit();
1779 1 50         REQUIRE_STR(s, mstr("a"), MAX_SSO_CHARS);
    50          
1780 1 50         CHECK_ALLOCS();
1781             }
1782 7 50         SECTION("internal owner") {
    50          
    50          
    50          
    100          
1783 2 50         String s(cstr("a", 50));
    50          
1784 1           get_allocs();
1785 1 50         s.shrink_to_fit();
1786 1 50         REQUIRE_STR(s, mstr("a", 50));
    50          
1787 1 50         CHECK_ALLOCS();
1788 1 50         s.offset(0, 40);
1789 1 50         s.shrink_to_fit();
1790 1 50         REQUIRE_STR(s, mstr("a", 40));
    50          
1791 1 50         CHECK_ALLOCS(0,0,0,0,1,-10); //realloced
1792 1 50         s.offset(10);
1793 1 50         s.shrink_to_fit();
1794 1 50         REQUIRE_STR(s, mstr("a", 30));
    50          
1795 1 50         CHECK_ALLOCS(1,BUF_CHARS+30,1,BUF_CHARS+40); // dealloc+alloc
1796 1 50         s.offset(0,2);
1797 1 50         s.shrink_to_fit();
1798 1 50         REQUIRE_STR(s, mstr("aa"), MAX_SSO_CHARS); // shrinked to sso
    50          
1799 1 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+30);
1800             }
1801 7 50         SECTION("internal cow") {
    50          
    50          
    50          
    100          
1802 2 50         String s(cstr("a", 50));
    50          
1803 2 50         String tmp(s);
1804 1           get_allocs();
1805 1 50         s.offset(10, 30);
1806 1 50         s.shrink_to_fit();
1807 1 50         REQUIRE_STR(s, mstr("a", 30), 0, 40);
    50          
1808 1 50         CHECK_ALLOCS();
1809 1 50         s.offset(0, 2);
1810 1 50         s.shrink_to_fit();
1811 1 50         REQUIRE_STR(s, mstr("aa"), MAX_SSO_CHARS); // shrinked to sso
    50          
1812 1 50         CHECK_ALLOCS();
1813             }
1814 7 50         SECTION("external owner") {
    50          
    50          
    50          
    100          
1815 2 50         String s = create_external<>(mstr("a", 50));
    50          
1816 1           get_allocs();
1817 1 50         s.shrink_to_fit();
1818 1 50         REQUIRE_STR(s, mstr("a", 50));
    50          
1819 1 50         CHECK_ALLOCS();
1820 1 50         s.offset(0, 40);
1821 1 50         s.shrink_to_fit();
1822 1 50         REQUIRE_STR(s, mstr("a", 40)); // shrinked
    50          
1823 1 50         CHECK_ALLOCS(1, BUF_CHARS+40, 1, EBUF_CHARS, 0, 0, 1, 50); // moved to internal
1824 1 50         s = create_external<>(mstr("a", 50));
    50          
    50          
1825 1           get_allocs();
1826 1 50         s.offset(0,2);
1827 1 50         s.shrink_to_fit();
1828 1 50         REQUIRE_STR(s, mstr("aa"), MAX_SSO_CHARS); // shrinked to sso
    50          
1829 1 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,50);
1830             }
1831 7 50         SECTION("external cow") {
    50          
    50          
    50          
    100          
1832 2 50         String s = create_external<>(mstr("a", 50));
    50          
1833 1           get_allocs();
1834 2 50         String tmp(s);
1835 1 50         s.offset(10, 30);
1836 1 50         s.shrink_to_fit();
1837 1 50         REQUIRE_STR(s, mstr("a", 30), 0, 40);
    50          
1838 1 50         CHECK_ALLOCS();
1839 1 50         s = create_external<>(mstr("a", 50));
    50          
    50          
1840 1 50         tmp = s;
1841 1           get_allocs();
1842 1 50         s.offset(0, 2);
1843 1 50         s.shrink_to_fit();
1844 1 50         REQUIRE_STR(s, mstr("aa"), MAX_SSO_CHARS); // shrinked to sso
    50          
1845 1 50         CHECK_ALLOCS();
1846             }
1847 6           }
1848              
1849 10           static void test_append () {
1850 20 50         String s(cstr("abcd"));
    50          
1851 11 50         SECTION("char") {
    50          
    50          
    50          
    100          
1852 1 50         s.append(5, (T)'x');
1853 1 50         REQUIRE_STRM(s, mstr("abcdxxxxx"));
    50          
1854             }
1855 11 50         SECTION("same class string") {
    50          
    50          
    50          
    100          
1856 1 50         s.append(String(cstr("1234")));
    50          
    50          
1857 1 50         REQUIRE_STRM(s, mstr("abcd1234"));
    50          
1858 1 50         s.append(String(cstr("qwerty")), 3);
    50          
    50          
1859 1 50         REQUIRE_STRM(s, mstr("abcd1234rty"));
    50          
1860 1 50         s.append(String(cstr("hello world")), 5, 4);
    50          
    50          
1861 1 50         REQUIRE_STRM(s, mstr("abcd1234rty wor"));
    50          
1862             }
1863 11 50         SECTION("foreign class string") {
    50          
    50          
    50          
    100          
1864 1 50         s.append(String2(cstr("1234")));
    50          
    50          
1865 1 50         REQUIRE_STRM(s, mstr("abcd1234"));
    50          
1866 1 50         s.append(String2(cstr("qwerty")), 3);
    50          
    50          
1867 1 50         REQUIRE_STRM(s, mstr("abcd1234rty"));
    50          
1868 1 50         s.append(String2(cstr("hello world")), 5, 4);
    50          
    50          
1869 1 50         REQUIRE_STRM(s, mstr("abcd1234rty wor"));
    50          
1870             }
1871 11 50         SECTION("ptr") {
    50          
    50          
    50          
    100          
1872 1 50         s.append(cstr("1234"));
    50          
1873 1 50         REQUIRE_STRM(s, mstr("abcd1234"));
    50          
1874 1 50         s.append(cstr("qwerty"), 3);
    50          
1875 1 50         REQUIRE_STRM(s, mstr("abcd1234qwe"));
    50          
1876             }
1877 11 50         SECTION("literal") {
    50          
    50          
    50          
    100          
1878 1 50         s.append(LITERAL);
1879 1 50         REQUIRE_STRM(s, mstr("abcd") + StdString(LITERAL));
    50          
    50          
    50          
1880             }
1881 11 50         SECTION("initializer list") {
    50          
    50          
    50          
    100          
1882 1 50         s.append({'1', '2', '3', '4'});
1883 1 50         REQUIRE_STRM(s, mstr("abcd1234"));
    50          
1884             }
1885 11 50         SECTION("string_view") {
    50          
    50          
    50          
    100          
1886 1 50         s.append(svstr("1234"));
    50          
1887 1 50         REQUIRE_STRM(s, mstr("abcd1234"));
    50          
1888             }
1889 11 50         SECTION("self append") {
    50          
    50          
    50          
    100          
1890 1 50         s = cstr("12345678901234567890");
    50          
1891 1 50         s.append(s);
1892 1 50         REQUIRE_STRM(s, mstr("1234567890123456789012345678901234567890"));
    50          
1893 1 50         s.append(s, 1, 6);
1894 1 50         REQUIRE_STRM(s, mstr("1234567890123456789012345678901234567890234567"));
    50          
1895             }
1896 11 50         SECTION("preserve_allocated_when_empty_but_reserved") {
    50          
    50          
    50          
    100          
1897 2           String s;
1898 2 50         String s2(cstr("a", 50));
    50          
1899 2 50         String s3(cstr("b", 10));
    50          
1900 1           get_allocs();
1901 1 50         s.reserve(100);
1902 1 50         CHECK_ALLOCS(1, BUF_CHARS+100);
1903 1 50         s.append(s2);
1904 1 50         CHECK_ALLOCS();
1905 1 50         s.append(s3);
1906 1 50         CHECK_ALLOCS();
1907 1 50         REQUIRE_STR(s, mstr("a",50)+mstr("b",10), 100);
    50          
    50          
    50          
1908             }
1909 11 50         SECTION("operator +=") {
    50          
    50          
    50          
    100          
1910 2 50         String s(cstr("abcd"));
    50          
1911 1 50         s += String(cstr("1234"));
    50          
    50          
1912 1 50         REQUIRE_STRM(s, mstr("abcd1234"));
    50          
1913 1 50         s += String2(cstr("qwerty"));
    50          
    50          
1914 1 50         REQUIRE_STRM(s, mstr("abcd1234qwerty"));
    50          
1915 1 50         s += cstr("hello world");
    50          
1916 1 50         REQUIRE_STRM(s, mstr("abcd1234qwertyhello world"));
    50          
1917 1 50         s += (T)'x';
1918 1 50         REQUIRE_STRM(s, mstr("abcd1234qwertyhello worldx"));
    50          
1919 1 50         s += s;
1920 1 50         REQUIRE_STRM(s, mstr("abcd1234qwertyhello worldxabcd1234qwertyhello worldx"));
    50          
1921             }
1922 10           }
1923              
1924             template
1925 24           static void test_op_plus () {
1926 24           get_allocs();
1927 48 50         auto lexp = mstr("x", 30);
    50          
1928 48 50         auto rexp = mstr("y", 40);
    50          
1929 48           String empty;
1930 26 50         SECTION("str-str") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1931 4 50         String lhs(lexp.c_str());
    50          
1932 4 50         FString rhs(rexp.c_str());
    50          
1933 2           get_allocs();
1934 4 50         String s = lhs + rhs;
    50          
1935 2 50         REQUIRE_STR(s, lexp+rexp);
    50          
    50          
    50          
1936 2 50         REQUIRE(lhs.use_count() == 1); REQUIRE(rhs.use_count() == 1); REQUIRE(s.use_count() == 1); // no cows
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
1937 2 50         CHECK_ALLOCS(1, BUF_CHARS+70);
    50          
1938 2 50         s = EMPTY; get_allocs();
    50          
1939 2 50         s = lhs + empty;
    50          
    50          
    50          
1940 2 50         REQUIRE(lhs.use_count() == 2); REQUIRE(s.use_count() == 2); // cow
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
1941 2 50         REQUIRE_STR(s, lexp, 0, lexp.size());
    50          
    50          
    50          
1942 2 50         CHECK_ALLOCS();
    50          
1943 2 50         s = EMPTY;
    50          
1944 2 50         s = empty + rhs;
    50          
    50          
    50          
1945 2 50         REQUIRE(rhs.use_count() == 2); REQUIRE(s.use_count() == 2); // cow
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
1946 2 50         REQUIRE_STR(s, rexp, 0, rexp.size());
    50          
    50          
    50          
1947 2 50         CHECK_ALLOCS();
    50          
1948             }
1949 26 50         SECTION("ptr-str") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1950 2           auto lhs = lexp.c_str();
1951 4 50         String rhs(rexp.c_str());
    50          
1952 2           get_allocs();
1953 4 50         String s = lhs + rhs;
    50          
1954 2 50         REQUIRE_STR(s, lexp+rexp);
    50          
    50          
    50          
1955 2 50         REQUIRE(rhs.use_count() == 1); REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
1956 2 50         CHECK_ALLOCS(1, BUF_CHARS+lexp.size()+rexp.size());
    50          
1957 2 50         s = EMPTY; get_allocs();
    50          
1958 2 50         s = lhs + empty;
    50          
    50          
    50          
1959 2 50         REQUIRE_STR(s, lexp);
    50          
    50          
    50          
1960 2 50         CHECK_ALLOCS(1, BUF_CHARS+lexp.size());
    50          
1961 2 50         REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1962 2 50         s = EMPTY; get_allocs();
    50          
1963 2 50         s = cstr("") + rhs;
    50          
    50          
    50          
    50          
    50          
1964 2 50         REQUIRE_STR(s, rexp, 0, rexp.size());
    50          
    50          
    50          
1965 2 50         REQUIRE(rhs.use_count() == 2); REQUIRE(s.use_count() == 2);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
1966 2 50         CHECK_ALLOCS();
    50          
1967             }
1968 26 50         SECTION("char-str") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1969 2           T lhs = (T)'x';
1970 4 50         String rhs(rexp.c_str());
    50          
1971 2           get_allocs();
1972 4 50         String s = lhs + rhs;
    50          
1973 2 50         REQUIRE_STR(s, lhs+rexp);
    50          
    50          
    50          
1974 2 50         REQUIRE(rhs.use_count() == 1); REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
1975 2 50         CHECK_ALLOCS(1, BUF_CHARS + rexp.size() + 1);
    50          
1976 2 50         s = EMPTY; get_allocs();
    50          
1977 2 50         s = lhs + empty;
    50          
    50          
    50          
1978 2 50         REQUIRE_STR(s, mstr("x"), MAX_SSO_CHARS);
    50          
    50          
    50          
1979 2 50         CHECK_ALLOCS();
    50          
1980             }
1981 26 50         SECTION("str-ptr") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
1982 4 50         String lhs(lexp.c_str());
    50          
1983 2           auto rhs = rexp.c_str();
1984 2           get_allocs();
1985 4 50         String s = lhs + rhs;
    50          
1986 2 50         REQUIRE_STR(s, lexp+rexp);
    50          
    50          
    50          
1987 2 50         REQUIRE(lhs.use_count() == 1); REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
1988 2 50         CHECK_ALLOCS(1, BUF_CHARS + lexp.size() + rexp.size());
    50          
1989 2 50         s = EMPTY; get_allocs();
    50          
1990 2 50         s = empty + rhs;
    50          
    50          
    50          
1991 2 50         REQUIRE_STR(s, rexp);
    50          
    50          
    50          
1992 2 50         REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1993 2 50         s = EMPTY; get_allocs();
    50          
1994 2 50         s = lhs + cstr("");
    50          
    50          
    50          
    50          
    50          
1995 2 50         REQUIRE_STR(s, lexp, 0, lexp.size());
    50          
    50          
    50          
1996 2 50         REQUIRE(lhs.use_count() == 2); REQUIRE(s.use_count() == 2);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
1997 2 50         CHECK_ALLOCS();
    50          
1998             }
1999 26 50         SECTION("str-char") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
2000 4 50         String lhs(lexp.c_str());
    50          
2001 2           T rhs = (T)'y';
2002 2           get_allocs();
2003 4 50         String s = lhs + rhs;
    50          
2004 2 50         REQUIRE_STR(s, lexp+rhs);
    50          
    50          
    50          
2005 2 50         REQUIRE(lhs.use_count() == 1); REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
2006 2 50         CHECK_ALLOCS(1, BUF_CHARS + lhs.size() + 1);
    50          
2007 2 50         s = EMPTY; get_allocs();
    50          
2008 2 50         s = empty + rhs;
    50          
    50          
    50          
2009 2 50         REQUIRE_STR(s, mstr("y"), MAX_SSO_CHARS);
    50          
    50          
    50          
2010 2 50         CHECK_ALLOCS();
    50          
2011             }
2012 26 50         SECTION("mstr-str") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
2013 4 50         String lhs(lexp.c_str());
    50          
2014 4 50         FString rhs(rexp.c_str());
    50          
2015 2 50         lhs.reserve(200);
    50          
2016 2           get_allocs();
2017 4 50         String s = std::move(lhs) + rhs;
    50          
2018 2 50         REQUIRE_STR(s, lexp+rexp, 200);
    50          
    50          
    50          
2019 2 50         REQUIRE(lhs.use_count() == 1); REQUIRE(rhs.use_count() == 1); REQUIRE(s.use_count() == 1); // no cows
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
2020 2 50         REQUIRE(!lhs); // lhs moved
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
2021 2 50         REQUIRE_STR(rhs, rexp);
    50          
    50          
    50          
2022 2 50         CHECK_ALLOCS();
    50          
2023             }
2024 26 50         SECTION("str-mstr") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
2025 4 50         String lhs(lexp.c_str());
    50          
2026 4 50         FString rhs(rexp.c_str());
    50          
2027 2 50         rhs.reserve(250);
    50          
2028 2           get_allocs();
2029 4 50         String s = lhs + std::move(rhs);
    50          
2030 2 50         REQUIRE_STR(s, lexp+rexp, 250);
    50          
    50          
    50          
2031 2 50         REQUIRE(lhs.use_count() == 1); REQUIRE(rhs.use_count() == 1); REQUIRE(s.use_count() == 1); // no cows
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
2032 2 50         REQUIRE_STR(lhs, lexp);
    50          
    50          
    50          
2033 2 50         REQUIRE(!rhs);
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
2034 2 50         CHECK_ALLOCS();
    50          
2035             }
2036 26 50         SECTION("mstr-mstr") { // for now it's just lhs.append(rhs), i.e. the same as mstr-str
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
2037 4 50         String lhs(lexp.c_str());
    50          
2038 4 50         FString rhs(rexp.c_str());
    50          
2039 2 50         lhs.reserve(150);
    50          
2040 2           get_allocs();
2041 4 50         String s = std::move(lhs) + std::move(rhs);
    50          
2042 2 50         REQUIRE_STR(s, lexp+rexp, 150);
    50          
    50          
    50          
2043 2 50         REQUIRE(lhs.use_count() == 1); REQUIRE(rhs.use_count() == 1); REQUIRE(s.use_count() == 1); // no cows
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
2044 2 50         REQUIRE(!lhs); // lhs moved
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
2045 2 50         REQUIRE_STR(rhs, rexp);
    50          
    50          
    50          
2046 2 50         CHECK_ALLOCS();
    50          
2047             }
2048 26 50         SECTION("ptr-mstr") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
2049 2           auto lhs = lexp.c_str();
2050 4 50         String rhs(rexp.c_str());
    50          
2051 2 50         rhs.reserve(100);
    50          
2052 2           get_allocs();
2053 4 50         String s = lhs + std::move(rhs);
    50          
2054 2 50         REQUIRE_STR(s, lexp+rexp, 100);
    50          
    50          
    50          
2055 2 50         REQUIRE(rhs.use_count() == 1); REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
2056 2 50         REQUIRE(!rhs);
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
2057 2 50         CHECK_ALLOCS();
    50          
2058             }
2059 26 50         SECTION("char-mstr") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
2060 2           T lhs = (T)'x';
2061 4 50         String rhs(rexp.c_str());
    50          
2062 2 50         rhs.reserve(120);
    50          
2063 2           get_allocs();
2064 4 50         String s = lhs + std::move(rhs);
    50          
2065 2 50         REQUIRE_STR(s, lhs+rexp, 120);
    50          
    50          
    50          
2066 2 50         REQUIRE(rhs.use_count() == 1); REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
2067 2 50         REQUIRE(!rhs);
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
2068 2 50         CHECK_ALLOCS();
    50          
2069             }
2070 26 50         SECTION("mstr-ptr") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
2071 4 50         String lhs(lexp.c_str());
    50          
2072 2           auto rhs = rexp.c_str();
2073 2 50         lhs.reserve(300);
    50          
2074 2           get_allocs();
2075 4 50         String s = std::move(lhs) + rhs;
    50          
2076 2 50         REQUIRE_STR(s, lexp+rexp, 300);
    50          
    50          
    50          
2077 2 50         REQUIRE(lhs.use_count() == 1); REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
2078 2 50         REQUIRE(!lhs);
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
2079 2 50         CHECK_ALLOCS();
    50          
2080             }
2081 26 50         SECTION("mstr-char") {
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
2082 4 50         String lhs(lexp.c_str());
    50          
2083 2           T rhs = (T)'y';
2084 2 50         lhs.reserve(400);
    50          
2085 2           get_allocs();
2086 4 50         String s = std::move(lhs) + rhs;
    50          
2087 2 50         REQUIRE_STR(s, lexp+rhs, 400);
    50          
    50          
    50          
2088 2 50         REQUIRE(lhs.use_count() == 1); REQUIRE(s.use_count() == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
2089 2 50         REQUIRE(!lhs);
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
2090 2 50         CHECK_ALLOCS();
    50          
2091             }
2092 24           }
2093              
2094 32           static void test_insert_impl (int cnt, bool is_external) {
2095 64 50         auto exp = mstr("a", cnt);
2096 64 100         String s = is_external ? create_external<>(exp) : String(exp.c_str());
    50          
    50          
    50          
    100          
    100          
    0          
    0          
2097 32           get_allocs();
2098 42 50         SECTION("end") {
    50          
    50          
    50          
    100          
2099 12 50         SECTION("has end space") {
    50          
    50          
    50          
    100          
2100 2           s.length(s.length() - 6);
2101 2 50         s.insert(s.length(), cstr(" world"));
    50          
2102 2 50         REQUIRE_STR(s, mstr("a", cnt-6)+mstr(" world"), cnt);
    50          
    50          
    50          
2103 2 50         CHECK_ALLOCS();
2104             }
2105 12 50         SECTION("has head space") {
    50          
    50          
    50          
    100          
2106 2 50         s.offset(cnt - 3);
2107 2 50         s.insert(s.length(), cstr(" world"));
    50          
2108 2 50         REQUIRE_STR(s, mstr("aaa world"), cnt);
    50          
2109 2 50         CHECK_ALLOCS();
2110             }
2111 12 50         SECTION("has both space") {
    50          
    50          
    50          
    100          
2112 2 50         s.offset(4, 3);
2113 2 50         REQUIRE(s.capacity() >= 7);
    50          
    50          
    50          
    50          
    0          
    0          
2114 2 50         s.insert(s.length(), cstr(" XX"));
    50          
2115 2 50         REQUIRE_STR(s, mstr("aaa XX"), cnt-4);
    50          
2116 2 50         CHECK_ALLOCS();
2117             }
2118 12 50         SECTION("has summary space") {
    50          
    50          
    50          
    100          
2119 2 50         s.offset(4, cnt-8); // 4 free from head and tail
2120 2 50         s.insert(s.length(), cstr("world")); // 5 inserted
    50          
2121 2 50         REQUIRE_STR(s, mstr("a", cnt-8)+mstr("world"), cnt); // moved to the beginning
    50          
    50          
    50          
2122 2 50         CHECK_ALLOCS();
2123             }
2124 12 50         SECTION("has no space") {
    50          
    50          
    50          
    100          
2125 2 50         s.offset(2, cnt-4); // 2 free from head and tail
2126 2 50         s.insert(s.length(), cstr("world")); // 5 insterted
    50          
2127 2 50         REQUIRE_STR(s, mstr("a", cnt-4)+mstr("world"), cnt+1); // moved to the beginning
    50          
    50          
    50          
2128 2           auto stat = get_allocs();
2129 2 50         REQUIRE(stat.allocated_cnt == 1);
    50          
    50          
    50          
    50          
    0          
    0          
2130 2 50         REQUIRE(stat.allocated == (int)BUF_CHARS+cnt+1);
    50          
    50          
    50          
    50          
    0          
    0          
2131             }
2132             }
2133 42 50         SECTION("begin") {
    50          
    50          
    50          
    100          
2134 12 50         SECTION("has end space") {
    50          
    50          
    50          
    100          
2135 2           s.length(s.length() - 6);
2136 2 50         s.insert(0, cstr("world "));
    50          
2137 2 50         REQUIRE_STR(s, mstr("world ")+mstr("a",cnt-6), cnt);
    50          
    50          
    50          
2138 2 50         CHECK_ALLOCS();
2139             }
2140 12 50         SECTION("has head space") {
    50          
    50          
    50          
    100          
2141 2 50         s.offset(cnt - 3);
2142 2 50         s.insert(0, cstr("world "));
    50          
2143 2 50         REQUIRE_STR(s, mstr("world aaa"), 9);
    50          
2144 2 50         CHECK_ALLOCS();
2145             }
2146 12 50         SECTION("has both space") {
    50          
    50          
    50          
    100          
2147 2 50         s.offset(3, 4);
2148 2 50         REQUIRE(s.capacity() >= 8);
    50          
    50          
    50          
    50          
    0          
    0          
2149 2 50         s.insert(0, cstr("X "));
    50          
2150 2 50         REQUIRE_STR(s, mstr("X aaaa"), cnt-1);
    50          
2151 2 50         CHECK_ALLOCS();
2152             }
2153 12 50         SECTION("has summary space") {
    50          
    50          
    50          
    100          
2154 2 50         s.offset(4, cnt-8); // 4 free from head and tail
2155 2 50         s.insert(0, cstr("world")); // 5 insterted
    50          
2156 2 50         REQUIRE_STR(s, mstr("world")+mstr("a",cnt-8), cnt); // moved to the beginning
    50          
    50          
    50          
2157 2 50         CHECK_ALLOCS();
2158             }
2159 12 50         SECTION("has no space") {
    50          
    50          
    50          
    100          
2160 2 50         s.offset(2, cnt-4); // 2 free from head and tail
2161 2 50         s.insert(0, cstr("world")); // 5 insterted
    50          
2162 2 50         REQUIRE_STR(s, mstr("world")+mstr("a",cnt-4), cnt+1); // moved to the beginning
    50          
    50          
    50          
2163 2           auto stat = get_allocs();
2164 2 50         REQUIRE(stat.allocated_cnt == 1);
    50          
    50          
    50          
    50          
    0          
    0          
2165 2 50         REQUIRE(stat.allocated == (int)BUF_CHARS+cnt+1);
    50          
    50          
    50          
    50          
    0          
    0          
2166             }
2167             };
2168 44 50         SECTION("middle") {
    50          
    50          
    50          
    100          
2169 14 50         SECTION("has end space") {
    50          
    50          
    50          
    100          
2170 2           s.length(s.length() - 6);
2171 2 50         s.insert(2, cstr("world "));
    50          
2172 2 50         REQUIRE_STR(s, mstr("aaworld ")+mstr("a",cnt-8), cnt);
    50          
    50          
    50          
2173 2 50         CHECK_ALLOCS();
2174             }
2175 14 50         SECTION("has head space") {
    50          
    50          
    50          
    100          
2176 2 50         s.offset(cnt - 3);
2177 2 50         s.insert(2, cstr("world "));
    50          
2178 2 50         REQUIRE_STR(s, mstr("aaworld a"), 9);
    50          
2179 2 50         CHECK_ALLOCS();
2180             }
2181 14 50         SECTION("has both space, head is shorter") {
    50          
    50          
    50          
    100          
2182 2 50         s.offset(4, 3);
2183 2 50         REQUIRE(s.capacity() >= 7);
    50          
    50          
    50          
    50          
    0          
    0          
2184 2 50         s.insert(1, cstr(" X ")); // head is moved (3 bytes left)
    50          
2185 2 50         REQUIRE_STR(s, mstr("a X aa"), cnt-1);
    50          
2186 2 50         CHECK_ALLOCS();
2187             }
2188 14 50         SECTION("has both space, tail is shorter") {
    50          
    50          
    50          
    100          
2189 2 50         s.offset(4, 3);
2190 2 50         s.insert(2, cstr(" X ")); // tail is moved (3 bytes right)
    50          
2191 2 50         REQUIRE_STR(s, mstr("aa X a"), cnt-4);
    50          
2192 2 50         CHECK_ALLOCS();
2193             }
2194 14 50         SECTION("has summary space") {
    50          
    50          
    50          
    100          
2195 2 50         s.offset(4, cnt-8); // 4 free from head and tail
2196 2 50         s.insert(2, cstr("world")); // 5 insterted
    50          
2197 2 50         REQUIRE_STR(s, mstr("aaworld")+mstr("a",cnt-10), cnt); // moved to the beginning
    50          
    50          
    50          
2198 2 50         CHECK_ALLOCS();
2199             }
2200 14 50         SECTION("has no space") {
    50          
    50          
    50          
    100          
2201 2 50         s.offset(2, cnt-4); // 2 free from head and tail
2202 2 50         s.insert(2, cstr("world")); // 5 insterted
    50          
2203 2 50         REQUIRE_STR(s, mstr("aaworld")+mstr("a",cnt-6), cnt+1); // moved to the beginning
    50          
    50          
    50          
2204 2           auto stat = get_allocs();
2205 2 50         REQUIRE(stat.allocated_cnt == 1);
    50          
    50          
    50          
    50          
    0          
    0          
2206 2 50         REQUIRE(stat.allocated == (int)BUF_CHARS+cnt+1);
    50          
    50          
    50          
    50          
    0          
    0          
2207             }
2208             };
2209 32           }
2210              
2211 6           static void test_insert_cow (bool is_external) {
2212 12 50         auto exp = mstr("a", 50);
2213 12 100         String s = is_external ? create_external<>(exp) : String(exp.c_str());
    50          
    50          
    50          
    100          
    100          
    0          
    0          
2214 6           get_allocs();
2215 12 50         String tmp(s);
2216              
2217 8 50         SECTION("end") {
    50          
    50          
    50          
    100          
2218 2           s.length(s.length() - 10);
2219 2 50         s.insert(s.length(), cstr("hello"));
    50          
2220 2 50         REQUIRE_STR(s, mstr("a", 40)+mstr("hello"), 45);
    50          
    50          
    50          
2221 2 50         CHECK_ALLOCS(1, BUF_CHARS+45);
2222             };
2223 8 50         SECTION("begin") {
    50          
    50          
    50          
    100          
2224 2 50         s.offset(10, 30);
2225 2 50         s.insert(0, cstr("hello"));
    50          
2226 2 50         REQUIRE_STR(s, mstr("hello")+mstr("a",30), 35);
    50          
    50          
    50          
2227 2 50         CHECK_ALLOCS(1, BUF_CHARS+35);
2228             };
2229 8 50         SECTION("middle") {
    50          
    50          
    50          
    100          
2230 2 50         s.offset(10, 30);
2231 2 50         s.insert(5, cstr("hello"));
    50          
2232 2 50         REQUIRE_STR(s, mstr("aaaaahello")+mstr("a",25), 35);
    50          
    50          
    50          
2233 2 50         CHECK_ALLOCS(1, BUF_CHARS+35);
2234             };
2235 6           }
2236              
2237 56           static void test_insert () {
2238 56           get_allocs();
2239              
2240 59 50         SECTION("literal") {
    50          
    50          
    50          
    100          
2241 3           get_allocs();
2242 4 50         SECTION("end") {
    50          
    50          
    50          
    100          
2243 2 50         auto exp = mstr(" hello");
2244 2           String s(LITERAL);
2245 1 50         s.insert(s.length(), exp.c_str());
2246 1 50         REQUIRE_STR(s, StdString(LITERAL)+exp);
    50          
    50          
2247 1 50         CHECK_ALLOCS(1, BUF_CHARS + LITERAL_LEN + exp.size());
2248             }
2249 4 50         SECTION("begin") {
    50          
    50          
    50          
    100          
2250 2 50         auto exp = mstr("hello ");
2251 2           String s(LITERAL);
2252 1 50         s.insert(0, exp.c_str());
2253 1 50         REQUIRE_STR(s, exp + StdString(LITERAL));
    50          
    50          
2254 1 50         CHECK_ALLOCS(1, BUF_CHARS + LITERAL_LEN + exp.size());
2255             }
2256 4 50         SECTION("middle") {
    50          
    50          
    50          
    100          
2257 2 50         auto exp = mstr("epta");
2258 2           String s(LITERAL);
2259 1 50         s.insert(5, exp.c_str());
2260 2 50         auto tmp = StdString(LITERAL);
2261 1 50         tmp.insert(5, exp);
2262 1 50         REQUIRE_STR(s, tmp);
    50          
2263 1 50         CHECK_ALLOCS(1, BUF_CHARS+tmp.size());
2264             }
2265             }
2266              
2267             if (CHAR_SIZE == 1) SECTION("sso") { test_insert_impl(MAX_SSO_CHARS, false); }
2268 56 50         SECTION("internal") { test_insert_impl(50, false); }
    50          
    50          
    50          
    100          
    50          
2269 56 50         SECTION("external") { test_insert_impl(50, true); }
    50          
    50          
    50          
    100          
    50          
2270              
2271 112 50         String s (cstr("hello, world"));
    50          
2272 112 50         String a (cstr(" suka"));
    50          
2273 112 50         String2 a2(cstr(" suka"));
    50          
2274              
2275 57 50         SECTION("str") {
    50          
    50          
    50          
    100          
2276 1 50         s.insert(5, a);
2277 1 50         REQUIRE_STRM(s, mstr("hello suka, world"));
    50          
2278 1 50         REQUIRE_THROWS(s.insert(1000, a));
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
2279             }
2280 57 50         SECTION("fstr") {
    50          
    50          
    50          
    100          
2281 1 50         s.insert(6, a2);
2282 1 50         REQUIRE_STRM(s, mstr("hello, suka world"));
    50          
2283             }
2284 57 50         SECTION("str&pos") {
    50          
    50          
    50          
    100          
2285 1 50         s.insert(5, a, 2);
2286 1 50         REQUIRE_STRM(s, mstr("hellouka, world"));
    50          
2287             }
2288 57 50         SECTION("str&pos/len") {
    50          
    50          
    50          
    100          
2289 1 50         s.insert(5, a, 2, 2);
2290 1 50         REQUIRE_STRM(s, mstr("hellouk, world"));
    50          
2291             }
2292 57 50         SECTION("fstr&pos/len") {
    50          
    50          
    50          
    100          
2293 1 50         s.insert(6, a2, 1, 2);
2294 1 50         REQUIRE_STRM(s, mstr("hello,su world"));
    50          
2295             }
2296 57 50         SECTION("ptr") {
    50          
    50          
    50          
    100          
2297 1 50         s.insert(10, cstr("123"));
    50          
2298 1 50         REQUIRE_STRM(s, mstr("hello, wor123ld"));
    50          
2299             }
2300 57 50         SECTION("ptr&len") {
    50          
    50          
    50          
    100          
2301 1 50         s.insert(10, cstr("123"), 2);
    50          
2302 1 50         REQUIRE_STRM(s, mstr("hello, wor12ld"));
    50          
2303             }
2304 57 50         SECTION("=literal=") {
    50          
    50          
    50          
    100          
2305 1 50         s.insert(7, LITERAL);
2306 1 50         REQUIRE_STRM(s, mstr("hello, ")+StdString(LITERAL)+mstr("world"));
    50          
    50          
    50          
    50          
    50          
2307             }
2308 57 50         SECTION("count char") {
    50          
    50          
    50          
    100          
2309 1 50         s.insert(2, 5, (T)'x');
2310 1 50         REQUIRE_STRM(s, mstr("hexxxxxllo, world"));
    50          
2311             }
2312 57 50         SECTION("iterator count char") {
    50          
    50          
    50          
    100          
2313 1 50         auto it = s.insert(s.cbegin()+3, 5, (T)'y');
    50          
2314 1 50         REQUIRE(*it == (T)'y');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2315 1 50         REQUIRE(*(it-1) == (T)'l');
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2316 1 50         REQUIRE_STRM(s, mstr("helyyyyylo, world"));
    50          
2317             }
2318 57 50         SECTION("iterator char") {
    50          
    50          
    50          
    100          
2319 1 50         auto it = s.insert(s.cbegin()+5, (T)'z');
    50          
2320 1 50         REQUIRE(*it == (T)'z');
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2321 1 50         REQUIRE(*(it-1) == (T)'o');
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2322 1 50         REQUIRE_STRM(s, mstr("helloz, world"));
    50          
2323             }
2324 57 50         SECTION("initializer list") {
    50          
    50          
    50          
    100          
2325 1 50         s.insert(s.cbegin()+1, {(T)'h', (T)'i'});
    50          
2326 1 50         REQUIRE_STRM(s, mstr("hhiello, world"));
    50          
2327             }
2328 57 50         SECTION("string_view") {
    50          
    50          
    50          
    100          
2329 1 50         s.insert(9, svstr("x", 5));
    50          
2330 1 50         REQUIRE_STRM(s, mstr("hello, woxxxxxrld"));
    50          
2331             }
2332              
2333 56 50         SECTION("internal cow") { test_insert_cow(false); }
    50          
    50          
    50          
    100          
    50          
2334 56 50         SECTION("external cow") { test_insert_cow(true); }
    50          
    50          
    50          
    100          
    50          
2335              
2336 57 50         SECTION("self") {
    50          
    50          
    50          
    100          
2337 1 50         s = cstr("a", 20);
    50          
2338 1 50         s.insert(10, s);
2339 1 50         REQUIRE_STRM(s, mstr("a", 40));
    50          
2340             }
2341 57 50         SECTION("self&pos/len") {
    50          
    50          
    50          
    100          
2342 1 50         s = cstr("a", 20);
    50          
2343 1 50         s.insert(10, s, 5, 10);
2344 1 50         REQUIRE_STRM(s, mstr("a", 30));
    50          
2345             }
2346 56           }
2347              
2348             // all tests should keep in mind that cnt could be 11 bytes on 32bit
2349 14           static void test_replace_impl (int cnt, bool is_external) {
2350 28 50         auto exp = mstr("a", cnt);
2351 28 100         String s = is_external ? create_external<>(exp) : String(exp.c_str());
    50          
    50          
    50          
    100          
    100          
    0          
    0          
2352 14           get_allocs();
2353              
2354 16 50         SECTION("shrink") {
    50          
    50          
    50          
    100          
2355 2 50         s.replace(3, 4, cstr("hi"));
    50          
2356 2 50         REQUIRE_STR(s, mstr("a",3)+mstr("hi")+mstr("a",cnt-7), cnt);
    50          
    50          
    50          
    50          
    50          
2357 2 50         CHECK_ALLOCS();
2358 2 50         s.replace(0, 4, EMPTY);
2359 2 50         REQUIRE_STR(s, mstr("i")+mstr("a",cnt-7), cnt-4);
    50          
    50          
    50          
2360 2 50         CHECK_ALLOCS();
2361             }
2362              
2363 26 50         SECTION("grow") {
    50          
    50          
    50          
    100          
2364 14 50         SECTION("has end space") {
    50          
    50          
    50          
    100          
2365 2           s.length(s.length() - 3);
2366 2 50         s.replace(3, 3, cstr("world "));
    50          
2367 2 50         REQUIRE_STR(s, mstr("aaaworld ")+mstr("a",cnt-9), cnt);
    50          
    50          
    50          
2368 2 50         CHECK_ALLOCS();
2369             };
2370 14 50         SECTION("has head space") {
    50          
    50          
    50          
    100          
2371 2 50         s.offset(4);
2372 2 50         s.replace(2, 2, cstr(" XX "));
    50          
2373 2 50         REQUIRE_STR(s, mstr("aa XX ")+mstr("a",cnt-8), cnt-2);
    50          
    50          
    50          
2374 2 50         CHECK_ALLOCS();
2375             };
2376 14 50         SECTION("has both space, head is shorter") {
    50          
    50          
    50          
    100          
2377 2 50         s.offset(3, 4);
2378 2 50         REQUIRE(s.capacity() >= 7);
    50          
    50          
    50          
    50          
    0          
    0          
2379 2 50         s.replace(1,2, cstr(" XX ")); // head is moved
    50          
2380 2 50         REQUIRE_STR(s, mstr("a XX a"), cnt-1);
    50          
2381 2 50         CHECK_ALLOCS();
2382             };
2383 14 50         SECTION("has both space, tail is shorter") {
    50          
    50          
    50          
    100          
2384 2 50         s.offset(3, 4);
2385 2 50         s.replace(2,1, cstr(" XX ")); // tail is moved
    50          
2386 2 50         REQUIRE_STR(s, mstr("aa XX a"), cnt-3);
    50          
2387 2 50         CHECK_ALLOCS();
2388             };
2389 14 50         SECTION("has summary space") {
    50          
    50          
    50          
    100          
2390 2 50         s.offset(3, cnt-6); // 3 free from head and tail
2391 2 50         s.replace(2,2, cstr("XXXXXXX")); // 5 inserted
    50          
2392 2 50         REQUIRE_STR(s, mstr("aaXXXXXXX")+mstr("a",cnt-10), cnt); // moved to the beginning
    50          
    50          
    50          
2393 2 50         CHECK_ALLOCS();
2394             };
2395 14 50         SECTION("has no space") {
    50          
    50          
    50          
    100          
2396 2 50         s.offset(2, cnt-4); // 2 free from head and tail
2397 2 50         s.replace(3,2, cstr("XXXXXXX")); // 5 insterted
    50          
2398 2 50         REQUIRE_STR(s, mstr("aaaXXXXXXX")+mstr("a",cnt-9), cnt+1); // moved to the beginning
    50          
    50          
    50          
2399 2           auto stat = get_allocs();
2400 2 50         REQUIRE(stat.allocated_cnt == 1);
    50          
    50          
    50          
    50          
    0          
    0          
2401 2 50         REQUIRE(stat.allocated == (int)BUF_CHARS+cnt+1);
    50          
    50          
    50          
    50          
    0          
    0          
2402             };
2403             }
2404 14           }
2405              
2406 36           static void test_replace () {
2407 38 50         SECTION("literal") {
    50          
    50          
    50          
    100          
2408 4           String s (LITERAL);
2409 4 50         StdString exp(LITERAL);
2410 3 50         SECTION("shrink") {
    50          
    50          
    50          
    100          
2411 1 50         exp.replace(5, 5, cstr("hi"));
    50          
2412 1 50         s.replace(5, 5, cstr("hi"));
    50          
2413 1 50         REQUIRE_STR(s, exp);
    50          
2414 1 50         CHECK_ALLOCS(1, BUF_CHARS + exp.size());
2415             }
2416 3 50         SECTION("grow") {
    50          
    50          
    50          
    100          
2417 1 50         exp.replace(5, 10, cstr("epta"));
    50          
2418 1 50         s.replace(5, 10, cstr("epta"));
    50          
2419 1 50         REQUIRE_STR(s, exp);
    50          
2420 1 50         CHECK_ALLOCS(1, BUF_CHARS + exp.size());
2421             }
2422             }
2423              
2424             if (CHAR_SIZE == 1) SECTION("sso") { test_replace_impl(MAX_SSO_CHARS, false); }
2425 36 50         SECTION("internal") { test_replace_impl(50, false); }
    50          
    50          
    50          
    100          
    50          
2426 36 50         SECTION("external") { test_replace_impl(50, true); }
    50          
    50          
    50          
    100          
    50          
2427              
2428 72 50         String s (cstr("hello, world"));
    50          
2429 72 50         String a (cstr(" suka"));
    50          
2430 72 50         String2 a2(cstr(" suka"));
    50          
2431              
2432 37 50         SECTION("str") {
    50          
    50          
    50          
    100          
2433 1 50         s.replace(6, 6, a);
2434 1 50         REQUIRE_STRM(s, mstr("hello, suka"));
    50          
2435 1 50         s.replace(5, 1000, a);
2436 1 50         REQUIRE_STRM(s, mstr("hello suka"));
    50          
2437 1 50         REQUIRE_THROWS(s.replace(1000, 1, a));
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
2438             }
2439 37 50         SECTION("fstr") {
    50          
    50          
    50          
    100          
2440 1 50         s.replace(1, String::npos, a2);
2441 1 50         REQUIRE_STRM(s, mstr("h suka"));
    50          
2442             }
2443 37 50         SECTION("it/str") {
    50          
    50          
    50          
    100          
2444 1 50         s.replace(s.cbegin()+6, s.cbegin()+12, a);
    50          
    50          
2445 1 50         REQUIRE_STRM(s, mstr("hello, suka"));
    50          
2446 1 50         s.replace(s.cbegin()+5, s.cend()+100, a);
    50          
    50          
2447 1 50         REQUIRE_STRM(s, mstr("hello suka"));
    50          
2448 1 50         REQUIRE_THROWS(s.replace(s.cend()+1, s.end(), a));
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
2449             }
2450              
2451 37 50         SECTION("it/fstr") {
    50          
    50          
    50          
    100          
2452 1 50         s.replace(s.cbegin()+1, s.cend(), a2);
    50          
    50          
2453 1 50         REQUIRE_STRM(s, mstr("h suka"));
    50          
2454             }
2455 37 50         SECTION("str&pos/len") {
    50          
    50          
    50          
    100          
2456 1 50         s.replace(6, 6, a, 1, 2);
2457 1 50         REQUIRE_STRM(s, mstr("hello,su"));
    50          
2458 1 50         s.replace(6, 6, a, 1, 20);
2459 1 50         REQUIRE_STRM(s, mstr("hello,suka"));
    50          
2460 1 50         s.replace(6, 6, a, 1);
2461 1 50         REQUIRE_STRM(s, mstr("hello,suka"));
    50          
2462 1 50         REQUIRE_THROWS(s.replace(6,6,a,10));
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
2463             }
2464 37 50         SECTION("fstr&pos/len") {
    50          
    50          
    50          
    100          
2465 1 50         s.replace(6, 6, a2, 1, 2);
2466 1 50         REQUIRE_STRM(s, mstr("hello,su"));
    50          
2467             }
2468 37 50         SECTION("ptr") {
    50          
    50          
    50          
    100          
2469 1 50         s.replace(6, 6, cstr(" guy"));
    50          
2470 1 50         REQUIRE_STRM(s, mstr("hello, guy"));
    50          
2471             }
2472 37 50         SECTION("ptr&len") {
    50          
    50          
    50          
    100          
2473 1 50         s.replace(6, 6, cstr(" guy"), 3);
    50          
2474 1 50         REQUIRE_STRM(s, mstr("hello, gu"));
    50          
2475             }
2476 37 50         SECTION("=literal=") {
    50          
    50          
    50          
    100          
2477 1 50         s.replace(6,6, LITERAL);
2478 1 50         REQUIRE_STRM(s, mstr("hello,")+StdString(LITERAL));
    50          
    50          
    50          
2479             }
2480 37 50         SECTION("it/ptr") {
    50          
    50          
    50          
    100          
2481 1 50         s.replace(s.cbegin()+6, s.cbegin()+12, cstr(" guy"));
    50          
    50          
    50          
2482 1 50         REQUIRE_STRM(s, mstr("hello, guy"));
    50          
2483             }
2484 37 50         SECTION("it/ptr&len") {
    50          
    50          
    50          
    100          
2485 1 50         s.replace(s.cbegin()+6, s.cbegin()+12, cstr(" guy"), 3);
    50          
    50          
    50          
2486 1 50         REQUIRE_STRM(s, mstr("hello, gu"));
    50          
2487             }
2488 37 50         SECTION("it/=literal=") {
    50          
    50          
    50          
    100          
2489 1 50         s.replace(s.cbegin()+6, s.cbegin()+12, LITERAL);
    50          
    50          
2490 1 50         REQUIRE_STRM(s, mstr("hello,")+StdString(LITERAL));
    50          
    50          
    50          
2491             }
2492 37 50         SECTION("count char") {
    50          
    50          
    50          
    100          
2493 1 50         s.replace(6, 5, 10, (T)'x');
2494 1 50         REQUIRE_STRM(s, mstr("hello,xxxxxxxxxxd"));
    50          
2495             }
2496 37 50         SECTION("it/count char") {
    50          
    50          
    50          
    100          
2497 1 50         s.replace(s.cbegin()+6, s.cbegin()+11, 10, (T)'x');
    50          
    50          
2498 1 50         REQUIRE_STRM(s, mstr("hello,xxxxxxxxxxd"));
    50          
2499             }
2500 37 50         SECTION("initializer list") {
    50          
    50          
    50          
    100          
2501 1 50         s.replace(s.cbegin()+6, s.cbegin()+11, {(T)'h', (T)'i'});
    50          
    50          
2502 1 50         REQUIRE_STRM(s, mstr("hello,hid"));
    50          
2503             }
2504 37 50         SECTION("string_view") {
    50          
    50          
    50          
    100          
2505 1 50         s.replace(6, 6, svstr(" guy"));
    50          
2506 1 50         REQUIRE_STRM(s, mstr("hello, guy"));
    50          
2507             }
2508 37 50         SECTION("it/string_view") {
    50          
    50          
    50          
    100          
2509 1 50         s.replace(s.cbegin()+6, s.cbegin()+12, svstr(" guy"));
    50          
    50          
    50          
2510 1 50         REQUIRE_STRM(s, mstr("hello, guy"));
    50          
2511             }
2512 37 50         SECTION("self") {
    50          
    50          
    50          
    100          
2513 1 50         s = cstr("1234567890", 2);
    50          
2514 1 50         s.replace(3, 5, s);
2515 1 50         REQUIRE_STRM(s, mstr("123")+mstr("1234567890",2)+mstr("90")+mstr("1234567890"));
    50          
    50          
    50          
    50          
    50          
    50          
    50          
2516             }
2517 37 50         SECTION("self&pos/len") {
    50          
    50          
    50          
    100          
2518 1 50         s = cstr("1234567890", 2);
    50          
2519 1 50         s.replace(3, 5, s, 2, 15);
2520 1 50         REQUIRE_STRM(s, mstr("123")+mstr("345678901234567")+mstr("90")+mstr("1234567890"));
    50          
    50          
    50          
    50          
    50          
    50          
    50          
2521             }
2522 37 50         SECTION("it/self") {
    50          
    50          
    50          
    100          
2523 1 50         s = cstr("1234567890", 2);
    50          
2524 1 50         s.replace(s.cbegin()+3, s.cbegin()+8, s);
    50          
    50          
2525 1 50         REQUIRE_STRM(s, mstr("123")+mstr("1234567890",2)+mstr("90")+mstr("1234567890"));
    50          
    50          
    50          
    50          
    50          
    50          
    50          
2526             }
2527 36           }
2528              
2529 4           static void test_shared_detach () {
2530 4           get_allocs();
2531 5 50         SECTION("literal") {
    50          
    50          
    50          
    100          
2532 1           auto llen = LITERAL_LEN;
2533 2           String s(LITERAL);
2534 1 50         s.shared_buf();
2535 1 50         REQUIRE(s.capacity() == llen); // detached
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2536 1 50         CHECK_ALLOCS(1, BUF_CHARS + LITERAL_LEN);
2537             }
2538 5 50         SECTION("sso") {
    50          
    50          
    50          
    100          
2539 1           auto msc = MAX_SSO_CHARS;
2540 2 50         String s(cstr("ab"));
    50          
2541 1 50         s.shared_buf();
2542 1 50         REQUIRE(s.capacity() == msc); // noop
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2543 1 50         CHECK_ALLOCS();
2544             }
2545 5 50         SECTION("internal") {
    50          
    50          
    50          
    100          
2546 2 50         String s(cstr("a", 50));
    50          
2547 1           get_allocs();
2548 1 50         s.offset(0, 10);
2549 1 50         s.shared_buf();
2550 1 50         REQUIRE(s.capacity() == 50); // noop
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2551 1 50         CHECK_ALLOCS();
2552 2 50         String tmp(s);
2553 1 50         s.shared_buf();
2554 1 50         REQUIRE(s.shared_capacity() == 50); // noop
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2555 1 50         CHECK_ALLOCS();
2556             }
2557 5 50         SECTION("external") {
    50          
    50          
    50          
    100          
2558 2 50         String s = create_external(mstr("a",50));
    50          
2559 1           get_allocs();
2560 1 50         s.offset(0, 10);
2561 1 50         s.shared_buf();
2562 1 50         REQUIRE(s.capacity() == 50); // noop
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2563 1 50         CHECK_ALLOCS();
2564 2 50         String tmp(s);
2565 1 50         s.shared_buf();
2566 1 50         REQUIRE(s.shared_capacity() == 50); // noop
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2567 1 50         CHECK_ALLOCS();
2568             }
2569 4           }
2570              
2571 1           static void test_to_from_number () {
2572 1           if (CHAR_SIZE > 1) return;
2573              
2574             SECTION("to number") {
2575             string s(" 1020asd");
2576             uint64_t val;
2577              
2578             auto res = s.to_number(val);
2579             REQUIRE(!res.ec);
2580             REQUIRE(val == 1020);
2581              
2582             res = s.to_number(val, (size_t)3);
2583             REQUIRE(!res.ec);
2584             REQUIRE(val == 20);
2585              
2586             res = s.to_number(val, 4, 1);
2587             REQUIRE(!res.ec);
2588             REQUIRE(val == 2);
2589              
2590             res = s.to_number(val, 0, 999, 16);
2591             REQUIRE(!res.ec);
2592             REQUIRE(val == 66058);
2593              
2594             res = s.to_number(val, 2, 9, 2);
2595             REQUIRE(!res.ec);
2596             REQUIRE(val == 2);
2597              
2598             res = s.to_number(val, (size_t)5);
2599             REQUIRE(!res.ec);
2600             REQUIRE(val == 0);
2601              
2602             REQUIRE(s.to_number(val, (size_t)6).ec);
2603             };
2604              
2605             SECTION("from number") {
2606             string s;
2607             REQUIRE(string::from_number(10) == "10");
2608             REQUIRE(string::from_number(10,8) == "12");
2609             REQUIRE(string::from_number(10, 16) == "a");
2610             CHECK_ALLOCS();
2611             };
2612             }
2613              
2614 5           static void test_foreign_allocator () {
2615 6 50         SECTION("from literal") {
    50          
    50          
    50          
    100          
2616 2           String2 src(LITERAL);
2617 2 50         String s(src);
2618 1 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
2619 1 50         s = EMPTY; src = EMPTY;
    50          
2620 1 50         CHECK_ALLOCS();
2621             };
2622 6 50         SECTION("from sso") {
    50          
    50          
    50          
    100          
2623 2 50         auto exp = mstr("ab");
2624 2 50         String2 src(exp.c_str());
2625 2 50         String s(src);
2626 1 50         REQUIRE_STR(s, exp, MAX_SSO_CHARS);
    50          
2627 1 50         s = EMPTY; src = EMPTY;
    50          
2628 1 50         CHECK_ALLOCS();
2629             };
2630 6 50         SECTION("from internal") {
    50          
    50          
    50          
    100          
2631 2 50         auto exp = mstr("a", 50);
2632 2 50         String2 src(exp.c_str());
2633 1 50         CHECK_ALLOCS(1, BUF_CHARS+exp.size());
2634 2 50         String s(src);
2635 1 50         CHECK_ALLOCS();
2636 1 50         REQUIRE_STR(s, exp, 0, exp.size());
    50          
2637 1 50         src = EMPTY;
2638 1 50         CHECK_ALLOCS();
2639 1 50         s = EMPTY;
2640 1 50         CHECK_ALLOCS(0,0,1,BUF_CHARS+exp.size());
2641             };
2642 6 50         SECTION("from external") {
    50          
    50          
    50          
    100          
2643 2 50         auto exp = mstr("b", 50);
2644 2 50         String2 src = create_external(exp);
    50          
2645 1 50         CHECK_ALLOCS(1, EBUF_CHARS);
2646 2 50         String s(src);
2647 1 50         CHECK_ALLOCS();
2648 1 50         REQUIRE_STR(s, exp, 0, exp.size());
    50          
2649 1 50         src = EMPTY;
2650 1 50         CHECK_ALLOCS();
2651 1 50         s = EMPTY;
2652 1 50         CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp.size());
2653             };
2654 6 50         SECTION("from external with custom buf") {
    50          
    50          
    50          
    100          
2655 2 50         auto exp = mstr("b", 50);
2656 2 50         String2 src = create_external_cbuf(exp);
    50          
2657 2 50         String s(src);
2658 1 50         CHECK_ALLOCS();
2659 1 50         REQUIRE_STR(s, exp, 0, exp.size());
    50          
2660 1 50         src = EMPTY;
2661 1 50         CHECK_ALLOCS();
2662 1 50         s = EMPTY;
2663 1 50         CHECK_ALLOCS(0,0,0,0,0,0,1,exp.size(),1);
2664             };
2665 5           }
2666              
2667 6           static void test_cstr () {
2668 7 50         SECTION("empty") {
    50          
    50          
    50          
    100          
2669 2           String s;
2670 1 50         REQUIRE(s.c_str()[0] == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2671 1 50         REQUIRE_STR(s, EMPTY);
2672 1 50         CHECK_ALLOCS();
2673             }
2674 7 50         SECTION("literal") {
    50          
    50          
    50          
    100          
2675 2           String s(LITERAL);
2676 1 50         REQUIRE(s.c_str()[LITERAL_LEN] == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2677 1 50         REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
2678 1 50         CHECK_ALLOCS();
2679             }
2680 8 50         SECTION("sso") {
    50          
    50          
    50          
    100          
2681 3 50         SECTION("self") {
    50          
    50          
    50          
    100          
2682 2 50         auto exp = mstr("a", MAX_SSO_CHARS-1);
2683 2 50         String s(exp.c_str());
2684 1 50         REQUIRE(s.c_str()[exp.length()] == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2685 1 50         REQUIRE_STR(s, exp, MAX_SSO_CHARS);
    50          
2686 1 50         CHECK_ALLOCS();
2687             }
2688 3 50         SECTION("detach") {
    50          
    50          
    50          
    100          
2689 2 50         auto exp = mstr("a", 50);
2690 2 50         String src(exp.c_str());
2691 1           get_allocs();
2692 2 50         String s = src.substr(0, MAX_SSO_CHARS-1);
2693 1 50         CHECK(s.c_str()[MAX_SSO_CHARS-1] == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2694 1 50         REQUIRE_STR(s, mstr("a", MAX_SSO_CHARS-1), MAX_SSO_CHARS);
    50          
2695 1 50         CHECK_ALLOCS();
2696             }
2697             }
2698 8 50         SECTION("internal") {
    50          
    50          
    50          
    100          
2699 3 50         SECTION("self") {
    50          
    50          
    50          
    100          
2700 2 50         auto exp = mstr("ab", 50);
2701 2 50         String s(exp.c_str());
2702 1           get_allocs();
2703 1 50         REQUIRE(s.c_str()[exp.length()] == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2704 1 50         REQUIRE_STR(s, exp, exp.length() + 1);
    50          
2705 1 50         CHECK_ALLOCS(0,0,0,0,1,1);
2706 1 50         s.c_str();
2707 1 50         CHECK_ALLOCS();
2708             }
2709 3 50         SECTION("detach") {
    50          
    50          
    50          
    100          
2710 2 50         auto exp = mstr("ab", 50);
2711 2 50         String s(exp.c_str());
2712 1           get_allocs();
2713 2 50         String s2(s);
2714 1 50         REQUIRE(s.c_str()[exp.length()] == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
2715 1 50         REQUIRE_STR(s, exp, exp.length() + 1);
    50          
2716 1 50         CHECK_ALLOCS(1,BUF_CHARS+exp.size()+1,0,0,0,0);
2717 1 50         s.c_str();
2718 1 50         CHECK_ALLOCS();
2719             }
2720             }
2721 6           }
2722              
2723 388           static void run () {
2724 388           get_allocs();
2725              
2726 388 50         SECTION("ctor") { test_ctor(); }
    50          
    50          
    50          
    100          
    50          
2727 398 50         SECTION("copy ctor") {
    50          
    50          
    50          
    100          
2728 10 50         SECTION("local") { test_copy_ctor(); }
    50          
    50          
    50          
    100          
    50          
2729 10 50         SECTION("foreign") { test_copy_ctor(); }
    50          
    50          
    50          
    100          
    50          
2730             }
2731 398 50         SECTION("move ctor") {
    50          
    50          
    50          
    100          
2732 10 50         SECTION("local") { test_move_ctor(); }
    50          
    50          
    50          
    100          
    50          
2733 10 50         SECTION("foreign") { test_move_ctor(); }
    50          
    50          
    50          
    100          
    50          
2734             }
2735 400 50         SECTION("copy ctor with offset") {
    50          
    50          
    50          
    100          
2736 12 50         SECTION("local") { test_copy_ctor_offset(); }
    50          
    50          
    50          
    100          
    50          
2737 12 50         SECTION("foreign") { test_copy_ctor_offset(); }
    50          
    50          
    50          
    100          
    50          
2738             }
2739 388 50         SECTION("substr") { test_substr(); }
    50          
    50          
    50          
    100          
    50          
2740 388 50         SECTION("clear") { test_clear(); }
    50          
    50          
    50          
    100          
    50          
2741 494 50         SECTION("assign") {
    50          
    50          
    50          
    100          
2742 106 50         SECTION("local") { test_assign(); }
    50          
    50          
    50          
    100          
    50          
2743 106 50         SECTION("foreign") { test_assign(); }
    50          
    50          
    50          
    100          
    50          
2744             }
2745 388 50         SECTION("offset") { test_offset(); }
    50          
    50          
    50          
    100          
    50          
2746 408 50         SECTION("swap") {
    50          
    50          
    50          
    100          
2747 20 50         SECTION("local") { test_swap(); }
    50          
    50          
    50          
    100          
    50          
2748 20 50         SECTION("foreign") { test_swap(); }
    50          
    50          
    50          
    100          
    50          
2749             }
2750 388 50         SECTION("copy") { test_copy(); }
    50          
    50          
    50          
    100          
    50          
2751 388 50         SECTION("to_bool, empty") { test_bool_empty(); }
    50          
    50          
    50          
    100          
    50          
2752 388 50         SECTION("use_count") { test_use_count(); }
    50          
    50          
    50          
    100          
    50          
2753 388 50         SECTION("detach") { test_detach(); }
    50          
    50          
    50          
    100          
    50          
2754              
2755 388 50         SECTION("at/op[]/front/[pop_]back") { test_at_front_back(); }
    50          
    50          
    50          
    100          
    50          
2756 388 50         SECTION("iterator") { test_iterator(); }
    50          
    50          
    50          
    100          
    50          
2757              
2758 388 50         SECTION("erase") { test_erase(); }
    50          
    50          
    50          
    100          
    50          
2759 390 50         SECTION("compare") {
    50          
    50          
    50          
    100          
2760 2 50         SECTION("local") { test_compare(); }
    50          
    50          
    50          
    100          
    50          
2761 2 50         SECTION("foreign") { test_compare(); }
    50          
    50          
    50          
    100          
    50          
2762             }
2763 400 50         SECTION("find") {
    50          
    50          
    50          
    100          
2764 12 50         SECTION("local") { test_find(); }
    50          
    50          
    50          
    100          
    50          
2765 12 50         SECTION("foreign") { test_find(); }
    50          
    50          
    50          
    100          
    50          
2766             }
2767 388 50         SECTION("reserve") { test_reserve(); }
    50          
    50          
    50          
    100          
    50          
2768 388 50         SECTION("resize") { test_resize(); }
    50          
    50          
    50          
    100          
    50          
2769 388 50         SECTION("shrink_to_fit") { test_shrink_to_fit(); }
    50          
    50          
    50          
    100          
    50          
2770 388 50         SECTION("append") { test_append(); }
    50          
    50          
    50          
    100          
    50          
2771 412 50         SECTION("operator +") {
    50          
    50          
    50          
    100          
2772 24 50         SECTION("local") { test_op_plus(); }
    50          
    50          
    50          
    100          
    50          
2773 24 50         SECTION("foreign") { test_op_plus(); }
    50          
    50          
    50          
    100          
    50          
2774             }
2775 388 50         SECTION("insert") { test_insert(); }
    50          
    50          
    50          
    100          
    50          
2776 388 50         SECTION("replace") { test_replace(); }
    50          
    50          
    50          
    100          
    50          
2777 388 50         SECTION("shared_detach") { test_shared_detach(); }
    50          
    50          
    50          
    100          
    50          
2778 388 50         SECTION("to/from_number") { test_to_from_number(); }
    50          
    50          
    50          
    100          
    50          
2779 388 50         SECTION("from foreign allocator") { test_foreign_allocator(); }
    50          
    50          
    50          
    100          
    50          
2780 388 50         SECTION("c_str") { test_cstr(); }
    50          
    50          
    50          
    100          
    50          
2781 388           }
2782             };
2783              
2784             template const T test_string::LITERAL[38] = {'h','e','l','l','o',' ','w','o','r','l','d',',',' ','t','h','i','s',' ','i','s',' ','a',' ','l','i','t','e','r','a','l',' ','s','t','r','i','n','g',0};
2785             template const T test_string::EMPTY[1] = {0};
2786              
2787             }