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