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