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