1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_string/string.h"
16
17 #include <cstddef>
18 #include <iterator>
19 #include <type_traits>
20
21 #include "pw_compilation_testing/negative_compilation.h"
22 #include "pw_unit_test/framework.h"
23
24 namespace pw {
25 namespace {
26
27 using namespace std::string_view_literals;
28
29 template <typename T>
30 class StringViewLike {
31 public:
StringViewLike(const T * data,size_t size)32 constexpr StringViewLike(const T* data, size_t size) : value_(data, size) {}
33
operator std::basic_string_view<T>() const34 constexpr operator std::basic_string_view<T>() const { return value_; }
35
36 private:
37 std::basic_string_view<T> value_;
38 };
39
40 // The StringView overload ignores types that convert to const T* to avoid
41 // ambiguity with the existing const T* overload.
42 template <typename T>
43 class StringViewLikeButConvertsToPointer : public StringViewLike<T> {
44 public:
45 using StringViewLike<T>::StringViewLike;
46
operator std::basic_string_view<T>() const47 constexpr operator std::basic_string_view<T>() const { return value_; }
operator const T*() const48 constexpr operator const T*() const { return value_.data(); }
49
50 private:
51 std::basic_string_view<T> value_;
52 };
53
54 template <typename T>
55 class EvenNumberIterator {
56 public:
57 using difference_type = std::ptrdiff_t;
58 using value_type = T;
59 using pointer = const T*;
60 using reference = const T&;
61 using iterator_category = std::input_iterator_tag;
62
63 // Rounds down to nearest even.
EvenNumberIterator(value_type value)64 explicit constexpr EvenNumberIterator(value_type value)
65 : value_(static_cast<value_type>(value & ~static_cast<value_type>(1))) {}
66
operator ++()67 constexpr EvenNumberIterator& operator++() {
68 value_ += 2;
69 return *this;
70 }
71
operator *() const72 constexpr const T& operator*() const { return value_; }
73
operator ==(const EvenNumberIterator & rhs) const74 constexpr bool operator==(const EvenNumberIterator& rhs) const {
75 return value_ == rhs.value_;
76 }
77
operator !=(const EvenNumberIterator & rhs) const78 constexpr bool operator!=(const EvenNumberIterator& rhs) const {
79 return value_ != rhs.value_;
80 }
81
82 private:
83 value_type value_;
84 };
85
86 #ifdef __cpp_deduction_guides
87
TEST(InlineString,DeduceBasicString_Char)88 TEST(InlineString, DeduceBasicString_Char) {
89 InlineBasicString string_10("1234567890");
90 static_assert(std::is_same_v<decltype(string_10), InlineString<10>>);
91
92 InlineBasicString string_3 = "abc";
93 static_assert(std::is_same_v<decltype(string_3), InlineString<3>>);
94
95 string_10.resize(6);
96 EXPECT_STREQ(
97 string_10.append(string_3).append(InlineBasicString("?")).c_str(),
98 "123456abc?");
99 }
100
TEST(InlineString,DeduceBasicString_Int)101 TEST(InlineString, DeduceBasicString_Int) {
102 constexpr char kCharArray[4] = {0, 1, 2, 0};
103 InlineBasicString string_3 = kCharArray;
104 static_assert(std::is_same_v<decltype(string_3), InlineBasicString<char, 3>>);
105
106 EXPECT_EQ(string_3, InlineBasicString(kCharArray));
107 }
108
109 // Test CTAD on the InlineString alias, if supported.
110 #if __cpp_deduction_guides >= 201907L
111
TEST(InlineString,DeduceString)112 TEST(InlineString, DeduceString) {
113 InlineString string("123456789");
114 static_assert(std::is_same_v<decltype(string), InlineString<10>>);
115
116 EXPECT_STREQ("123456789", string.c_str());
117 }
118
119 #endif // __cpp_deduction_guides >= 201907L
120 #endif // __cpp_deduction_guides
121
122 template <typename T, size_t kExpectedSize>
TestEqual(const T * string,const T (& expected)[kExpectedSize])123 constexpr bool TestEqual(const T* string, const T (&expected)[kExpectedSize]) {
124 for (size_t i = 0; i < kExpectedSize; ++i) {
125 if (string[i] != expected[i]) {
126 return false;
127 }
128 }
129 return true;
130 }
131
132 // Compares a pw::InlineBasicString to a null-terminated array of characters.
133 #define EXPECT_PW_STRING(pw_string, array) \
134 ASSERT_EQ(pw_string.size(), sizeof(array) / sizeof(array[0]) - 1); \
135 ASSERT_EQ(pw_string.c_str()[pw_string.size()], decltype(array[0]){0}); \
136 EXPECT_TRUE(TestEqual(pw_string.c_str(), array))
137
138 #define EXPECT_CONSTEXPR_PW_STRING(string, array) \
139 static_assert(string.size() == sizeof(array) / sizeof(array[0]) - 1, \
140 #string ".size() == sizeof(" #array ") - 1 FAILED"); \
141 static_assert(string.c_str()[string.size()] == decltype(array[0]){0}, \
142 #string " must be null terminated"); \
143 static_assert(TestEqual(string.c_str(), array), \
144 #string " == " #array " FAILED")
145
146 // This macro performs operations on a string and checks the result.
147 //
148 // 1. Declare a string variable named fixed_str using the provided
149 // initialization statement. fixed_str can be used in tests that
150 // specifically want a known-capacity string.
151 // 2. Declare a generic-capacity generic_str reference for use in tests that
152 // specifically want to use a generic-capacity string.
153 // 3. Declare a str reference for use in tests. It is fixed-capacity in
154 // constexpr tests and known-capacity in runtime tests.
155 // 4. Execute the provided statements.
156 // 5. Check that str equals the provided string literal.
157 //
158 // The test is executed twice:
159 // - At compile time (with constexpr and static_assert) on a known-length
160 // string (InlineString<kLength>).
161 // - At runtime a generic reference (InlineString<>&) at runtime.
162 #if __cpp_constexpr >= 201603L // constexpr lambdas are required
163 #define TEST_CONSTEXPR_STRING(create_string, statements, expected) \
164 do { \
165 constexpr auto constexpr_str = [] { \
166 [[maybe_unused]] auto fixed_str = create_string; \
167 [[maybe_unused]] auto& str = fixed_str; \
168 [[maybe_unused]] auto& generic_str = Generic(fixed_str); \
169 statements; \
170 return str; \
171 }(); \
172 EXPECT_CONSTEXPR_PW_STRING(constexpr_str, expected); \
173 } while (0)
174 #else // Skip constexpr tests in C++14.
175 #define TEST_CONSTEXPR_STRING(create_string, statements, expected) \
176 do { \
177 constexpr auto str = create_string; \
178 EXPECT_NE(str.data(), nullptr); \
179 } while (0)
180 #endif //__cpp_constexpr >= 201603L
181
182 #define TEST_RUNTIME_STRING(create_string, statements, expected) \
183 do { \
184 [[maybe_unused]] auto fixed_str = create_string; \
185 [[maybe_unused]] auto& generic_str = Generic(fixed_str); \
186 [[maybe_unused]] auto& str = generic_str; \
187 statements; \
188 EXPECT_PW_STRING(str, expected); \
189 } while (0)
190
191 #define TEST_STRING(create_string, statements, expected) \
192 TEST_CONSTEXPR_STRING(create_string, statements, expected); \
193 TEST_RUNTIME_STRING(create_string, statements, expected)
194
195 // Casts any pw::InlineString to a generic (runtime-capacity) reference.
196 template <typename T>
Generic(const InlineBasicString<T> & str)197 constexpr const InlineBasicString<T>& Generic(const InlineBasicString<T>& str) {
198 return str;
199 }
200
201 template <typename T>
Generic(InlineBasicString<T> & str)202 constexpr InlineBasicString<T>& Generic(InlineBasicString<T>& str) {
203 return str;
204 }
205
206 constexpr InlineString<0> kEmptyCapacity0;
207 constexpr InlineString<10> kEmptyCapacity10;
208
209 constexpr InlineString<10> kSize5Capacity10 = "12345";
210 constexpr InlineString<10> kSize10Capacity10("1234567890", 10);
211
212 constexpr const char* kPointer0 = "";
213 constexpr const char* kPointer10 = "9876543210";
214
215 constexpr const char kArrayNull1[1] = {'\0'};
216 constexpr const char kArray5[5] = {'1', '2', '3', '4', '\0'};
217
218 // Invalid, non-terminated arrays used in negative compilation tests.
219 [[maybe_unused]] constexpr const char kArrayNonNull1[1] = {'?'};
220 [[maybe_unused]] constexpr const char kArrayNonNull5[5] = {
221 '1', '2', '3', '4', '5'};
222
223 constexpr EvenNumberIterator<char> kEvenNumbers0(0);
224 constexpr EvenNumberIterator<char> kEvenNumbers2(2);
225 constexpr EvenNumberIterator<char> kEvenNumbers8(8);
226
227 constexpr std::string_view kView0;
228 constexpr std::string_view kView5 = "12345"sv;
229 constexpr std::string_view kView10 = "1234567890"sv;
230
231 constexpr StringViewLike<char> kStringViewLike10("0123456789", 10);
232
233 //
234 // Construction and assignment
235 //
236
237 // Constructor
238
TEST(InlineString,Construct_Default)239 TEST(InlineString, Construct_Default) {
240 constexpr InlineString<0> kEmpty0;
241 static_assert(kEmpty0.empty(), "Must be empty");
242 static_assert(kEmpty0.c_str()[0] == '\0', "Must be null terminated");
243
244 constexpr InlineString<10> kEmpty10;
245 static_assert(kEmpty10.empty(), "Must be empty");
246 static_assert(kEmpty10.c_str()[0] == '\0', "Must be null terminated");
247 }
248
TEST(InlineString,Construct_Characters)249 TEST(InlineString, Construct_Characters) {
250 TEST_STRING(InlineString<0>(0, 'a'), , "");
251 TEST_STRING(InlineString<10>(0, 'a'), , "");
252
253 TEST_STRING(InlineString<1>(1, 'a'), , "a");
254 TEST_STRING(InlineString<10>(1, 'a'), , "a");
255
256 TEST_STRING(InlineString<10>(10, 'a'), , "aaaaaaaaaa");
257
258 TEST_STRING(InlineString<10>(0, '\0'), , "");
259 TEST_STRING(InlineString<10>(1, '\0'), , "\0");
260 TEST_STRING(InlineString<10>(5, '\0'), , "\0\0\0\0\0");
261
262 #if PW_NC_TEST(Construct_Char_TooMany_0)
263 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
264 [[maybe_unused]] constexpr InlineString<0> too_large(1, 'A');
265 #elif PW_NC_TEST(Construct_Char_TooMany_10)
266 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
267 [[maybe_unused]] constexpr InlineString<10> too_large(11, 'A');
268 #endif // PW_NC_TEST
269 }
270 // NOLINTNEXTLINE(google-readability-function-size)
TEST(InlineString,Construct_Substr)271 TEST(InlineString, Construct_Substr) {
272 TEST_STRING(InlineString<10>(kEmptyCapacity0, 0), , "");
273 TEST_STRING(InlineString<10>(kEmptyCapacity0, 0, 0), , "");
274 TEST_STRING(InlineString<10>(Generic(kEmptyCapacity0), 0), , "");
275 TEST_STRING(InlineString<10>(Generic(kEmptyCapacity0), 0, 0), , "");
276
277 TEST_STRING(InlineString<0>(kEmptyCapacity10, 0), , "");
278 TEST_STRING(InlineString<0>(kEmptyCapacity10, 0, 0), , "");
279 TEST_RUNTIME_STRING(InlineString<0>(Generic(kEmptyCapacity10), 0), , "");
280 TEST_RUNTIME_STRING(InlineString<0>(Generic(kEmptyCapacity10), 0, 0), , "");
281
282 TEST_STRING(InlineString<10>(kSize5Capacity10, 0), , "12345");
283 TEST_RUNTIME_STRING(
284 InlineString<10>(Generic(kSize5Capacity10), 0), , "12345");
285 TEST_STRING(InlineString<10>(kSize5Capacity10, 1), , "2345");
286 TEST_RUNTIME_STRING(InlineString<10>(Generic(kSize5Capacity10), 1), , "2345");
287 TEST_STRING(InlineString<10>(kSize5Capacity10, 4), , "5");
288 TEST_RUNTIME_STRING(InlineString<10>(Generic(kSize5Capacity10), 4), , "5");
289 TEST_STRING(InlineString<10>(kSize5Capacity10, 5), , "");
290 TEST_RUNTIME_STRING(InlineString<10>(Generic(kSize5Capacity10), 5), , "");
291
292 TEST_STRING(InlineString<10>(kSize5Capacity10, 0, 0), , "");
293 TEST_RUNTIME_STRING(InlineString<10>(Generic(kSize5Capacity10), 0, 0), , "");
294 TEST_STRING(InlineString<10>(kSize5Capacity10, 0, 1), , "1");
295 TEST_RUNTIME_STRING(InlineString<10>(Generic(kSize5Capacity10), 0, 1), , "1");
296 TEST_STRING(InlineString<10>(kSize5Capacity10, 1, 0), , "");
297 TEST_RUNTIME_STRING(InlineString<10>(Generic(kSize5Capacity10), 1, 0), , "");
298 TEST_STRING(InlineString<10>(kSize5Capacity10, 1, 1), , "2");
299 TEST_RUNTIME_STRING(InlineString<10>(Generic(kSize5Capacity10), 1, 1), , "2");
300 TEST_STRING(InlineString<10>(kSize5Capacity10, 1, 4), , "2345");
301 TEST_RUNTIME_STRING(
302 InlineString<10>(Generic(kSize5Capacity10), 1, 4), , "2345");
303 TEST_STRING(InlineString<10>(kSize5Capacity10, 1, 5), , "2345");
304 TEST_RUNTIME_STRING(
305 InlineString<10>(Generic(kSize5Capacity10), 1, 4), , "2345");
306 TEST_STRING(InlineString<10>(kSize5Capacity10, 1, 9000), , "2345");
307 TEST_RUNTIME_STRING(
308 InlineString<10>(Generic(kSize5Capacity10), 1, 9000), , "2345");
309
310 TEST_STRING(InlineString<10>(kSize5Capacity10, 4, 9000), , "5");
311 TEST_RUNTIME_STRING(
312 InlineString<10>(Generic(kSize5Capacity10), 4, 9000), , "5");
313
314 TEST_STRING(InlineString<10>(kSize5Capacity10, 5, 0), , "");
315 TEST_RUNTIME_STRING(InlineString<10>(Generic(kSize5Capacity10), 5, 0), , "");
316 TEST_STRING(InlineString<10>(kSize5Capacity10, 5, 1), , "");
317 TEST_RUNTIME_STRING(InlineString<10>(Generic(kSize5Capacity10), 5, 1), , "");
318
319 #if PW_NC_TEST(Construct_Substr_IndexPastEnd)
320 PW_NC_EXPECT("PW_ASSERT\(index <= source_size\)");
321 [[maybe_unused]] constexpr InlineString<10> bad_string(kSize5Capacity10, 6);
322 #endif // PW_NC_TEST
323 }
324
TEST(InlineString,Construct_PointerLength)325 TEST(InlineString, Construct_PointerLength) {
326 TEST_STRING(InlineString<0>(static_cast<const char*>(nullptr), 0), , "");
327 TEST_STRING(InlineString<10>(static_cast<const char*>(nullptr), 0), , "");
328
329 TEST_STRING(InlineString<0>(kPointer0, 0), , "");
330 TEST_STRING(InlineString<0>(kPointer10, 0), , "");
331 TEST_STRING(InlineString<10>(kPointer10, 0), , "");
332
333 TEST_STRING(InlineString<1>(kPointer10, 1), , "9");
334 TEST_STRING(InlineString<5>(kPointer10, 1), , "9");
335
336 TEST_STRING(InlineString<5>(kPointer10, 4), , "9876");
337 TEST_STRING(InlineString<5>(kPointer10 + 1, 4), , "8765");
338
339 TEST_STRING(InlineString<5>(kPointer10, 5), , "98765");
340 TEST_STRING(InlineString<5>(kPointer10 + 1, 5), , "87654");
341
342 #if PW_NC_TEST(Construct_PointerLength_LengthLargerThanCapacity)
343 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
344 [[maybe_unused]] constexpr InlineString<5> bad_string(kPointer10, 6);
345 #elif PW_NC_TEST(Construct_PointerLength_LengthLargerThanInputString)
346 PW_NC_EXPECT_CLANG(
347 "constexpr variable 'bad_string' must be initialized by a constant "
348 "expression");
349 PW_NC_EXPECT_GCC("outside the bounds of array type");
350 [[maybe_unused]] constexpr InlineString<10> bad_string(kPointer10 + 6, 7);
351 #endif // PW_NC_TEST
352 }
353
TEST(InlineString,Construct_Pointer)354 TEST(InlineString, Construct_Pointer) {
355 TEST_STRING(InlineString<10>(static_cast<const char*>("")), , "");
356 TEST_STRING(InlineString<10>(kPointer10), , "9876543210");
357 TEST_STRING(InlineString<10>(kPointer10 + 5), , "43210");
358 TEST_STRING(InlineString<10>(kPointer10 + 10), , "");
359
360 TEST_STRING(InlineString<10>(static_cast<const char*>("ab\0cde")), , "ab");
361 TEST_STRING(InlineString<2>(static_cast<const char*>("ab\0cde")), , "ab");
362
363 #if PW_NC_TEST(Construct_Pointer_LargerThanCapacity)
364 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
365 [[maybe_unused]] constexpr InlineString<5> bad_string(kPointer10);
366 #endif // PW_NC_TEST
367 }
368
TEST(InlineString,Construct_Array)369 TEST(InlineString, Construct_Array) {
370 TEST_STRING(InlineString<0>(""), , "");
371
372 TEST_STRING(InlineString<1>(""), , "");
373 TEST_STRING(InlineString<10>(""), , "");
374
375 TEST_STRING(InlineString<2>("A"), , "A");
376 TEST_STRING(InlineString<10>("A"), , "A");
377 TEST_STRING(InlineString<10>("123456789"), , "123456789");
378
379 TEST_STRING(InlineString<2>("\0"), , "");
380 TEST_STRING(InlineString<10>(""), , "");
381 TEST_STRING(InlineString<10>("12\000456789"), , "12");
382
383 TEST_STRING(InlineString<1>(kArrayNull1), , "");
384 TEST_STRING(InlineString<5>(kArray5), , "1234");
385 TEST_STRING(InlineString<10>(kArray5), , "1234");
386
387 #if PW_NC_TEST(Construct_Array_NullTerminationIsRequiredFillsCapacity)
388 PW_NC_EXPECT("PW_ASSERT\(.*The array is not null terminated");
389 [[maybe_unused]] constexpr InlineString<1> bad_string(kArrayNonNull1);
390 #elif PW_NC_TEST(Construct_Array_NullTerminationIsRequiredExtraCapacity)
391 PW_NC_EXPECT("PW_ASSERT\(.*The array is not null terminated");
392 [[maybe_unused]] constexpr InlineString<10> bad_string(kArrayNonNull5);
393 #elif PW_NC_TEST(Construct_Array_NonTerminatedArrayDoesNotFit)
394 PW_NC_EXPECT(
395 "InlineString's capacity is too small to hold the assigned string");
396 [[maybe_unused]] constexpr InlineString<3> bad_string(kArrayNonNull5);
397 #elif PW_NC_TEST(Construct_Array_SingleCharLiteralRequiresCapacityOfAtLeast1)
398 PW_NC_EXPECT(
399 "InlineString's capacity is too small to hold the assigned string");
400 [[maybe_unused]] constexpr InlineString<0> bad_string("A");
401 #elif PW_NC_TEST(Construct_Array_5CharLiteralRequiresCapacityOfAtLeast5)
402 PW_NC_EXPECT(
403 "InlineString's capacity is too small to hold the assigned string");
404 [[maybe_unused]] constexpr InlineString<4> bad_string("ACDEF");
405 #elif PW_NC_TEST(Construct_Array_TooManyNulls)
406 PW_NC_EXPECT(
407 "InlineString's capacity is too small to hold the assigned string");
408 [[maybe_unused]] constexpr InlineString<3> bad_string(kArray5);
409 #endif // PW_NC_TEST
410 }
411
TEST(InlineString,Construct_Iterator)412 TEST(InlineString, Construct_Iterator) {
413 TEST_STRING(InlineString<0>(kView0.begin(), kView0.end()), , "");
414 TEST_STRING(InlineString<0>(kView5.end(), kView5.end()), , "");
415 TEST_STRING(InlineString<5>(kView0.begin(), kView0.end()), , "");
416 TEST_STRING(InlineString<5>(kView5.end(), kView5.end()), , "");
417
418 TEST_STRING(InlineString<5>(kView5.begin(), kView5.end()), , "12345");
419 TEST_STRING(InlineString<10>(kView5.begin(), kView5.end()), , "12345");
420 TEST_STRING(InlineString<10>(kView10.begin(), kView10.end()), , "1234567890");
421
422 TEST_STRING(InlineString<0>(kEvenNumbers0, kEvenNumbers0), , "");
423 TEST_STRING(InlineString<10>(kEvenNumbers2, kEvenNumbers2), , "");
424
425 TEST_STRING(InlineString<4>(kEvenNumbers0, kEvenNumbers2), , "\0");
426 TEST_STRING(InlineString<4>(kEvenNumbers0, kEvenNumbers8), , "\0\2\4\6");
427 TEST_STRING(InlineString<10>(kEvenNumbers0, kEvenNumbers8), , "\0\2\4\6");
428
429 #if PW_NC_TEST(Construct_Iterator_DoesNotFit)
430 PW_NC_EXPECT("PW_ASSERT\(current_position != string_end\)");
431 [[maybe_unused]] constexpr InlineString<3> str(kEvenNumbers0, kEvenNumbers8);
432 #endif // PW_NC_TEST
433 }
434
TEST(InlineString,Construct_CopySameCapacity)435 TEST(InlineString, Construct_CopySameCapacity) {
436 static_assert(std::is_trivially_copyable<InlineString<0>>(), "Copy");
437 static_assert(std::is_trivially_copyable<InlineString<10>>(), "Copy");
438 static_assert(std::is_trivially_copyable<InlineBasicString<char, 10>>(),
439 "Copy");
440
441 TEST_STRING(InlineString<0>(kEmptyCapacity0), , "");
442 TEST_STRING(InlineString<10>(kEmptyCapacity10), , "");
443 TEST_STRING(InlineString<10>(kSize5Capacity10), , "12345");
444 TEST_STRING(InlineString<10>(kSize10Capacity10), , "1234567890");
445 }
446
TEST(InlineString,Construct_CopyDifferentCapacity)447 TEST(InlineString, Construct_CopyDifferentCapacity) {
448 TEST_STRING(InlineString<1>(kEmptyCapacity0), , "");
449 TEST_STRING(InlineString<5>(kEmptyCapacity0), , "");
450 TEST_STRING(InlineString<11>(kEmptyCapacity10), , "");
451 TEST_STRING(InlineString<11>(kSize5Capacity10), , "12345");
452 TEST_STRING(InlineString<11>(kSize10Capacity10), , "1234567890");
453 TEST_STRING(InlineString<30>(kSize10Capacity10), , "1234567890");
454
455 #if PW_NC_TEST(Construct_CopyDifferentCapacity_DoesNotFit)
456 PW_NC_EXPECT(
457 "pw::InlineString must be at least as large as the source string");
458 [[maybe_unused]] InlineString<5> bad_string(kEmptyCapacity10);
459 #elif PW_NC_TEST(Construct_CopyDifferentCapacity_DoesNotFitConstexpr)
460 PW_NC_EXPECT(
461 "pw::InlineString must be at least as large as the source string");
462 constexpr [[maybe_unused]] InlineString<5> bad_string(kEmptyCapacity10);
463 #endif // PW_NC_TEST
464 }
465
TEST(InlineString,Construct_CopyGenericCapacity)466 TEST(InlineString, Construct_CopyGenericCapacity) {
467 TEST_STRING(InlineString<10>(Generic(kEmptyCapacity0)), , "");
468 TEST_RUNTIME_STRING(InlineString<10>(Generic(kEmptyCapacity10)), , "");
469 TEST_RUNTIME_STRING(InlineString<10>(Generic(kSize5Capacity10)), , "12345");
470 TEST_RUNTIME_STRING(
471 InlineString<10>(Generic(kSize10Capacity10)), , "1234567890");
472 TEST_RUNTIME_STRING(
473 InlineString<20>(Generic(kSize10Capacity10)), , "1234567890");
474 }
475
TEST(InlineString,Construct_InitializerList)476 TEST(InlineString, Construct_InitializerList) {
477 TEST_STRING(InlineString<0>({}), , "");
478 TEST_STRING(InlineString<1>({}), , "");
479 TEST_STRING(InlineString<10>({}), , "");
480
481 TEST_STRING(InlineString<1>({'\0'}), , "\0");
482 TEST_STRING(InlineString<1>({'?'}), , "?");
483
484 TEST_STRING(InlineString<5>({'A'}), , "A");
485 TEST_STRING(InlineString<5>({'\0', '\0', '\0'}), , "\0\0\0");
486 TEST_STRING(InlineString<5>({'5', '4', '3', '2', '1'}), , "54321");
487
488 #if PW_NC_TEST(Construct_InitializerList_DoesNotFit)
489 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
490 [[maybe_unused]] constexpr InlineString<3> bad_string({'1', '2', '3', '\0'});
491 #endif // PW_NC_TEST
492 }
493
TakesInlineString(const InlineString<16> & str)494 constexpr InlineString<16> TakesInlineString(const InlineString<16>& str) {
495 return str;
496 }
497
498 struct HoldsString {
499 InlineString<16> value;
500 };
501
TEST(InlineString,Construct_StringView)502 TEST(InlineString, Construct_StringView) {
503 TEST_STRING(InlineString<0>(""sv), , "");
504 TEST_STRING(InlineString<10>(""sv), , "");
505 TEST_STRING(InlineString<10>("01234"sv), , "01234");
506 TEST_STRING(InlineString<10>("0123456789"sv), , "0123456789");
507 TEST_STRING(InlineString<20>("0123456789"sv), , "0123456789");
508
509 TEST_STRING(InlineString<10>(StringViewLike<char>("01234", 5)), , "01234");
510 TEST_STRING(InlineString<10>(kStringViewLike10), , "0123456789");
511
512 // pw::InlineString supports implicit conversion from std::string_view.
513 constexpr InlineString<16> implicit_call = TakesInlineString("1234"sv);
514 EXPECT_CONSTEXPR_PW_STRING(implicit_call, "1234");
515
516 constexpr HoldsString implicit_initialize_1{.value = "1234"sv};
517 EXPECT_CONSTEXPR_PW_STRING(implicit_initialize_1.value, "1234");
518
519 constexpr HoldsString implicit_initialize_2{.value{"1234"sv}};
520 EXPECT_CONSTEXPR_PW_STRING(implicit_initialize_2.value, "1234");
521
522 constexpr HoldsString implicit_initialize_3{"1234"sv};
523 EXPECT_CONSTEXPR_PW_STRING(implicit_initialize_3.value, "1234");
524
525 #if PW_NC_TEST(Construct_StringView_DoesNotFit)
526 PW_NC_EXPECT(
527 "pw::InlineString must be at least as large as the source string");
528 [[maybe_unused]] InlineString<5> bad_string(kEmptyCapacity10);
529 #elif PW_NC_TEST(Construct_StringView_DoesNotFitConstexpr)
530 PW_NC_EXPECT(
531 "pw::InlineString must be at least as large as the source string");
532 constexpr [[maybe_unused]] InlineString<5> bad_string(kEmptyCapacity10);
533 #elif PW_NC_TEST(Construct_StringView_NoConversionFromAmbiguousClass)
534 PW_NC_EXPECT_CLANG("no matching constructor");
535 PW_NC_EXPECT_GCC("no matching function for call to");
536 [[maybe_unused]] InlineString<10> fail(
537 StringViewLikeButConvertsToPointer<char>("1", 1));
538 #elif PW_NC_TEST(Construct_StringView_NoImplicitConversionFromStringViewLike)
539 PW_NC_EXPECT_CLANG("no matching function for call to 'TakesInlineString'");
540 PW_NC_EXPECT_GCC(
541 "invalid initialization of reference of type .* from expression of type "
542 "'const pw::.*StringViewLike<char>'");
543 TakesInlineString(kStringViewLike10);
544 #elif PW_NC_TEST(Construct_StringView_NoImplicitConvFromStringViewLikeInInit1)
545 PW_NC_EXPECT_GCC("could not convert 'pw::.*kStringViewLike10'");
546 PW_NC_EXPECT_CLANG("no viable conversion from 'const StringViewLike<char>'");
547 (void)HoldsString{.value = kStringViewLike10};
548 #elif PW_NC_TEST(Construct_StringView_NoImplicitConvFromStringViewLikeInInit2)
549 PW_NC_EXPECT_GCC("could not convert 'pw::.*kStringViewLike10'");
550 PW_NC_EXPECT_CLANG("no viable conversion from 'const StringViewLike<char>'");
551 (void)HoldsString{kStringViewLike10};
552 #endif // PW_NC_TEST
553 }
554
TEST(InlineString,Construct_StringViewSubstr)555 TEST(InlineString, Construct_StringViewSubstr) {
556 TEST_STRING(InlineString<0>(""sv, 0, 0), , "");
557 TEST_STRING(InlineString<5>(""sv, 0, 0), , "");
558
559 TEST_STRING(InlineString<5>("0123456789"sv, 5, 0), , "");
560 TEST_STRING(InlineString<5>("0123456789"sv, 10, 0), , "");
561
562 TEST_STRING(InlineString<5>("0123456789"sv, 0, 5), , "01234");
563 TEST_STRING(InlineString<5>("0123456789"sv, 1, 5), , "12345");
564 TEST_STRING(InlineString<5>("0123456789"sv, 8, 2), , "89");
565 TEST_STRING(InlineString<5>("0123456789"sv, 8, 10), , "89");
566 TEST_STRING(InlineString<5>("0123456789"sv, 10, 100), , "");
567
568 TEST_STRING(InlineString<10>("0123456789"sv, 0, 10), , "0123456789");
569 TEST_STRING(InlineString<10>("0123456789"sv, 0, 100), , "0123456789");
570
571 TEST_STRING(InlineString<10>(kStringViewLike10, 0, 100), , "0123456789");
572
573 #if PW_NC_TEST(Construct_StringViewSubstr_DoesNotFit)
574 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
575 [[maybe_unused]] constexpr InlineString<10> bad_string(
576 "0123456789?"sv, 0, 11);
577 #elif PW_NC_TEST(Construct_StringViewSubstr_IndexTooFar)
578 PW_NC_EXPECT_CLANG("must be initialized by a constant expression");
579 PW_NC_EXPECT_GCC("call to non-'constexpr' function");
580 [[maybe_unused]] constexpr InlineString<10> bad_string("12345"sv, 6, 0);
581 #endif // PW_NC_TEST
582 }
583
TEST(InlineString,Construct_Nullptr)584 TEST(InlineString, Construct_Nullptr) {
585 #if PW_NC_TEST(Construct_Nullptr)
586 PW_NC_EXPECT("Cannot construct from nullptr");
587 [[maybe_unused]] constexpr InlineString<0> bad_string(nullptr);
588 #endif // PW_NC_TEST
589 }
590
591 // operator=
592
TEST(InlineString,AssignOperator_Copy)593 TEST(InlineString, AssignOperator_Copy) {
594 TEST_STRING(InlineString<0>(), fixed_str = InlineString<0>(), "");
595 TEST_STRING(InlineString<10>("something"),
596 fixed_str = InlineString<9>("el\0se"),
597 "el");
598 TEST_STRING(InlineString<10>("0_o"), fixed_str = InlineString<10>(), "");
599
600 #if PW_NC_TEST(AssignOperator_Copy_DoesNotFit)
601 PW_NC_EXPECT(
602 "pw::InlineString must be at least as large as the source string");
603 [[maybe_unused]] constexpr auto fail = [] {
604 InlineString<5> str;
605 return str = InlineString<6>("2big");
606 }();
607 #elif PW_NC_TEST(AssignOperator_Copy_NotSupportedByGeneric)
608 PW_NC_EXPECT("operator=.*protected");
609 [[maybe_unused]] constexpr auto fail = [] {
610 InlineString<5> str;
611 return Generic(str) = InlineString<0>();
612 }();
613 #endif // PW_NC_TEST
614 }
615
TEST(InlineString,AssignOperator_Array)616 TEST(InlineString, AssignOperator_Array) {
617 TEST_STRING(InlineString<1>({'a'}), fixed_str = "", "");
618 TEST_STRING(InlineString<10>("hey"), fixed_str = "wow", "wow");
619 TEST_STRING(InlineString<10>("hey"), fixed_str = "123456789", "123456789");
620
621 #if PW_NC_TEST(AssignOperator_Array_DoesNotFit)
622 PW_NC_EXPECT(
623 "InlineString's capacity is too small to hold the assigned string");
624 [[maybe_unused]] constexpr auto fail = [] {
625 InlineString<4> str("abc");
626 return str = "12345";
627 }();
628 #elif PW_NC_TEST(AssignOperator_Array_NotSupportedByGeneric)
629 PW_NC_EXPECT("operator=");
630 [[maybe_unused]] constexpr auto fail = [] {
631 InlineString<5> str("abc");
632 return Generic(str) = "";
633 }();
634 #endif // PW_NC_TEST
635 }
636
TEST(InlineString,AssignOperator_Pointer)637 TEST(InlineString, AssignOperator_Pointer) {
638 TEST_STRING(InlineString<1>({'a'}), fixed_str = kPointer0, "");
639 TEST_STRING(InlineString<10>("hey"),
640 fixed_str = static_cast<const char*>("wow"),
641 "wow");
642 TEST_STRING(InlineString<10>("hey"), fixed_str = kPointer10, "9876543210");
643
644 #if PW_NC_TEST(AssignOperator_Pointer_DoesNotFit)
645 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
646 [[maybe_unused]] constexpr auto fail = [] {
647 InlineString<5> str("abc");
648 return str = static_cast<const char*>("123456");
649 }();
650 #elif PW_NC_TEST(AssignPointer_Pointer_NotSupportedByGeneric)
651 PW_NC_EXPECT("operator=");
652 [[maybe_unused]] constexpr auto fail = [] {
653 InlineString<5> str("abc");
654 return Generic(str) = kPointer0;
655 }();
656 #endif // PW_NC_TEST
657 }
658
TEST(InlineString,AssignOperator_Character)659 TEST(InlineString, AssignOperator_Character) {
660 TEST_STRING(InlineString<1>(), fixed_str = '\0', "\0");
661 TEST_STRING(InlineString<1>({'a'}), fixed_str = '\0', "\0");
662 TEST_STRING(InlineString<10>("hey"), fixed_str = '?', "?");
663
664 #if PW_NC_TEST(AssignPointer_Character_DoesNotFit)
665 PW_NC_EXPECT("Cannot assign a character to pw::InlineString<0>");
666 [[maybe_unused]] constexpr auto fail = [] {
667 InlineString<0> str;
668 return str = 'a';
669 }();
670 #endif // PW_NC_TEST
671 }
672
TEST(InlineString,AssignOperator_InitializerList)673 TEST(InlineString, AssignOperator_InitializerList) {
674 TEST_STRING(InlineString<1>(), fixed_str = {'\0'}, "\0");
675 TEST_STRING(InlineString<1>({'a'}), fixed_str = {'\0'}, "\0");
676 TEST_STRING(
677 InlineString<10>("hey"), (fixed_str = {'W', 'h', 'y', '?'}), "Why?");
678
679 #if PW_NC_TEST(AssignPointer_InitializerList_DoesNotFit)
680 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
681 [[maybe_unused]] constexpr auto fail = [] {
682 InlineString<2> str;
683 return str = {'1', '2', '3'};
684 }();
685 #endif // PW_NC_TEST
686 }
687
TEST(InlineString,AssignOperator_StringView)688 TEST(InlineString, AssignOperator_StringView) {
689 TEST_STRING(InlineString<1>(), fixed_str = "\0"sv, "\0");
690 TEST_STRING(InlineString<1>({'a'}), fixed_str = "\0"sv, "\0");
691 TEST_STRING(InlineString<10>("hey"), fixed_str = "Why?"sv, "Why?");
692
693 #if PW_NC_TEST(AssignPointer_StringView_DoesNotFit)
694 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
695 [[maybe_unused]] constexpr auto fail = [] {
696 InlineString<2> str;
697 return str = "123"sv;
698 }();
699 #endif // PW_NC_TEST
700 }
701
702 // assign
703
TEST(InlineString,Assign_Characters)704 TEST(InlineString, Assign_Characters) {
705 TEST_STRING(InlineString<0>(), str.assign(0, 'a'), "");
706 TEST_STRING(InlineString<10>(), str.assign(0, 'a'), "");
707 TEST_STRING(InlineString<10>("hey"), str.assign(0, 'a'), "");
708
709 TEST_STRING(InlineString<1>(), str.assign(1, 'a'), "a");
710 TEST_STRING(InlineString<10>(), str.assign(10, 'a'), "aaaaaaaaaa");
711
712 TEST_STRING(InlineString<1>({'?'}), str.assign(1, 'a'), "a");
713 TEST_STRING(InlineString<10>("1"), str.assign(1, 'a'), "a");
714 TEST_STRING(InlineString<10>("123456789"), str.assign(1, 'a'), "a");
715 TEST_STRING(InlineString<10>("?"), str.assign(10, 'a'), "aaaaaaaaaa");
716
717 TEST_STRING(InlineString<5>("?"), str.assign(0, '\0'), "");
718 TEST_STRING(InlineString<5>("?"), str.assign(1, '\0'), "\0");
719 TEST_STRING(InlineString<5>("?"), str.assign(5, '\0'), "\0\0\0\0\0");
720 TEST_STRING(InlineString<10>("???"), str.assign(5, '\0'), "\0\0\0\0\0");
721
722 #if PW_NC_TEST(Assign_Characters_TooMany)
723 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
724 [[maybe_unused]] constexpr auto value = [] {
725 InlineString<6> str;
726 return str.assign(7, '?');
727 }();
728 #endif // PW_NC_TEST
729 }
730
TEST(InlineString,Assign_CopySameCapacity)731 TEST(InlineString, Assign_CopySameCapacity) {
732 TEST_STRING(InlineString<0>(), str.assign(kEmptyCapacity0), "");
733 TEST_STRING(InlineString<10>(), str.assign(kEmptyCapacity10), "");
734 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10), "12345");
735 TEST_STRING(InlineString<10>(), str.assign(kSize10Capacity10), "1234567890");
736 }
737
TEST(InlineString,Assign_CopyDifferentCapacity)738 TEST(InlineString, Assign_CopyDifferentCapacity) {
739 TEST_STRING(InlineString<1>(), str.assign(kEmptyCapacity0), "");
740 TEST_STRING(InlineString<5>(), str.assign(kEmptyCapacity0), "");
741 TEST_STRING(InlineString<11>(), str.assign(kEmptyCapacity10), "");
742 TEST_STRING(InlineString<11>(), str.assign(kSize5Capacity10), "12345");
743 TEST_STRING(InlineString<11>(), str.assign(kSize10Capacity10), "1234567890");
744 TEST_STRING(InlineString<30>(), str.assign(kSize10Capacity10), "1234567890");
745
746 #if PW_NC_TEST(Assign_CopyDifferentCapacity_DoesNotFit)
747 PW_NC_EXPECT(
748 "pw::InlineString must be at least as large as the source string");
749 [[maybe_unused]] InlineString<5> bad_string;
750 bad_string.assign(kEmptyCapacity10);
751 #elif PW_NC_TEST(Assign_CopyDifferentCapacity_DoesNotFitConstexpr)
752 PW_NC_EXPECT(
753 "pw::InlineString must be at least as large as the source string");
754 [[maybe_unused]] InlineString<5> bad_string;
755 bad_string.assign(kEmptyCapacity10);
756 #endif // PW_NC_TEST
757 }
758
TEST(InlineString,Assign_CopyGenericCapacity)759 TEST(InlineString, Assign_CopyGenericCapacity) {
760 TEST_STRING(InlineString<10>(), str.assign(Generic(kEmptyCapacity0)), "");
761 TEST_RUNTIME_STRING(
762 InlineString<10>(), str.assign(Generic(kEmptyCapacity10)), "");
763 TEST_RUNTIME_STRING(
764 InlineString<10>(), str.assign(Generic(kSize5Capacity10)), "12345");
765 TEST_RUNTIME_STRING(
766 InlineString<10>(), str.assign(Generic(kSize10Capacity10)), "1234567890");
767 TEST_RUNTIME_STRING(
768 InlineString<20>(), str.assign(Generic(kSize10Capacity10)), "1234567890");
769 }
770
TEST(InlineString,Assign_Substr)771 TEST(InlineString, Assign_Substr) { // NOLINT(google-readability-function-size)
772 TEST_STRING(InlineString<10>(), str.assign(kEmptyCapacity0, 0), "");
773 TEST_STRING(InlineString<10>(), str.assign(kEmptyCapacity0, 0, 0), "");
774 TEST_STRING(InlineString<10>(), str.assign(Generic(kEmptyCapacity0), 0), "");
775 TEST_STRING(
776 InlineString<10>(), str.assign(Generic(kEmptyCapacity0), 0, 0), "");
777
778 TEST_STRING(InlineString<0>(), str.assign(kEmptyCapacity10, 0), "");
779 TEST_STRING(InlineString<0>(), str.assign(kEmptyCapacity10, 0, 0), "");
780 TEST_RUNTIME_STRING(
781 InlineString<0>(), str.assign(Generic(kEmptyCapacity10), 0), "");
782 TEST_RUNTIME_STRING(
783 InlineString<0>(), str.assign(Generic(kEmptyCapacity10), 0, 0), "");
784
785 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 0), "12345");
786 TEST_RUNTIME_STRING(
787 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 0), "12345");
788 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 1), "2345");
789 TEST_RUNTIME_STRING(
790 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 1), "2345");
791 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 4), "5");
792 TEST_RUNTIME_STRING(
793 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 4), "5");
794 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 5), "");
795 TEST_RUNTIME_STRING(
796 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 5), "");
797
798 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 0, 0), "");
799 TEST_RUNTIME_STRING(
800 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 0, 0), "");
801 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 0, 1), "1");
802 TEST_RUNTIME_STRING(
803 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 0, 1), "1");
804 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 1, 0), "");
805 TEST_RUNTIME_STRING(
806 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 1, 0), "");
807 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 1, 1), "2");
808 TEST_RUNTIME_STRING(
809 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 1, 1), "2");
810 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 1, 4), "2345");
811 TEST_RUNTIME_STRING(
812 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 1, 4), "2345");
813
814 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 4, 9000), "5");
815 TEST_RUNTIME_STRING(
816 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 4, 9000), "5");
817
818 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 5, 0), "");
819 TEST_RUNTIME_STRING(
820 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 5, 0), "");
821 TEST_STRING(InlineString<10>(), str.assign(kSize5Capacity10, 5, 1), "");
822 TEST_RUNTIME_STRING(
823 InlineString<10>(), str.assign(Generic(kSize5Capacity10), 5, 1), "");
824
825 #if PW_NC_TEST(Assign_Substr_IndexPastEnd)
826 PW_NC_EXPECT("PW_ASSERT\(index <= source_size\)");
827 [[maybe_unused]] constexpr auto bad_string = [] {
828 InlineString<10> str;
829 return str.assign(kSize5Capacity10, 6);
830 }();
831 #endif // PW_NC_TEST
832 }
833
TEST(InlineString,Assign_PointerLength)834 TEST(InlineString, Assign_PointerLength) {
835 TEST_STRING(InlineString<0>(), str.assign(nullptr, 0), "");
836 TEST_STRING(InlineString<10>(), str.assign(nullptr, 0), "");
837
838 TEST_STRING(InlineString<0>(), str.assign(kPointer0, 0), "");
839 TEST_STRING(InlineString<0>(), str.assign(kPointer10, 0), "");
840 TEST_STRING(InlineString<10>("abc"), str.assign(kPointer10, 0), "");
841
842 TEST_STRING(InlineString<1>(), str.assign(kPointer10, 1), "9");
843 TEST_STRING(InlineString<5>("?"), str.assign(kPointer10, 1), "9");
844
845 TEST_STRING(InlineString<5>("?"), str.assign(kPointer10, 4), "9876");
846 TEST_STRING(InlineString<5>("?"), str.assign(kPointer10 + 1, 4), "8765");
847
848 TEST_STRING(InlineString<5>("?"), str.assign(kPointer10, 5), "98765");
849 TEST_STRING(InlineString<5>("?"), str.assign(kPointer10 + 1, 5), "87654");
850
851 #if PW_NC_TEST(Assign_PointerLength_LengthLargerThanCapacity)
852 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
853 [[maybe_unused]] constexpr auto bad_string = [] {
854 InlineString<5> str;
855 return str.assign(kPointer10, 6);
856 }();
857 #elif PW_NC_TEST(Assign_PointerLength_LengthLargerThanInputString)
858 PW_NC_EXPECT_CLANG(
859 "constexpr variable 'bad_string' must be initialized by a constant "
860 "expression");
861 PW_NC_EXPECT_GCC("outside the bounds of array type");
862 [[maybe_unused]] constexpr auto bad_string = [] {
863 InlineString<10> str;
864 return str.assign(kPointer10 + 6, 7);
865 }();
866 #endif // PW_NC_TEST
867 }
868
TEST(InlineString,Assign_Pointer)869 TEST(InlineString, Assign_Pointer) {
870 TEST_STRING(
871 InlineString<10>("\0"), str.assign(static_cast<const char*>("")), "");
872 TEST_STRING(InlineString<10>("abc"), str.assign(kPointer10), "9876543210");
873 TEST_STRING(InlineString<10>("abc"), str.assign(kPointer10 + 5), "43210");
874 TEST_STRING(InlineString<10>("abc"), str.assign(kPointer10 + 10), "");
875
876 TEST_STRING(InlineString<10>(),
877 str.assign(static_cast<const char*>("ab\0cde")),
878 "ab");
879 TEST_STRING(
880 InlineString<2>(), str.assign(static_cast<const char*>("ab\0cde")), "ab");
881
882 #if PW_NC_TEST(Assign_Pointer_LargerThanCapacity)
883 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
884 [[maybe_unused]] constexpr auto bad_string = [] {
885 InlineString<5> str;
886 return str.assign(kPointer10);
887 }();
888 #endif // PW_NC_TEST
889 }
890
TEST(InlineString,Assign_Array)891 TEST(InlineString, Assign_Array) {
892 TEST_STRING(InlineString<0>(), str.assign(""), "");
893 TEST_STRING(InlineString<1>(), str.assign(""), "");
894 TEST_STRING(InlineString<10>("a"), str.assign(""), "");
895
896 TEST_STRING(InlineString<1>(), str.assign("A"), "A");
897 TEST_STRING(InlineString<10>(), str.assign("A"), "A");
898 TEST_STRING(InlineString<10>(), str.assign("123456789"), "123456789");
899
900 TEST_STRING(InlineString<1>(), str.assign("\0"), "");
901 TEST_STRING(InlineString<10>(), str.assign("\0"), "");
902 TEST_STRING(InlineString<10>(), str.assign("12\000456789"), "12");
903
904 TEST_STRING(InlineString<1>(""), str.assign(kArrayNull1), "");
905 TEST_STRING(InlineString<5>(), str.assign(kArray5), "1234");
906 TEST_STRING(InlineString<10>(), str.assign(kArray5), "1234");
907
908 TEST_RUNTIME_STRING(InlineString<1>(), Generic(str).assign("?"), "?");
909 TEST_RUNTIME_STRING(
910 InlineString<5>("abcd"), Generic(str).assign("12345"), "12345");
911
912 #if 0 // Triggers PW_ASSERT
913 [[maybe_unused]] InlineString<5> too_small("abcd");
914 Generic(too_small).assign("123456");
915 #endif // 0
916
917 #if PW_NC_TEST(Assign_Array_NullTerminationIsRequiredFillsCapacity)
918 PW_NC_EXPECT("PW_ASSERT\(.*The array is not null terminated");
919 [[maybe_unused]] constexpr auto fail = [] {
920 InlineString<1> bad_string;
921 return bad_string.assign(kArrayNonNull1);
922 }();
923 #elif PW_NC_TEST(Assign_Array_NullTerminationIsRequiredExtraCapacity)
924 PW_NC_EXPECT("PW_ASSERT\(.*The array is not null terminated");
925 [[maybe_unused]] constexpr auto fail = [] {
926 InlineString<10> bad_string;
927 return bad_string.assign(kArrayNonNull5);
928 }();
929 #elif PW_NC_TEST(Assign_Array_NonTerminatedArrayDoesNotFit)
930 PW_NC_EXPECT(
931 "InlineString's capacity is too small to hold the assigned string");
932 [[maybe_unused]] constexpr auto fail = [] {
933 InlineString<3> bad_string;
934 return bad_string.assign(kArrayNonNull5);
935 }();
936 #elif PW_NC_TEST(Assign_Array_SingleCharLiteralRequiresCapacityOfAtLeast1)
937 PW_NC_EXPECT(
938 "InlineString's capacity is too small to hold the assigned string");
939 [[maybe_unused]] constexpr auto fail = [] {
940 InlineString<0> str;
941 return str.assign("?");
942 }();
943 #endif // PW_NC_TEST
944 }
945
TEST(InlineString,Assign_Iterator)946 TEST(InlineString, Assign_Iterator) {
947 TEST_STRING(InlineString<0>(), str.assign(kView0.begin(), kView0.end()), "");
948 TEST_STRING(InlineString<0>(), str.assign(kView5.end(), kView5.end()), "");
949 TEST_STRING(
950 InlineString<5>("abc"), str.assign(kView0.begin(), kView0.end()), "");
951 TEST_STRING(
952 InlineString<5>("abc"), str.assign(kView5.end(), kView5.end()), "");
953
954 TEST_STRING(
955 InlineString<5>(), str.assign(kView5.begin(), kView5.end()), "12345");
956 TEST_STRING(InlineString<10>("abc"),
957 str.assign(kView5.begin(), kView5.end()),
958 "12345");
959 TEST_STRING(InlineString<10>("abc"),
960 str.assign(kView10.begin(), kView10.end()),
961 "1234567890");
962
963 TEST_STRING(InlineString<0>(), str.assign(kEvenNumbers0, kEvenNumbers0), "");
964 TEST_STRING(InlineString<10>(), str.assign(kEvenNumbers2, kEvenNumbers2), "");
965
966 TEST_STRING(
967 InlineString<4>("abc"), str.assign(kEvenNumbers0, kEvenNumbers2), "\0");
968 TEST_STRING(InlineString<4>("abc"),
969 str.assign(kEvenNumbers0, kEvenNumbers8),
970 "\0\2\4\6");
971 TEST_STRING(InlineString<10>("abc"),
972 str.assign(kEvenNumbers0, kEvenNumbers8),
973 "\0\2\4\6");
974
975 #if PW_NC_TEST(Assign_Iterator_DoesNotFit)
976 PW_NC_EXPECT("PW_ASSERT\(current_position != string_end\)");
977 [[maybe_unused]] constexpr auto bad_string = [] {
978 InlineString<3> str;
979 return str.assign(kEvenNumbers0, kEvenNumbers8);
980 }();
981 #endif // PW_NC_TEST
982 }
983
TEST(InlineString,Assign_InitializerList)984 TEST(InlineString, Assign_InitializerList) {
985 TEST_STRING(InlineString<0>(), str.assign({}), "");
986 TEST_STRING(InlineString<1>(), str.assign({}), "");
987 TEST_STRING(InlineString<10>("abc"), str.assign({}), "");
988
989 TEST_STRING(InlineString<1>(), str.assign({'\0'}), "\0");
990 TEST_STRING(InlineString<1>(), str.assign({'?'}), "?");
991
992 TEST_STRING(InlineString<5>("abc"), str.assign({'A'}), "A");
993 TEST_STRING(InlineString<5>("abc"), str.assign({'\0', '\0', '\0'}), "\0\0\0");
994 TEST_STRING(
995 InlineString<5>("abc"), str.assign({'5', '4', '3', '2', '1'}), "54321");
996
997 #if PW_NC_TEST(Assign_InitializerList_DoesNotFit)
998 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
999 [[maybe_unused]] constexpr auto bad_string = [] {
1000 InlineString<3> str;
1001 return str.assign({'1', '2', '3', '\0'});
1002 }();
1003 #endif // PW_NC_TEST
1004 }
1005
TEST(InlineString,Assign_StringView)1006 TEST(InlineString, Assign_StringView) {
1007 TEST_STRING(InlineString<0>(), str.assign(""sv), "");
1008 TEST_STRING(InlineString<10>("abc"), str.assign(""sv), "");
1009 TEST_STRING(InlineString<10>("abc"), str.assign("01234"sv), "01234");
1010 TEST_STRING(
1011 InlineString<10>("abc"), str.assign("0123456789"sv), "0123456789");
1012 TEST_STRING(InlineString<20>(), str.assign("0123456789"sv), "0123456789");
1013
1014 TEST_STRING(InlineString<10>("abc"),
1015 str.assign(StringViewLike<char>("01234", 5)),
1016 "01234");
1017 TEST_STRING(InlineString<10>(), str.assign(kStringViewLike10), "0123456789");
1018
1019 #if PW_NC_TEST(Assign_StringView_DoesNotFit)
1020 PW_NC_EXPECT(
1021 "pw::InlineString must be at least as large as the source string");
1022 [[maybe_unused]] InlineString<5> bad_string;
1023 bad_string.assign(kEmptyCapacity10);
1024 #elif PW_NC_TEST(Assign_StringView_DoesNotFitConstexpr)
1025 PW_NC_EXPECT(
1026 "pw::InlineString must be at least as large as the source string");
1027 [[maybe_unused]] constexpr auto bad_string = [] {
1028 InlineString<5> str;
1029 str.assign(kEmptyCapacity10);
1030 return str;
1031 }();
1032 #elif PW_NC_TEST(Assign_StringView_NoAssignmentFromAmbiguousClass)
1033 PW_NC_EXPECT_CLANG("no matching member function for call to");
1034 PW_NC_EXPECT_GCC("no matching function for call to");
1035 [[maybe_unused]] InlineString<10> fail;
1036 fail.assign(StringViewLikeButConvertsToPointer<char>("1", 1));
1037 #endif // PW_NC_TEST
1038 }
1039
1040 // NOLINTNEXTLINE(google-readability-function-size)
TEST(InlineString,Assign_StringViewSubstr)1041 TEST(InlineString, Assign_StringViewSubstr) {
1042 TEST_STRING(InlineString<0>(), str.assign(""sv, 0, 0), "");
1043 TEST_STRING(InlineString<5>(), str.assign(""sv, 0, 0), "");
1044
1045 TEST_STRING(InlineString<5>(), str.assign("0123456789"sv, 5, 0), "");
1046 TEST_STRING(InlineString<5>(), str.assign("0123456789"sv, 10, 0), "");
1047
1048 TEST_STRING(InlineString<5>(), str.assign("0123456789"sv, 0, 5), "01234");
1049 TEST_STRING(InlineString<5>(), str.assign("0123456789"sv, 1, 5), "12345");
1050 TEST_STRING(InlineString<5>(), str.assign("0123456789"sv, 8, 2), "89");
1051 TEST_STRING(InlineString<5>(), str.assign("0123456789"sv, 8, 10), "89");
1052 TEST_STRING(InlineString<5>(), str.assign("0123456789"sv, 10, 10), "");
1053 TEST_STRING(InlineString<5>(), str.assign("0123456789"sv, 10, 100), "");
1054
1055 TEST_STRING(
1056 InlineString<10>(), str.assign("0123456789"sv, 0, 10), "0123456789");
1057 TEST_STRING(
1058 InlineString<10>(), str.assign("0123456789"sv, 0, 100), "0123456789");
1059
1060 TEST_STRING(
1061 InlineString<10>(), str.assign(kStringViewLike10, 0, 100), "0123456789");
1062
1063 #if PW_NC_TEST(Assign_StringViewSubstr_DoesNotFit)
1064 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
1065 [[maybe_unused]] constexpr auto bad_string = [] {
1066 InlineString<10> str;
1067 return str.assign("0123456789?"sv, 0, 11);
1068 }();
1069 #elif PW_NC_TEST(Assign_StringViewSubstr_IndexTooFar)
1070 PW_NC_EXPECT_CLANG("must be initialized by a constant expression");
1071 PW_NC_EXPECT_GCC("call to non-'constexpr' function");
1072 [[maybe_unused]] constexpr auto bad_string = [] {
1073 InlineString<10> str;
1074 return str.assign("12345"sv, 6, 0);
1075 }();
1076 #endif // PW_NC_TEST
1077 }
1078
1079 //
1080 // Element access
1081 //
1082
TEST(InlineString,At)1083 TEST(InlineString, At) {
1084 static_assert(kSize5Capacity10.at(0) == '1', "1");
1085 static_assert(kSize5Capacity10.at(1) == '2', "2");
1086 static_assert(kSize5Capacity10.at(2) == '3', "3");
1087 static_assert(kSize5Capacity10.at(3) == '4', "4");
1088 static_assert(kSize5Capacity10.at(4) == '5', "5");
1089
1090 static_assert(kSize10Capacity10.at(9) == '0', "null");
1091
1092 EXPECT_EQ(Generic(kSize5Capacity10).at(0), '1');
1093 EXPECT_EQ(Generic(kSize5Capacity10).at(1), '2');
1094 EXPECT_EQ(Generic(kSize5Capacity10).at(2), '3');
1095 EXPECT_EQ(Generic(kSize5Capacity10).at(3), '4');
1096 EXPECT_EQ(Generic(kSize5Capacity10).at(4), '5');
1097
1098 #if PW_NC_TEST(At_OutOfBounds)
1099 PW_NC_EXPECT("PW_ASSERT\(index < length\(\)\);");
1100 [[maybe_unused]] constexpr char out_of_bounds = kSize5Capacity10.at(5);
1101 #endif // PW_NC_TEST
1102 }
1103
TEST(InlineString,SubscriptOperator)1104 TEST(InlineString, SubscriptOperator) {
1105 static_assert(kSize5Capacity10[0] == '1', "1");
1106 static_assert(kSize5Capacity10[1] == '2', "2");
1107 static_assert(kSize5Capacity10[2] == '3', "3");
1108 static_assert(kSize5Capacity10[3] == '4', "4");
1109 static_assert(kSize5Capacity10[4] == '5', "5");
1110
1111 static_assert(kSize10Capacity10[9] == '0', "null");
1112
1113 EXPECT_EQ(Generic(kSize5Capacity10)[0], '1');
1114 EXPECT_EQ(Generic(kSize5Capacity10)[1], '2');
1115 EXPECT_EQ(Generic(kSize5Capacity10)[2], '3');
1116 EXPECT_EQ(Generic(kSize5Capacity10)[3], '4');
1117 EXPECT_EQ(Generic(kSize5Capacity10)[4], '5');
1118
1119 static_assert(kSize5Capacity10[5] == '\0', "No range checking");
1120 static_assert(kSize5Capacity10[6] == '\0', "No range checking");
1121 }
1122
TEST(InlineString,FrontBack)1123 TEST(InlineString, FrontBack) {
1124 static_assert(kSize10Capacity10.front() == '1', "1");
1125 static_assert(kSize10Capacity10.back() == '0', "0");
1126 EXPECT_EQ(Generic(kSize10Capacity10).front(), '1');
1127 EXPECT_EQ(Generic(kSize10Capacity10).back(), '0');
1128 }
1129
TEST(InlineString,DataCStr)1130 TEST(InlineString, DataCStr) {
1131 static_assert(kSize10Capacity10.data() == kSize10Capacity10.c_str(),
1132 "data() and c_str()");
1133 EXPECT_EQ(Generic(kSize10Capacity10).data(),
1134 Generic(kSize10Capacity10).c_str());
1135
1136 EXPECT_STREQ(kSize10Capacity10.data(), "1234567890");
1137 EXPECT_STREQ(kSize10Capacity10.c_str(), "1234567890");
1138 }
1139
TEST(InlineString,ConvertsToStringView)1140 TEST(InlineString, ConvertsToStringView) {
1141 static_assert(std::string_view(kSize5Capacity10) == "12345"sv);
1142 EXPECT_EQ(std::string_view(Generic(kSize5Capacity10)), "12345"sv);
1143 }
1144
1145 //
1146 // Iterators
1147 //
1148
TEST(InlineString,Iterators)1149 TEST(InlineString, Iterators) {
1150 static_assert(kEmptyCapacity10.begin() == kEmptyCapacity10.end());
1151 static_assert(kSize5Capacity10.end() - kSize5Capacity10.begin() == 5u);
1152 static_assert(kSize5Capacity10.begin() + 5 == kSize5Capacity10.end());
1153
1154 static_assert(*kSize5Capacity10.begin() == '1');
1155 static_assert(*(kSize5Capacity10.begin() + 1) == '2');
1156
1157 static_assert(kEmptyCapacity10.rbegin() == kEmptyCapacity10.rend());
1158 static_assert(kSize5Capacity10.rend() - kSize5Capacity10.rbegin() == 5u);
1159 static_assert(kSize5Capacity10.rbegin() + 5 == kSize5Capacity10.rend());
1160
1161 static_assert(*kSize5Capacity10.rbegin() == '5');
1162 static_assert(*(kSize5Capacity10.rbegin() + 1) == '4');
1163
1164 static_assert(kSize5Capacity10.begin() == kSize5Capacity10.cbegin());
1165 static_assert(kSize5Capacity10.end() == kSize5Capacity10.cend());
1166 static_assert(kSize5Capacity10.rbegin() == kSize5Capacity10.crbegin());
1167 static_assert(kSize5Capacity10.rend() == kSize5Capacity10.crend());
1168
1169 static_assert([] {
1170 char expected = '1';
1171 for (char ch : kSize5Capacity10) {
1172 if (ch != expected) {
1173 return false;
1174 }
1175 expected += 1;
1176 }
1177 return true;
1178 }());
1179 }
1180
1181 //
1182 // Capacity
1183 //
1184
TEST(InlineString,Size)1185 TEST(InlineString, Size) {
1186 static_assert(kEmptyCapacity0.empty(), "empty");
1187 static_assert(kEmptyCapacity10.empty(), "empty");
1188
1189 static_assert(kEmptyCapacity10.size() == 0u, "0"); // NOLINT
1190 static_assert(kSize5Capacity10.size() == 5u, "5");
1191 static_assert(kEmptyCapacity10.length() == 0u, "0"); // NOLINT
1192 static_assert(kSize5Capacity10.length() == 5u, "5");
1193 }
1194
TEST(InlineString,MaxSize)1195 TEST(InlineString, MaxSize) {
1196 static_assert(InlineString<0>().max_size() == 0u, "0");
1197 static_assert(InlineString<1>().max_size() == 1u, "1");
1198 static_assert(InlineString<10>().max_size() == 10u, "10");
1199 static_assert(InlineString<10>("123").max_size() == 10u, "10");
1200 static_assert(Generic(InlineString<10>("123")).max_size() == 10u, "10");
1201
1202 static_assert(InlineString<0>().capacity() == 0u, "0");
1203 static_assert(InlineString<10>().capacity() == 10u, "10");
1204 }
1205
1206 //
1207 // Operations
1208 //
1209
1210 // clear
1211
TEST(InlineString,Clear)1212 TEST(InlineString, Clear) {
1213 TEST_STRING(InlineString<0>(), str.clear(), "");
1214 TEST_STRING(InlineString<8>(), str.clear(), "");
1215 TEST_STRING(InlineString<8>("stuff"), str.clear(), "");
1216 TEST_RUNTIME_STRING(InlineString<8>("stuff"), generic_str.clear(), "");
1217 TEST_STRING(InlineString<8>("!!"), str.clear(); str.assign("?"), "?");
1218 }
1219
1220 // insert
1221
TEST(InlineString,Insert_CharactersAtIndex)1222 TEST(InlineString, Insert_CharactersAtIndex) {
1223 TEST_STRING(InlineString<1>(), str.insert(0, 0, 'b'), "");
1224 TEST_STRING(InlineString<1>("a"), str.insert(0, 0, 'b'), "a");
1225 TEST_STRING(InlineString<10>("a"), str.insert(0, 2, 'b'), "bba");
1226 TEST_STRING(InlineString<10>("a"), str.insert(1, 2, 'b'), "abb");
1227 TEST_STRING(InlineString<10>(), str.insert(0, 10, 'b'), "bbbbbbbbbb");
1228 }
1229 #if PW_NC_TEST(Insert_CharactersAtIndex_DoesNotFit)
1230 PW_NC_EXPECT("PW_ASSERT\(size\(\) - index <= max_size\(\) - new_index\)");
__anon055724311a02null1231 [[maybe_unused]] constexpr auto fail = [] {
1232 InlineString<3> str({0, 1});
1233 return str.insert(1, 2, '?');
1234 }();
1235 #endif // PW_NC_TEST
1236
TEST(InlineString,Insert_PointerSizeAtIndex)1237 TEST(InlineString, Insert_PointerSizeAtIndex) {
1238 TEST_STRING(InlineString<1>(), str.insert(0, "", 0), "");
1239 TEST_STRING(InlineString<1>("a"), str.insert(0, "b", 0), "a");
1240 TEST_STRING(InlineString<10>("a"), str.insert(0, "bb", 2), "bba");
1241 TEST_STRING(InlineString<10>("a"), str.insert(1, "bb", 2), "abb");
1242 TEST_STRING(
1243 InlineString<10>(), str.insert(0, "bbbbbbbbbb", 10), "bbbbbbbbbb");
1244 }
1245 #if PW_NC_TEST(Insert_PointerSizeAtIndex_DoesNotFit)
1246 PW_NC_EXPECT("PW_ASSERT\(size\(\) - index <= max_size\(\) - new_index\)");
__anon055724311b02null1247 [[maybe_unused]] constexpr auto fail = [] {
1248 InlineString<3> str({0, 1});
1249 return str.insert(1, "23", 2);
1250 }();
1251 #endif // PW_NC_TEST
1252
TEST(InlineString,Insert_ArrayAtIndex)1253 TEST(InlineString, Insert_ArrayAtIndex) {
1254 TEST_STRING(InlineString<1>(), fixed_str.insert(0, ""), "");
1255 TEST_STRING(InlineString<2>(), fixed_str.insert(0, "a"), "a");
1256 TEST_STRING(InlineString<6>(), fixed_str.insert(0, "12345"), "12345");
1257
1258 TEST_STRING(InlineString<1>({'a'}), fixed_str.insert(1, ""), "a");
1259 TEST_STRING(InlineString<2>("a"), fixed_str.insert(1, "a"), "aa");
1260 TEST_STRING(InlineString<6>("a"), fixed_str.insert(1, "12345"), "a12345");
1261 }
1262 #if PW_NC_TEST(Insert_ArrayAtIndex_DoesNotFit)
1263 PW_NC_EXPECT("PW_ASSERT\(size\(\) - index <= max_size\(\) - new_index\)");
__anon055724311c02null1264 [[maybe_unused]] constexpr auto fail = [] {
1265 InlineString<4> str({0, 1});
1266 return str.insert(1, "123");
1267 }();
1268 #endif // PW_NC_TEST
1269
TEST(InlineString,Insert_PointerAtIndex)1270 TEST(InlineString, Insert_PointerAtIndex) {
1271 TEST_STRING(InlineString<0>(), str.insert(0, kPointer0), "");
1272 TEST_STRING(InlineString<10>(), str.insert(0, kPointer10), "9876543210");
1273 TEST_STRING(
1274 InlineString<10>("abc"), str.insert(1, kPointer10 + 5), "a43210bc");
1275 TEST_STRING(
1276 InlineString<13>("abc"), str.insert(3, kPointer10), "abc9876543210");
1277 }
1278 #if PW_NC_TEST(Insert_PointerAtIndex_DoesNotFit)
1279 PW_NC_EXPECT("PW_ASSERT\(size\(\) - index <= max_size\(\) - new_index\)");
__anon055724311d02null1280 [[maybe_unused]] constexpr auto fail = [] {
1281 InlineString<3> str({0, 1});
1282 return str.insert(1, kPointer10 + 8);
1283 }();
1284 #endif // PW_NC_TEST
1285
TEST(InlineString,Insert_BasicStringAtIndex)1286 TEST(InlineString, Insert_BasicStringAtIndex) {
1287 TEST_STRING(InlineString<0>(), str.insert(0, kEmptyCapacity0), "");
1288 TEST_STRING(InlineString<10>(), str.insert(0, kEmptyCapacity10), "");
1289 TEST_STRING(InlineString<10>(), str.insert(0, kSize5Capacity10), "12345");
1290 TEST_STRING(
1291 InlineString<10>(), str.insert(0, kSize10Capacity10), "1234567890");
1292
1293 TEST_STRING(InlineString<1>({'a'}), str.insert(0, kEmptyCapacity0), "a");
1294 TEST_STRING(InlineString<11>("a"), str.insert(1, kEmptyCapacity10), "a");
1295 TEST_STRING(
1296 InlineString<12>("aa"), str.insert(1, kSize5Capacity10), "a12345a");
1297 TEST_STRING(
1298 InlineString<12>("aa"), str.insert(2, kSize10Capacity10), "aa1234567890");
1299 }
1300
1301 #if PW_NC_TEST(Insert_BasicStringAtIndex_DoesNotFit)
1302 PW_NC_EXPECT("PW_ASSERT\(new_index <= max_size\(\)\)");
__anon055724311e02null1303 [[maybe_unused]] constexpr auto fail = [] {
1304 InlineString<3> str({0, 1});
1305 return str.insert(1, kSize5Capacity10);
1306 }();
1307 #endif // PW_NC_TEST
1308
TEST(InlineString,Insert_BasicStringSubstrAtIndex)1309 TEST(InlineString, Insert_BasicStringSubstrAtIndex) {
1310 TEST_STRING(
1311 InlineString<1>({'a'}), str.insert(0, kEmptyCapacity0, 0, 0), "a");
1312 TEST_STRING(
1313 InlineString<11>("a"), str.insert(1, kSize10Capacity10, 10, 0), "a");
1314 TEST_STRING(InlineString<12>("aa"),
1315 str.insert(1, kSize10Capacity10, 3, 5),
1316 "a45678a");
1317 TEST_STRING(InlineString<12>("aa"),
1318 str.insert(2, kSize10Capacity10, 0, 10),
1319 "aa1234567890");
1320 }
1321 #if PW_NC_TEST(Insert_BasicStringSubstrAtIndex_DoesNotFit)
1322 PW_NC_EXPECT("PW_ASSERT\(size\(\) - index <= max_size\(\) - new_index\)");
__anon055724311f02null1323 [[maybe_unused]] constexpr auto fail = [] {
1324 InlineString<3> str({0, 1});
1325 return str.insert(1, kSize5Capacity10, 1, 2);
1326 }();
1327 #endif // PW_NC_TEST
1328
TEST(InlineString,Insert_CharactersAtPosition)1329 TEST(InlineString, Insert_CharactersAtPosition) {
1330 TEST_STRING(InlineString<1>(), str.insert(str.begin(), 0, 'b'), "");
1331 TEST_STRING(InlineString<1>("a"), str.insert(str.begin(), 0, 'b'), "a");
1332 TEST_STRING(InlineString<10>("a"), str.insert(str.begin(), 2, 'b'), "bba");
1333 TEST_STRING(
1334 InlineString<10>("a"), str.insert(str.begin() + 1, 2, 'b'), "abb");
1335 TEST_STRING(InlineString<10>(), str.insert(str.end(), 10, 'b'), "bbbbbbbbbb");
1336 }
1337
1338 #if PW_NC_TEST(Insert_CharactersAtPosition_DoesNotFit)
1339 PW_NC_EXPECT("PW_ASSERT\(size\(\) - index <= max_size\(\) - new_index\)");
__anon055724312002null1340 [[maybe_unused]] constexpr auto fail = [] {
1341 InlineString<3> str({0, 1});
1342 return str.insert(str.begin() + 1, 2, '?');
1343 }();
1344 #endif // PW_NC_TEST
1345
TEST(InlineString,Insert_CharacterAtPosition)1346 TEST(InlineString, Insert_CharacterAtPosition) {
1347 TEST_STRING(InlineString<1>(), str.insert(str.begin(), 'b'), "b");
1348 TEST_STRING(InlineString<10>("aa"), str.insert(str.begin(), 'b'), "baa");
1349 TEST_STRING(InlineString<10>("aa"), str.insert(str.begin() + 1, 'b'), "aba");
1350 TEST_STRING(InlineString<10>("aa"), str.insert(str.begin() + 2, 'b'), "aab");
1351 TEST_STRING(InlineString<10>("aa"), str.insert(str.end(), 'b'), "aab");
1352 }
1353 #if PW_NC_TEST(Insert_CharacterAtPosition_DoesNotFit)
1354 PW_NC_EXPECT("PW_ASSERT\(size\(\) - index <= max_size\(\) - new_index\)");
__anon055724312102null1355 [[maybe_unused]] constexpr auto fail = [] {
1356 InlineString<2> str({0, 1});
1357 return str.insert(str.begin() + 1, '?');
1358 }();
1359 #endif // PW_NC_TEST
1360
TEST(InlineString,Insert_IteratorsAtPosition)1361 TEST(InlineString, Insert_IteratorsAtPosition) {
1362 TEST_STRING(InlineString<0>(),
1363 str.insert(str.begin(), kEvenNumbers0, kEvenNumbers0),
1364 "");
1365 TEST_STRING(InlineString<10>(),
1366 str.insert(str.end(), kEvenNumbers0, kEvenNumbers0),
1367 "");
1368 TEST_STRING(InlineString<10>(),
1369 str.insert(str.end(), kEvenNumbers0, kEvenNumbers0),
1370 "");
1371 TEST_STRING(InlineString<10>(),
1372 str.insert(str.begin(), kEvenNumbers0, kEvenNumbers8),
1373 "\0\2\4\6");
1374 TEST_STRING(InlineString<10>(),
1375 str.insert(str.end(), kEvenNumbers0, kEvenNumbers8),
1376 "\0\2\4\6");
1377 TEST_STRING(InlineString<10>("aa"),
1378 str.insert(str.begin(), kEvenNumbers0, kEvenNumbers8),
1379 "\0\2\4\6aa");
1380 TEST_STRING(InlineString<10>("aa"),
1381 str.insert(str.begin() + 1, kEvenNumbers0, kEvenNumbers8),
1382 "a\0\2\4\6a");
1383 TEST_STRING(InlineString<10>("aa"),
1384 str.insert(str.begin() + 2, kEvenNumbers0, kEvenNumbers8),
1385 "aa\0\2\4\6");
1386 TEST_STRING(InlineString<10>("aa"),
1387 str.insert(str.end(), kEvenNumbers0, kEvenNumbers8),
1388 "aa\0\2\4\6");
1389 }
1390 #if PW_NC_TEST(Insert_IteratorsAtPosition_DoesNotFit)
1391 PW_NC_EXPECT("PW_ASSERT\(count < max_size\(\)\)");
__anon055724312202null1392 [[maybe_unused]] constexpr auto fail = [] {
1393 InlineString<3> str({0, 1});
1394 return str.insert(str.begin() + 1, kEvenNumbers0, kEvenNumbers8);
1395 }();
1396 #endif // PW_NC_TEST
1397
TEST(InlineString,Insert_InitializerListAtPosition)1398 TEST(InlineString, Insert_InitializerListAtPosition) {
1399 TEST_STRING(InlineString<0>(), str.insert(str.begin(), {}), "");
1400 TEST_STRING(InlineString<10>(), str.insert(str.end(), {1, 2, 3}), "\1\2\3");
1401 TEST_STRING(
1402 InlineString<10>("abc"), str.insert(str.begin(), {1, 2, 3}), "\1\2\3abc");
1403 TEST_STRING(InlineString<10>("abc"),
1404 str.insert(str.begin() + 1, {1, 2, 3}),
1405 "a\1\2\3bc");
1406 TEST_STRING(InlineString<10>("abc"),
1407 str.insert(str.begin() + 3, {1, 2, 3}),
1408 "abc\1\2\3");
1409 TEST_STRING(
1410 InlineString<5>("abc"), str.insert(str.end(), {'4', '5'}), "abc45");
1411 }
1412 #if PW_NC_TEST(Insert_InitializerListAtPosition_DoesNotFit)
1413 PW_NC_EXPECT("PW_ASSERT\(size\(\) - index <= max_size\(\) - new_index\)");
__anon055724312302null1414 [[maybe_unused]] constexpr auto fail = [] {
1415 InlineString<3> str({0, 1, 2});
1416 return str.insert(str.begin() + 1, {3});
1417 }();
1418 #endif // PW_NC_TEST
1419
TEST(InlineString,Insert_StringViewAtIndex)1420 TEST(InlineString, Insert_StringViewAtIndex) {
1421 TEST_STRING(InlineString<0>(), str.insert(0, ""sv), "");
1422 TEST_STRING(InlineString<10>("a"), str.insert(0, ""sv), "a");
1423 TEST_STRING(InlineString<10>("abc"), str.insert(0, "123"sv), "123abc");
1424 TEST_STRING(InlineString<10>("abc"), str.insert(1, "123"sv), "a123bc");
1425 TEST_STRING(InlineString<5>("abc"), str.insert(3, "45"sv), "abc45");
1426 }
1427 #if PW_NC_TEST(Insert_StringViewAtIndex_DoesNotFit)
1428 PW_NC_EXPECT("PW_ASSERT\(size\(\) - index <= max_size\(\) - new_index\)");
__anon055724312402null1429 [[maybe_unused]] constexpr auto fail = [] {
1430 InlineString<3> str({0, 1, 2});
1431 return str.insert(1, "3"sv);
1432 }();
1433 #endif // PW_NC_TEST
1434
TEST(InlineString,Insert_StringViewSubstrAtIndex)1435 TEST(InlineString, Insert_StringViewSubstrAtIndex) {
1436 TEST_STRING(InlineString<0>(), str.insert(0, ""sv, 0), "");
1437 TEST_STRING(InlineString<0>(), str.insert(0, ""sv, 0, 0), "");
1438 TEST_RUNTIME_STRING(
1439 InlineString<5>("aa"), str.insert(0, "123"sv, 0), "123aa");
1440 TEST_RUNTIME_STRING(
1441 InlineString<10>("aa"), str.insert(1, "123"sv, 1, 0), "aa");
1442 TEST_RUNTIME_STRING(
1443 InlineString<10>("aa"), str.insert(1, "123"sv, 1, 1), "a2a");
1444 TEST_RUNTIME_STRING(
1445 InlineString<10>("aa"), str.insert(1, "123"sv, 1, 99), "a23a");
1446 TEST_RUNTIME_STRING(
1447 InlineString<10>("aa"), str.insert(2, "123"sv, 1, 99), "aa23");
1448 TEST_RUNTIME_STRING(
1449 InlineString<10>("aa"), str.insert(2, "123"sv, 3, 99), "aa");
1450 }
1451 #if PW_NC_TEST(Insert_StringViewSubstrAtIndex_DoesNotFit)
1452 PW_NC_EXPECT("PW_ASSERT\(size\(\) - index <= max_size\(\) - new_index\)");
__anon055724312502null1453 [[maybe_unused]] constexpr auto fail = [] {
1454 InlineString<3> str({0, 1, 2});
1455 return str.insert(1, "34"sv, 1);
1456 }();
1457 #endif // PW_NC_TEST
1458
1459 // erase.
1460
TEST(InlineString,Erase_CharactersAtIndex)1461 TEST(InlineString, Erase_CharactersAtIndex) {
1462 TEST_STRING(InlineString<0>(), str.erase(), "");
1463 TEST_STRING(InlineString<10>("abc"), str.erase(), "");
1464 TEST_STRING(InlineString<10>("abc"), str.erase(0), "");
1465 TEST_STRING(InlineString<10>("abc"), str.erase(1), "a");
1466 TEST_STRING(InlineString<10>("abc"), str.erase(1, 1), "ac");
1467 TEST_STRING(InlineString<10>("abc"), str.erase(1, 10), "a");
1468 TEST_STRING(InlineString<10>("abc"), str.erase(3, 10), "abc");
1469 }
1470 #if PW_NC_TEST(Erase_IndexOutOfRange)
1471 PW_NC_EXPECT("PW_ASSERT\(index <= size\(\)\)");
__anon055724312602null1472 [[maybe_unused]] constexpr auto fail = [] {
1473 InlineString<3> str("abc");
1474 return str.erase(4, 2);
1475 }();
1476 #endif // PW_NC_TEST
1477
TEST(InlineString,Erase_CharacterAtPosition)1478 TEST(InlineString, Erase_CharacterAtPosition) {
1479 TEST_STRING(InlineString<3>(), str.erase(str.begin()), "");
1480 TEST_STRING(InlineString<3>(), str.erase(str.end()), "");
1481 TEST_STRING(InlineString<3>("abc"), str.erase(str.begin()), "bc");
1482 TEST_STRING(InlineString<3>("abc"), str.erase(str.begin() + 1), "ac");
1483 TEST_STRING(InlineString<3>("abc"), str.erase(str.begin() + 2), "ab");
1484 TEST_STRING(InlineString<3>("abc"), str.erase(str.end()), "abc");
1485 }
1486
TEST(InlineString,Erase_CharactersInRange)1487 TEST(InlineString, Erase_CharactersInRange) {
1488 TEST_STRING(
1489 InlineString<3>("abc"), str.erase(str.begin(), str.begin()), "abc");
1490 TEST_STRING(InlineString<3>("abc"), str.erase(str.end(), str.end()), "abc");
1491 TEST_STRING(InlineString<3>("abc"), str.erase(str.begin(), str.end()), "");
1492 TEST_STRING(
1493 InlineString<3>("abc"), str.erase(str.begin(), str.begin() + 1), "bc");
1494 TEST_STRING(
1495 InlineString<3>("abc"), str.erase(str.begin() + 1, str.end()), "a");
1496 }
1497
TEST(InlineString,PushBack)1498 TEST(InlineString, PushBack) {
1499 TEST_STRING(InlineString<1>(), str.push_back('#'), "#");
1500 TEST_STRING(InlineString<5>("abc"), str.push_back('d');
1501 str.push_back('e'), "abcde");
1502
1503 #if PW_NC_TEST(PushBack_DoesNotFit)
1504 PW_NC_EXPECT("PW_ASSERT\(size\(\) < max_size\(\)\)");
1505 [[maybe_unused]] constexpr auto fail = [] {
1506 InlineString<1> str("?", 1);
1507 str.push_back('a');
1508 return str;
1509 }();
1510 #endif // PW_NC_TEST
1511 }
1512
TEST(InlineString,PopBack)1513 TEST(InlineString, PopBack) {
1514 TEST_STRING(InlineString<1>("?", 1), str.pop_back(), "");
1515 TEST_STRING(InlineString<1>(), str.push_back('?'); str.pop_back(), "");
1516
1517 TEST_STRING(InlineString<5>("abc"), str.pop_back(), "ab");
1518 TEST_STRING(InlineString<5>("abcde", 5), str.pop_back(), "abcd");
1519
1520 #if PW_NC_TEST(PopBack_Empty)
1521 PW_NC_EXPECT("PW_ASSERT\(!empty\(\)\)");
1522 [[maybe_unused]] constexpr auto fail = [] {
1523 InlineString<0> str;
1524 str.pop_back();
1525 return str;
1526 }();
1527 #endif // PW_NC_TEST
1528 }
1529
1530 // append
1531
TEST(InlineString,Append_BasicString)1532 TEST(InlineString, Append_BasicString) {
1533 TEST_STRING(InlineString<0>(), str.append(kEmptyCapacity0), "");
1534 TEST_STRING(InlineString<10>(), str.append(kEmptyCapacity10), "");
1535 TEST_STRING(InlineString<10>(), str.append(kSize5Capacity10), "12345");
1536 TEST_STRING(InlineString<10>(), str.append(kSize10Capacity10), "1234567890");
1537
1538 TEST_STRING(InlineString<1>({'a'}), str.append(kEmptyCapacity0), "a");
1539 TEST_STRING(InlineString<11>("a"), str.append(kEmptyCapacity10), "a");
1540 TEST_STRING(InlineString<11>("a"), str.append(kSize5Capacity10), "a12345");
1541 TEST_STRING(
1542 InlineString<11>("a"), str.append(kSize10Capacity10), "a1234567890");
1543
1544 #if PW_NC_TEST(Append_BasicString_DoesNotFit)
1545 PW_NC_EXPECT("PW_ASSERT\(count <= max_size\(\) - index");
1546 [[maybe_unused]] constexpr auto fail = [] {
1547 InlineString<3> str({0, 1});
1548 return str.append(kSize5Capacity10);
1549 }();
1550 #endif // PW_NC_TEST
1551 }
1552
TEST(InlineString,Append_Characters)1553 TEST(InlineString, Append_Characters) {
1554 TEST_STRING(InlineString<1>(), str.append(0, '1'), "");
1555 TEST_STRING(InlineString<1>(), str.append(1, '1'), "1");
1556 TEST_STRING(InlineString<10>(), str.append(2, '1'), "11");
1557 TEST_STRING(InlineString<10>(), str.append(10, '1'), "1111111111");
1558
1559 TEST_STRING(InlineString<4>("Hi"), str.append(0, '!'), "Hi");
1560 TEST_STRING(InlineString<4>("Hi"), str.append(1, '!'), "Hi!");
1561 TEST_STRING(InlineString<6>("Hi"), str.append(2, '!'), "Hi!!");
1562 TEST_STRING(InlineString<6>("Hi"), str.append(4, '!'), "Hi!!!!");
1563
1564 #if PW_NC_TEST(Append_Characters_DoesNotFit)
1565 PW_NC_EXPECT("PW_ASSERT\(count <= max_size\(\) - index\)");
1566 [[maybe_unused]] constexpr auto fail = [] {
1567 InlineString<3> str({0, 1});
1568 return str.append(2, '?');
1569 }();
1570 #endif // PW_NC_TEST
1571 }
1572
TEST(InlineString,Append_PointerSize)1573 TEST(InlineString, Append_PointerSize) {
1574 TEST_STRING(InlineString<0>(), str.append("", 0), "");
1575 TEST_STRING(InlineString<10>(), str.append("", 0), "");
1576 TEST_STRING(InlineString<1>(), str.append("?", 1), "?");
1577 TEST_STRING(InlineString<10>("abc"), str.append("", 0), "abc");
1578 TEST_STRING(InlineString<10>(), str.append("1234567", 1), "1");
1579 TEST_STRING(InlineString<10>("abc"), str.append("1234567", 3), "abc123");
1580
1581 #if PW_NC_TEST(Append_PointerSize_DoesNotFit)
1582 PW_NC_EXPECT("PW_ASSERT\(count <= max_size\(\) - index");
1583 [[maybe_unused]] constexpr auto fail = [] {
1584 InlineString<3> str({0, 1});
1585 return str.append("23", 2);
1586 }();
1587 #endif // PW_NC_TEST
1588 }
1589
TEST(InlineString,Append_Array)1590 TEST(InlineString, Append_Array) {
1591 TEST_STRING(InlineString<1>(), fixed_str.append(""), "");
1592 TEST_STRING(InlineString<2>(), fixed_str.append("a"), "a");
1593 TEST_STRING(InlineString<6>(), fixed_str.append("12345"), "12345");
1594
1595 TEST_STRING(InlineString<1>({'a'}), fixed_str.append(""), "a");
1596 TEST_STRING(InlineString<2>("a"), fixed_str.append("a"), "aa");
1597 TEST_STRING(InlineString<6>("a"), fixed_str.append("12345"), "a12345");
1598
1599 #if PW_NC_TEST(Append_Array_DoesNotFit)
1600 PW_NC_EXPECT(
1601 "InlineString's capacity is too small to hold the assigned string");
1602 [[maybe_unused]] constexpr auto fail = [] {
1603 InlineString<2> str;
1604 return str.append("123");
1605 }();
1606 #endif // PW_NC_TEST
1607 }
1608
TEST(InlineString,Append_Pointer)1609 TEST(InlineString, Append_Pointer) {
1610 TEST_STRING(InlineString<0>(), str.append(kPointer0), "");
1611 TEST_STRING(InlineString<10>(), str.append(kPointer10), "9876543210");
1612 TEST_STRING(InlineString<10>("abc"), str.append(kPointer10 + 5), "abc43210");
1613 TEST_STRING(InlineString<13>("abc"), str.append(kPointer10), "abc9876543210");
1614
1615 #if PW_NC_TEST(Append_Pointer_DoesNotFit)
1616 PW_NC_EXPECT("PW_ASSERT\(count <= max_size\(\) - index");
1617 [[maybe_unused]] constexpr auto fail = [] {
1618 InlineString<3> str({0, 1});
1619 return str.append(kPointer10 + 8);
1620 }();
1621 #endif // PW_NC_TEST
1622 }
1623
TEST(InlineString,Append_Iterator)1624 TEST(InlineString, Append_Iterator) {
1625 TEST_STRING(InlineString<0>(), str.append(kEvenNumbers0, kEvenNumbers0), "");
1626 TEST_STRING(InlineString<10>(), str.append(kEvenNumbers0, kEvenNumbers0), "");
1627 TEST_STRING(InlineString<10>(), str.append(kEvenNumbers0, kEvenNumbers0), "");
1628 TEST_STRING(
1629 InlineString<10>(), str.append(kEvenNumbers0, kEvenNumbers8), "\0\2\4\6");
1630 TEST_STRING(InlineString<10>("a"),
1631 str.append(kEvenNumbers0, kEvenNumbers8),
1632 "a\0\2\4\6");
1633
1634 #if PW_NC_TEST(Append_Iterator_DoesNotFit)
1635 PW_NC_EXPECT("PW_ASSERT\(current_position != string_end\)");
1636 [[maybe_unused]] constexpr auto fail = [] {
1637 InlineString<3> str;
1638 return str.append(kEvenNumbers0, kEvenNumbers8);
1639 }();
1640 #endif // PW_NC_TEST
1641 }
1642
TEST(InlineString,Append_InitializerList)1643 TEST(InlineString, Append_InitializerList) {
1644 TEST_STRING(InlineString<0>(), str.append({}), "");
1645 TEST_STRING(InlineString<10>(), str.append({1, 2, 3}), "\1\2\3");
1646 TEST_STRING(InlineString<10>("abc"), str.append({1, 2, 3}), "abc\1\2\3");
1647 TEST_STRING(InlineString<5>("abc"), str.append({'4', '5'}), "abc45");
1648
1649 #if PW_NC_TEST(Append_InitializerList_DoesNotFit)
1650 PW_NC_EXPECT("PW_ASSERT\(count <= max_size\(\) - index");
1651 [[maybe_unused]] constexpr auto fail = [] {
1652 InlineString<3> str({0, 1, 2});
1653 return str.append({3});
1654 }();
1655 #endif // PW_NC_TEST
1656 }
1657
TEST(InlineString,Append_StringView)1658 TEST(InlineString, Append_StringView) {
1659 TEST_STRING(InlineString<0>(), str.append(""sv), "");
1660 TEST_STRING(InlineString<10>("a"), str.append(""sv), "a");
1661 TEST_STRING(InlineString<10>("abc"), str.append("123"sv), "abc123");
1662 TEST_STRING(InlineString<5>("abc"), str.append("45"sv), "abc45");
1663
1664 #if PW_NC_TEST(Append_StringView_DoesNotFit)
1665 PW_NC_EXPECT("PW_ASSERT\(count <= max_size\(\) - index");
1666 [[maybe_unused]] constexpr auto fail = [] {
1667 InlineString<3> str({0, 1, 2});
1668 return str.append("3"sv);
1669 }();
1670 #endif // PW_NC_TEST
1671 }
1672
TEST(InlineString,Append_StringViewSubstr)1673 TEST(InlineString, Append_StringViewSubstr) {
1674 TEST_STRING(InlineString<0>(), str.append(""sv, 0), "");
1675 TEST_STRING(InlineString<0>(), str.append(""sv, 0, 0), "");
1676 TEST_RUNTIME_STRING(InlineString<4>("a"), str.append("123"sv, 0), "a123");
1677 TEST_RUNTIME_STRING(InlineString<4>("a"), str.append("123"sv, 1, 0), "a");
1678 TEST_RUNTIME_STRING(InlineString<4>("a"), str.append("123"sv, 1, 1), "a2");
1679 TEST_RUNTIME_STRING(InlineString<4>("a"), str.append("123"sv, 1, 99), "a23");
1680 TEST_RUNTIME_STRING(InlineString<4>("a"), str.append("123"sv, 3, 99), "a");
1681
1682 #if PW_NC_TEST(Append_StringViewSubstr_DoesNotFit)
1683 PW_NC_EXPECT("PW_ASSERT\(count <= max_size\(\) - index");
1684 [[maybe_unused]] constexpr auto fail = [] {
1685 InlineString<3> str({0, 1, 2});
1686 return str.append("34"sv, 1);
1687 }();
1688 #endif // PW_NC_TEST
1689 }
1690
1691 // operator+=
1692
TEST(InlineString,AppendOperator_BasicString)1693 TEST(InlineString, AppendOperator_BasicString) {
1694 TEST_STRING(InlineString<1>(), str.append(0, '1'), "");
1695 TEST_STRING(InlineString<1>(), str.append(1, '1'), "1");
1696 TEST_STRING(InlineString<10>(), str.append(2, '1'), "11");
1697 TEST_STRING(InlineString<10>(), str.append(10, '1'), "1111111111");
1698
1699 TEST_STRING(InlineString<4>("Hi"), str.append(0, '!'), "Hi");
1700 TEST_STRING(InlineString<4>("Hi"), str.append(1, '!'), "Hi!");
1701 TEST_STRING(InlineString<6>("Hi"), str.append(2, '!'), "Hi!!");
1702 TEST_STRING(InlineString<6>("Hi"), str.append(4, '!'), "Hi!!!!");
1703
1704 #if PW_NC_TEST(AppendOperator_BasicString_DoesNotFit)
1705 PW_NC_EXPECT("PW_ASSERT\(count <= max_size\(\) - index");
1706 [[maybe_unused]] constexpr auto fail = [] {
1707 InlineString<3> str({0, 1});
1708 return str.append(kSize5Capacity10);
1709 }();
1710 #endif // PW_NC_TEST
1711 }
1712
TEST(InlineString,AppendOperator_Character)1713 TEST(InlineString, AppendOperator_Character) {
1714 TEST_STRING(InlineString<1>(), fixed_str += '1', "1");
1715 TEST_STRING(InlineString<10>(), fixed_str += '\0', "\0");
1716
1717 TEST_STRING(InlineString<3>("Hi"), fixed_str += '!', "Hi!");
1718 TEST_STRING(InlineString<10>("Hi"), fixed_str += '!', "Hi!");
1719
1720 #if PW_NC_TEST(AppendOperator_Characters_DoesNotFit)
1721 PW_NC_EXPECT("PW_ASSERT\(size\(\) < max_size\(\)\);");
1722 [[maybe_unused]] constexpr auto fail = [] {
1723 InlineString<3> str({0, 1, 2});
1724 return str += '?';
1725 }();
1726 #endif // PW_NC_TEST
1727 }
1728
TEST(InlineString,AppendOperator_Array)1729 TEST(InlineString, AppendOperator_Array) {
1730 TEST_STRING(InlineString<1>(), fixed_str += "", "");
1731 TEST_STRING(InlineString<2>(), fixed_str += "a", "a");
1732 TEST_STRING(InlineString<6>(), fixed_str += "12345", "12345");
1733
1734 TEST_STRING(InlineString<1>({'a'}), fixed_str += "", "a");
1735 TEST_STRING(InlineString<2>("a"), fixed_str += "a", "aa");
1736 TEST_STRING(InlineString<6>("a"), fixed_str += "12345", "a12345");
1737
1738 #if PW_NC_TEST(AppendOperator_Array_DoesNotFit)
1739 PW_NC_EXPECT(
1740 "InlineString's capacity is too small to hold the assigned string");
1741 [[maybe_unused]] constexpr auto fail = [] {
1742 InlineString<3> str;
1743 return str += "1234";
1744 }();
1745 #endif // PW_NC_TEST
1746 }
1747
TEST(InlineString,AppendOperator_Pointer)1748 TEST(InlineString, AppendOperator_Pointer) {
1749 TEST_STRING(InlineString<0>(), fixed_str += kPointer0, "");
1750 TEST_STRING(InlineString<10>(), fixed_str += kPointer10, "9876543210");
1751 TEST_STRING(InlineString<10>("abc"), fixed_str += kPointer10 + 5, "abc43210");
1752 TEST_STRING(
1753 InlineString<13>("abc"), fixed_str += kPointer10, "abc9876543210");
1754
1755 #if PW_NC_TEST(AppendOperator_Pointer_DoesNotFit)
1756 PW_NC_EXPECT("PW_ASSERT\(count <= max_size\(\) - index");
1757 [[maybe_unused]] constexpr auto fail = [] {
1758 InlineString<3> str({0, 1});
1759 return str.append(kPointer10 + 8);
1760 }();
1761 #endif // PW_NC_TEST
1762 }
1763
TEST(InlineString,AppendOperator_InitializerList)1764 TEST(InlineString, AppendOperator_InitializerList) {
1765 TEST_STRING(InlineString<0>(), fixed_str += {}, "");
1766 TEST_STRING(InlineString<10>(), (fixed_str += {1, 2, 3}), "\1\2\3");
1767 TEST_STRING(InlineString<10>("abc"), (fixed_str += {1, 2, 3}), "abc\1\2\3");
1768 TEST_STRING(InlineString<5>("abc"), (fixed_str += {'4', '5'}), "abc45");
1769
1770 #if PW_NC_TEST(AppendOperator_InitializerList_DoesNotFit)
1771 PW_NC_EXPECT("PW_ASSERT\(count <= max_size\(\) - index");
1772 [[maybe_unused]] constexpr auto fail = [] {
1773 InlineString<3> str({0, 1, 2});
1774 return str.append({3});
1775 }();
1776 #endif // PW_NC_TEST
1777 }
1778
TEST(InlineString,AppendOperator_StringView)1779 TEST(InlineString, AppendOperator_StringView) {
1780 TEST_STRING(InlineString<0>(), fixed_str += ""sv, "");
1781 TEST_STRING(InlineString<10>("a"), fixed_str += ""sv, "a");
1782 TEST_STRING(InlineString<10>("abc"), fixed_str += "123"sv, "abc123");
1783 TEST_STRING(InlineString<5>("abc"), fixed_str += "45"sv, "abc45");
1784
1785 #if PW_NC_TEST(AppendOperator_StringView_DoesNotFit)
1786 PW_NC_EXPECT("PW_ASSERT\(count <= max_size\(\) - index");
1787 [[maybe_unused]] constexpr auto fail = [] {
1788 InlineString<3> str({0, 1, 2});
1789 return str.append("3"sv);
1790 }();
1791 #endif // PW_NC_TEST
1792 }
1793
TEST(InlineString,Compare)1794 TEST(InlineString, Compare) {
1795 EXPECT_EQ(InlineString<10>("abb").compare(InlineString<5>("abb")), 0);
1796 EXPECT_LT(InlineString<10>("abb").compare(InlineString<5>("bbb")), 0);
1797 EXPECT_LT(InlineString<10>("bb").compare(InlineString<5>("bbb")), 0);
1798
1799 static_assert(InlineString<10>("bbb").compare(InlineString<5>("bbb")) == 0,
1800 "equal");
1801 static_assert(InlineString<10>("abb").compare(InlineString<5>("bbb")) < 0,
1802 "less");
1803 static_assert(InlineString<10>("bbb").compare(InlineString<5>("abb")) > 0,
1804 "greater");
1805
1806 static_assert(InlineString<10>("bb").compare(InlineString<5>("bbb")) < 0,
1807 "less");
1808 static_assert(InlineString<10>("bbb").compare(InlineString<5>("bb")) > 0,
1809 "greater");
1810
1811 static_assert(InlineString<10>("bb").compare(InlineString<5>("abb")) > 0,
1812 "less");
1813 static_assert(InlineString<10>("abb").compare(InlineString<5>("bb")) < 0,
1814 "greater");
1815
1816 static_assert(InlineString<5>("").compare(InlineString<5>("")) == 0, "equal");
1817 static_assert(InlineString<5>("").compare(InlineString<5>("abc")) < 0,
1818 "less");
1819 static_assert(InlineString<5>("abc").compare(InlineString<5>("")) > 0,
1820 "greater");
1821 }
1822
1823 // TODO: b/239996007 - Test other pw::InlineString functions:
1824 //
1825 // - starts_with
1826 // - ends_with
1827 // - contains
1828 // - replace
1829 // - substr
1830 // - copy
1831
TEST(InlineString,Resize)1832 TEST(InlineString, Resize) {
1833 TEST_STRING(InlineString<10>(), str.resize(0), "");
1834 TEST_STRING(InlineString<10>(), str.resize(5), "\0\0\0\0\0");
1835 TEST_STRING(InlineString<10>(), str.resize(10), "\0\0\0\0\0\0\0\0\0\0");
1836 TEST_STRING(InlineString<10>(), str.resize(0, 'a'), "");
1837 TEST_STRING(InlineString<10>(), str.resize(5, 'a'), "aaaaa");
1838 TEST_STRING(InlineString<10>(), str.resize(10, 'a'), "aaaaaaaaaa");
1839
1840 TEST_STRING(InlineString<10>("ABCDE"), str.resize(0), "");
1841 TEST_STRING(InlineString<10>("ABCDE"), str.resize(4), "ABCD");
1842 TEST_STRING(InlineString<10>("ABCDE"), str.resize(5), "ABCDE");
1843 TEST_STRING(InlineString<10>("ABCDE"), str.resize(10), "ABCDE\0\0\0\0\0");
1844 TEST_STRING(InlineString<10>("ABCDE"), str.resize(0, 'a'), "");
1845 TEST_STRING(InlineString<10>("ABCDE"), str.resize(3, 'a'), "ABC");
1846 TEST_STRING(InlineString<10>("ABCDE"), str.resize(5, 'a'), "ABCDE");
1847 TEST_STRING(InlineString<10>("ABCDE"), str.resize(10, 'a'), "ABCDEaaaaa");
1848
1849 #if PW_NC_TEST(Resize_LargerThanCapacity)
1850 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
1851 [[maybe_unused]] constexpr auto fail = [] {
1852 InlineString<4> str("123");
1853 str.resize(5);
1854 return str;
1855 }();
1856 #endif // PW_NC_TEST
1857 }
1858
TEST(InlineString,ResizeAndOverwrite)1859 TEST(InlineString, ResizeAndOverwrite) {
1860 TEST_STRING(InlineString<2>(),
1861 str.resize_and_overwrite([](char* out, size_t) {
1862 out[0] = '\0';
1863 out[1] = '?';
1864 return 2;
1865 }),
1866 "\0?");
1867 TEST_STRING(InlineString<10>("ABCDE"),
1868 str.resize_and_overwrite([](char* out, size_t size) {
1869 out[1] = '?';
1870 for (size_t i = 5; i < size; ++i) {
1871 out[i] = static_cast<char>('0' + i);
1872 }
1873 return size - 1; // chop off the last character
1874 }),
1875 "A?CDE5678");
1876
1877 #if PW_NC_TEST(ResizeAndOverwrite_LargerThanCapacity)
1878 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
1879 [[maybe_unused]] constexpr auto fail = [] {
1880 InlineString<4> str("123");
1881 str.resize_and_overwrite([](char*, size_t) { return 5; });
1882 return str;
1883 }();
1884 #elif PW_NC_TEST(ResizeAndOverwrite_NegativeSize)
1885 PW_NC_EXPECT("PW_ASSERT\(new_size <= max_size\(\)\)");
1886 [[maybe_unused]] constexpr auto fail = [] {
1887 InlineString<4> str("123");
1888 str.resize_and_overwrite([](char*, size_t) { return -1; });
1889 return str;
1890 }();
1891 #endif // PW_NC_TEST
1892 }
1893
1894 // TODO: b/239996007 - Test other pw::InlineString functions:
1895 // - swap
1896
1897 //
1898 // Search
1899 //
1900
1901 // TODO: b/239996007 - Test search functions.
1902
1903 // TODO: b/239996007 - Test operator+.
1904
TEST(InlineString,ComparisonOperators_InlineString)1905 TEST(InlineString, ComparisonOperators_InlineString) {
1906 EXPECT_EQ(InlineString<10>("a"), InlineString<10>("a"));
1907 EXPECT_NE(InlineString<10>("a"), InlineString<10>("b"));
1908 EXPECT_LT(InlineString<10>("a"), InlineString<10>("b"));
1909 EXPECT_LE(InlineString<10>("a"), InlineString<10>("b"));
1910 EXPECT_GT(InlineString<10>("b"), InlineString<10>("a"));
1911 EXPECT_GE(InlineString<10>("b"), InlineString<10>("a"));
1912
1913 static_assert(InlineString<10>() == InlineString<10>(), "equal"); // NOLINT
1914 static_assert(InlineString<10>("abc") == InlineString<5>("abc"), "equal");
1915 static_assert(InlineString<1>({'a'}) == InlineString<10>("a"), "equal");
1916 static_assert(!(InlineString<10>("?") == InlineString<10>()), // NOLINT
1917 "equal");
1918
1919 static_assert(InlineString<10>() != InlineString<10>("a"), // NOLINT
1920 "not equal");
1921 static_assert(InlineString<10>("") != InlineString<5>("abc"), "not equal");
1922 static_assert(InlineString<1>({'\0'}) != InlineString<10>(""), "not equal");
1923 static_assert(!(InlineString<1>({'\0'}) != InlineString<10>("\0"sv)),
1924 "not equal");
1925
1926 static_assert(InlineString<10>() < InlineString<10>("a"), "less");
1927 static_assert(InlineString<10>("ab") < InlineString<5>("abc"), "less");
1928 static_assert(InlineString<1>({'\0'}) < InlineString<10>("\1\0"), "less");
1929 static_assert(!(InlineString<1>({'\2'}) < InlineString<10>("\1\0")), "less");
1930
1931 static_assert(InlineString<10>() <= InlineString<10>("a"), "less equal");
1932 static_assert(InlineString<10>("a") <= InlineString<10>("a"), "less equal");
1933 static_assert(InlineString<10>("ab") <= InlineString<5>("abc"), "less equal");
1934 static_assert(InlineString<10>("abc") <= InlineString<5>("abc"),
1935 "less equal");
1936 static_assert(InlineString<1>({'\0'}) <= InlineString<10>("\1\0"),
1937 "less equal");
1938 static_assert(InlineString<2>({'\1', '\0'}) <= InlineString<10>("\1\0"sv),
1939 "less equal");
1940 static_assert(!(InlineString<2>({'\2', '\0'}) <= InlineString<10>("\1\0"sv)),
1941 "less equal");
1942
1943 static_assert(InlineString<10>("?") > InlineString<10>(""), "greater");
1944 static_assert(InlineString<10>("abc") > InlineString<5>("ab"), "greater");
1945 static_assert(InlineString<2>({'\1', '\0'}) > InlineString<10>("\1"),
1946 "greater");
1947 static_assert(!(InlineString<2>({'\1', '\0'}) > InlineString<10>("\2")),
1948 "greater");
1949
1950 static_assert(InlineString<10>("?") >= InlineString<10>(""), "greater equal");
1951 static_assert(InlineString<10>("?") >= InlineString<10>("?"),
1952 "greater equal");
1953 static_assert(InlineString<10>("abc") >= InlineString<5>("ab"),
1954 "greater equal");
1955 static_assert(InlineString<10>("abc") >= InlineString<5>("abc"),
1956 "greater equal");
1957 static_assert(InlineString<2>({'\1', '\0'}) >= InlineString<10>("\1"),
1958 "greater equal");
1959 static_assert(InlineString<2>({'\1', '\0'}) >= InlineString<10>("\1\0"),
1960 "greater equal");
1961 static_assert(!(InlineString<3>("\0\0") >= InlineString<10>("\1\0")),
1962 "greater equal");
1963 }
1964
TEST(InlineString,ComparisonOperators_NullTerminatedString)1965 TEST(InlineString, ComparisonOperators_NullTerminatedString) {
1966 EXPECT_EQ(InlineString<10>("a"), "a");
1967 EXPECT_EQ("a", InlineString<10>("a"));
1968
1969 EXPECT_NE(InlineString<10>("a"), "b");
1970 EXPECT_NE("a", InlineString<10>("b"));
1971
1972 EXPECT_LT(InlineString<10>("a"), "b");
1973 EXPECT_LT("a", InlineString<10>("b"));
1974
1975 EXPECT_LE(InlineString<10>("a"), "b");
1976 EXPECT_LE("a", InlineString<10>("b"));
1977 EXPECT_LE(InlineString<10>("a"), "a");
1978 EXPECT_LE("a", InlineString<10>("a"));
1979
1980 EXPECT_GT(InlineString<10>("b"), "a");
1981 EXPECT_GT("b", InlineString<10>("a"));
1982
1983 EXPECT_GE(InlineString<10>("b"), "a");
1984 EXPECT_GE("b", InlineString<10>("a"));
1985 EXPECT_GE(InlineString<10>("a"), "a");
1986 EXPECT_GE("a", InlineString<10>("a"));
1987
1988 static_assert(InlineString<10>() == "", "equal"); // NOLINT
1989 static_assert("" == InlineString<10>(), "equal"); // NOLINT
1990 static_assert(InlineString<10>("abc") == "abc", "equal");
1991 static_assert("abc" == InlineString<5>("abc"), "equal");
1992
1993 static_assert("" != InlineString<10>("a"), "not equal"); // NOLINT
1994 static_assert(InlineString<10>("a") != "", "not equal"); // NOLINT
1995 static_assert(InlineString<10>("") != "abc", "not equal"); // NOLINT
1996 static_assert("" != InlineString<5>("abc"), "not equal"); // NOLINT
1997
1998 static_assert(InlineString<10>() < "a", "less");
1999 static_assert("" < InlineString<10>("a"), "less");
2000 static_assert(InlineString<10>("ab") < "abc", "less");
2001 static_assert("ab" < InlineString<5>("abc"), "less");
2002
2003 static_assert(InlineString<10>() <= "a", "less equal");
2004 static_assert("" <= InlineString<10>("a"), "less equal");
2005 static_assert(InlineString<10>("a") <= "a", "less equal");
2006 static_assert("a" <= InlineString<10>("a"), "less equal");
2007
2008 static_assert(InlineString<10>("ab") <= "abc", "less equal");
2009 static_assert("ab" <= InlineString<5>("abc"), "less equal");
2010 static_assert(InlineString<10>("abc") <= "abc", "less equal");
2011 static_assert("abc" <= InlineString<5>("abc"), "less equal");
2012
2013 static_assert(InlineString<10>("?") > "", "greater");
2014 static_assert("?" > InlineString<10>(""), "greater");
2015 static_assert(InlineString<10>("abc") > "ab", "greater");
2016 static_assert("abc" > InlineString<5>("ab"), "greater");
2017
2018 static_assert(InlineString<10>("?") >= "", "greater equal");
2019 static_assert("?" >= InlineString<10>(""), "greater equal");
2020 static_assert(InlineString<10>("abc") >= "ab", "greater equal");
2021 static_assert("abc" >= InlineString<5>("ab"), "greater equal");
2022 static_assert(InlineString<10>("abc") >= "abc", "greater equal");
2023 static_assert("abc" >= InlineString<5>("abc"), "greater equal");
2024 }
2025
2026 // Test instantiating an InlineBasicString with different character types.
2027
2028 #if __cpp_constexpr >= 201603L // constexpr lambdas are required
2029 #define PW_STRING_WRAP_TEST_EXPANSION(expr) \
2030 do { \
2031 expr; \
2032 } while (0)
2033 #else
2034 #define PW_STRING_WRAP_TEST_EXPANSION(expr)
2035 #endif // __cpp_constexpr >= 201603L
2036 #ifdef _LIBCPP_HAS_NO_WIDE_CHARACTERS
2037 #define TEST_FOR_TYPES_BASE(test_macro, ...) \
2038 PW_STRING_WRAP_TEST_EXPANSION(test_macro(char, __VA_ARGS__)); \
2039 PW_STRING_WRAP_TEST_EXPANSION(test_macro(char16_t, __VA_ARGS__)); \
2040 PW_STRING_WRAP_TEST_EXPANSION(test_macro(char32_t, __VA_ARGS__));
2041 #else
2042 #define TEST_FOR_TYPES_BASE(test_macro, ...) \
2043 PW_STRING_WRAP_TEST_EXPANSION(test_macro(char, __VA_ARGS__)); \
2044 PW_STRING_WRAP_TEST_EXPANSION(test_macro(wchar_t, __VA_ARGS__)); \
2045 PW_STRING_WRAP_TEST_EXPANSION(test_macro(char16_t, __VA_ARGS__)); \
2046 PW_STRING_WRAP_TEST_EXPANSION(test_macro(char32_t, __VA_ARGS__));
2047 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
2048
2049 #ifdef __cpp_char8_t
2050 #define TEST_FOR_TYPES(test_macro, ...) \
2051 TEST_FOR_TYPES_BASE(test_macro, __VA_ARGS__) \
2052 PW_STRING_WRAP_TEST_EXPANSION(test_macro(char8_t, __VA_ARGS__));
2053 #else
2054 #define TEST_FOR_TYPES(test_macro, ...) \
2055 TEST_FOR_TYPES_BASE(test_macro, __VA_ARGS__)
2056 #endif // __cpp_char8_t
2057
TEST(BasicStrings,Empty)2058 TEST(BasicStrings, Empty) {
2059 #define BASIC_STRINGS_EMPTY(type, capacity) \
2060 constexpr InlineBasicString<type, capacity> string; \
2061 static_assert(string.empty(), "empty"); \
2062 static_assert(string.size() == 0u, "size 0"); /* NOLINT */ \
2063 static_assert(string.c_str()[0] == static_cast<type>(0), "null"); \
2064 static_assert(std::basic_string_view<type>(string).empty())
2065
2066 TEST_FOR_TYPES(BASIC_STRINGS_EMPTY, 0);
2067 TEST_FOR_TYPES(BASIC_STRINGS_EMPTY, 1);
2068 TEST_FOR_TYPES(BASIC_STRINGS_EMPTY, 50);
2069
2070 #undef BASIC_STRINGS_EMPTY
2071 }
2072
TEST(BasicStrings,InitializerList)2073 TEST(BasicStrings, InitializerList) {
2074 #define BASIC_STRINGS_INITIALIZER_LIST(type, capacity) \
2075 constexpr InlineBasicString<type, capacity> string({0, 1, 2, 3, 4}); \
2076 static_assert(string.size() == 5u, "size 5"); \
2077 static_assert(string[0] == static_cast<type>(0), "0"); \
2078 static_assert(string[1] == static_cast<type>(1), "1"); \
2079 static_assert(string[2] == static_cast<type>(2), "2"); \
2080 static_assert(string[3] == static_cast<type>(3), "3"); \
2081 static_assert(string[4] == static_cast<type>(4), "4"); \
2082 static_assert(string.c_str()[0] == static_cast<type>(0), "null"); \
2083 static_assert(std::basic_string_view<type>(string).size() == 5)
2084
2085 TEST_FOR_TYPES(BASIC_STRINGS_INITIALIZER_LIST, 5);
2086 TEST_FOR_TYPES(BASIC_STRINGS_INITIALIZER_LIST, 10);
2087 TEST_FOR_TYPES(BASIC_STRINGS_INITIALIZER_LIST, 50);
2088
2089 #undef BASIC_STRINGS_INITIALIZER_LIST
2090 }
2091
TEST(BasicStrings,VariousOperations)2092 TEST(BasicStrings, VariousOperations) {
2093 #define BASIC_STRINGS_VARIOUS_OPERATIONS(type, capacity) \
2094 static constexpr type kOne[2] = {1, 0}; \
2095 constexpr auto string = [] { \
2096 InlineBasicString<type, capacity> str({0}); \
2097 str.append(kOne); \
2098 str.append({2, 10, 99}); \
2099 str.resize(3); \
2100 str.push_back(static_cast<int>(3)); \
2101 str.append(InlineBasicString<type, 2>({4})); \
2102 return str; \
2103 }(); \
2104 static_assert(string.size() == 5); \
2105 static_assert(string[0] == static_cast<type>(0), "0"); \
2106 static_assert(string[1] == static_cast<type>(1), "1"); \
2107 static_assert(string[2] == static_cast<type>(2), "2"); \
2108 static_assert(string[3] == static_cast<type>(3), "3"); \
2109 static_assert(string[4] == static_cast<type>(4), "4"); \
2110 static_assert(string.c_str()[0] == static_cast<type>(0), "null")
2111
2112 TEST_FOR_TYPES(BASIC_STRINGS_VARIOUS_OPERATIONS, 5);
2113 TEST_FOR_TYPES(BASIC_STRINGS_VARIOUS_OPERATIONS, 10);
2114 TEST_FOR_TYPES(BASIC_STRINGS_VARIOUS_OPERATIONS, 50);
2115
2116 #undef BASIC_STRINGS_VARIOUS_OPERATIONS
2117 }
2118
TEST(BasicStrings,ByteString)2119 TEST(BasicStrings, ByteString) {
2120 InlineByteString<5> bytes;
2121 bytes.push_back(std::byte{1});
2122 bytes.push_back(std::byte{2});
2123
2124 EXPECT_EQ(bytes.size(), 2u);
2125 EXPECT_EQ(bytes[0], std::byte{1});
2126 EXPECT_EQ(bytes[1], std::byte{2});
2127
2128 InlineByteString<5> higher_bytes({std::byte{99}, std::byte{100}});
2129 EXPECT_LT(bytes, higher_bytes);
2130 }
2131
2132 } // namespace
2133 } // namespace pw
2134