string_view_test.cc (47148B)
1 // Copyright 2017 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of 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, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "absl/strings/string_view.h" 16 17 #include <stdlib.h> 18 19 #include <cstddef> 20 #include <cstdlib> 21 #include <cstring> 22 #include <iomanip> 23 #include <ios> 24 #include <iterator> 25 #include <limits> 26 #include <map> 27 #include <memory> 28 #include <sstream> 29 #include <string> 30 #include <type_traits> 31 #include <utility> 32 33 #include "gtest/gtest.h" 34 #include "absl/base/config.h" 35 #include "absl/meta/type_traits.h" 36 37 #if defined(ABSL_HAVE_STD_STRING_VIEW) || defined(__ANDROID__) 38 // We don't control the death messaging when using std::string_view. 39 // Android assert messages only go to system log, so death tests cannot inspect 40 // the message for matching. 41 #define ABSL_EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ 42 EXPECT_DEATH_IF_SUPPORTED(statement, ".*") 43 #else 44 #define ABSL_EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ 45 EXPECT_DEATH_IF_SUPPORTED(statement, regex) 46 #endif 47 48 namespace { 49 50 static_assert(!absl::type_traits_internal::IsOwner<absl::string_view>::value && 51 absl::type_traits_internal::IsView<absl::string_view>::value, 52 "string_view is a view, not an owner"); 53 54 static_assert(absl::type_traits_internal::IsLifetimeBoundAssignment< 55 absl::string_view, std::string>::value, 56 "lifetimebound assignment not detected"); 57 58 // A minimal allocator that uses malloc(). 59 template <typename T> 60 struct Mallocator { 61 typedef T value_type; 62 typedef size_t size_type; 63 typedef ptrdiff_t difference_type; 64 typedef T* pointer; 65 typedef const T* const_pointer; 66 typedef T& reference; 67 typedef const T& const_reference; 68 69 size_type max_size() const { 70 return size_t(std::numeric_limits<size_type>::max()) / sizeof(value_type); 71 } 72 template <typename U> 73 struct rebind { 74 typedef Mallocator<U> other; 75 }; 76 Mallocator() = default; 77 template <class U> 78 Mallocator(const Mallocator<U>&) {} // NOLINT(runtime/explicit) 79 80 T* allocate(size_t n) { return static_cast<T*>(std::malloc(n * sizeof(T))); } 81 void deallocate(T* p, size_t) { std::free(p); } 82 }; 83 template <typename T, typename U> 84 bool operator==(const Mallocator<T>&, const Mallocator<U>&) { 85 return true; 86 } 87 template <typename T, typename U> 88 bool operator!=(const Mallocator<T>&, const Mallocator<U>&) { 89 return false; 90 } 91 92 TEST(StringViewTest, Ctor) { 93 { 94 // Null. 95 absl::string_view s10; 96 EXPECT_TRUE(s10.data() == nullptr); 97 EXPECT_EQ(0u, s10.length()); 98 } 99 100 { 101 // const char* without length. 102 const char* hello = "hello"; 103 absl::string_view s20(hello); 104 EXPECT_TRUE(s20.data() == hello); 105 EXPECT_EQ(5u, s20.length()); 106 107 // const char* with length. 108 absl::string_view s21(hello, 4); 109 EXPECT_TRUE(s21.data() == hello); 110 EXPECT_EQ(4u, s21.length()); 111 112 // Not recommended, but valid C++ 113 absl::string_view s22(hello, 6); 114 EXPECT_TRUE(s22.data() == hello); 115 EXPECT_EQ(6u, s22.length()); 116 } 117 118 { 119 // std::string. 120 std::string hola = "hola"; 121 absl::string_view s30(hola); 122 EXPECT_TRUE(s30.data() == hola.data()); 123 EXPECT_EQ(4u, s30.length()); 124 125 // std::string with embedded '\0'. 126 hola.push_back('\0'); 127 hola.append("h2"); 128 hola.push_back('\0'); 129 absl::string_view s31(hola); 130 EXPECT_TRUE(s31.data() == hola.data()); 131 EXPECT_EQ(8u, s31.length()); 132 } 133 134 { 135 using mstring = 136 std::basic_string<char, std::char_traits<char>, Mallocator<char>>; 137 mstring str1("BUNGIE-JUMPING!"); 138 const mstring str2("SLEEPING!"); 139 140 absl::string_view s1(str1); 141 s1.remove_prefix(strlen("BUNGIE-JUM")); 142 143 absl::string_view s2(str2); 144 s2.remove_prefix(strlen("SLEE")); 145 146 EXPECT_EQ(s1, s2); 147 EXPECT_EQ(s1, "PING!"); 148 } 149 150 // TODO(mec): absl::string_view(const absl::string_view&); 151 } 152 153 TEST(StringViewTest, Swap) { 154 absl::string_view a("a"); 155 absl::string_view b("bbb"); 156 EXPECT_TRUE(noexcept(a.swap(b))); 157 a.swap(b); 158 EXPECT_EQ(a, "bbb"); 159 EXPECT_EQ(b, "a"); 160 a.swap(b); 161 EXPECT_EQ(a, "a"); 162 EXPECT_EQ(b, "bbb"); 163 } 164 165 TEST(StringViewTest, STLComparator) { 166 std::string s1("foo"); 167 std::string s2("bar"); 168 std::string s3("baz"); 169 170 absl::string_view p1(s1); 171 absl::string_view p2(s2); 172 absl::string_view p3(s3); 173 174 typedef std::map<absl::string_view, int> TestMap; 175 TestMap map; 176 177 map.insert(std::make_pair(p1, 0)); 178 map.insert(std::make_pair(p2, 1)); 179 map.insert(std::make_pair(p3, 2)); 180 EXPECT_EQ(map.size(), 3u); 181 182 TestMap::const_iterator iter = map.begin(); 183 EXPECT_EQ(iter->second, 1); 184 ++iter; 185 EXPECT_EQ(iter->second, 2); 186 ++iter; 187 EXPECT_EQ(iter->second, 0); 188 ++iter; 189 EXPECT_TRUE(iter == map.end()); 190 191 TestMap::iterator new_iter = map.find("zot"); 192 EXPECT_TRUE(new_iter == map.end()); 193 194 new_iter = map.find("bar"); 195 EXPECT_TRUE(new_iter != map.end()); 196 197 map.erase(new_iter); 198 EXPECT_EQ(map.size(), 2u); 199 200 iter = map.begin(); 201 EXPECT_EQ(iter->second, 2); 202 ++iter; 203 EXPECT_EQ(iter->second, 0); 204 ++iter; 205 EXPECT_TRUE(iter == map.end()); 206 } 207 208 #define COMPARE(result, op, x, y) \ 209 EXPECT_EQ(result, absl::string_view((x)) op absl::string_view((y))); \ 210 EXPECT_EQ(result, absl::string_view((x)).compare(absl::string_view((y))) op 0) 211 212 TEST(StringViewTest, ComparisonOperators) { 213 COMPARE(true, ==, "", ""); 214 COMPARE(true, ==, "", absl::string_view()); 215 COMPARE(true, ==, absl::string_view(), ""); 216 COMPARE(true, ==, "a", "a"); 217 COMPARE(true, ==, "aa", "aa"); 218 COMPARE(false, ==, "a", ""); 219 COMPARE(false, ==, "", "a"); 220 COMPARE(false, ==, "a", "b"); 221 COMPARE(false, ==, "a", "aa"); 222 COMPARE(false, ==, "aa", "a"); 223 224 COMPARE(false, !=, "", ""); 225 COMPARE(false, !=, "a", "a"); 226 COMPARE(false, !=, "aa", "aa"); 227 COMPARE(true, !=, "a", ""); 228 COMPARE(true, !=, "", "a"); 229 COMPARE(true, !=, "a", "b"); 230 COMPARE(true, !=, "a", "aa"); 231 COMPARE(true, !=, "aa", "a"); 232 233 COMPARE(true, <, "a", "b"); 234 COMPARE(true, <, "a", "aa"); 235 COMPARE(true, <, "aa", "b"); 236 COMPARE(true, <, "aa", "bb"); 237 COMPARE(false, <, "a", "a"); 238 COMPARE(false, <, "b", "a"); 239 COMPARE(false, <, "aa", "a"); 240 COMPARE(false, <, "b", "aa"); 241 COMPARE(false, <, "bb", "aa"); 242 243 COMPARE(true, <=, "a", "a"); 244 COMPARE(true, <=, "a", "b"); 245 COMPARE(true, <=, "a", "aa"); 246 COMPARE(true, <=, "aa", "b"); 247 COMPARE(true, <=, "aa", "bb"); 248 COMPARE(false, <=, "b", "a"); 249 COMPARE(false, <=, "aa", "a"); 250 COMPARE(false, <=, "b", "aa"); 251 COMPARE(false, <=, "bb", "aa"); 252 253 COMPARE(false, >=, "a", "b"); 254 COMPARE(false, >=, "a", "aa"); 255 COMPARE(false, >=, "aa", "b"); 256 COMPARE(false, >=, "aa", "bb"); 257 COMPARE(true, >=, "a", "a"); 258 COMPARE(true, >=, "b", "a"); 259 COMPARE(true, >=, "aa", "a"); 260 COMPARE(true, >=, "b", "aa"); 261 COMPARE(true, >=, "bb", "aa"); 262 263 COMPARE(false, >, "a", "a"); 264 COMPARE(false, >, "a", "b"); 265 COMPARE(false, >, "a", "aa"); 266 COMPARE(false, >, "aa", "b"); 267 COMPARE(false, >, "aa", "bb"); 268 COMPARE(true, >, "b", "a"); 269 COMPARE(true, >, "aa", "a"); 270 COMPARE(true, >, "b", "aa"); 271 COMPARE(true, >, "bb", "aa"); 272 } 273 274 TEST(StringViewTest, ComparisonOperatorsByCharacterPosition) { 275 std::string x; 276 for (size_t i = 0; i < 256; i++) { 277 x += 'a'; 278 std::string y = x; 279 COMPARE(true, ==, x, y); 280 for (size_t j = 0; j < i; j++) { 281 std::string z = x; 282 z[j] = 'b'; // Differs in position 'j' 283 COMPARE(false, ==, x, z); 284 COMPARE(true, <, x, z); 285 COMPARE(true, >, z, x); 286 if (j + 1 < i) { 287 z[j + 1] = 'A'; // Differs in position 'j+1' as well 288 COMPARE(false, ==, x, z); 289 COMPARE(true, <, x, z); 290 COMPARE(true, >, z, x); 291 z[j + 1] = 'z'; // Differs in position 'j+1' as well 292 COMPARE(false, ==, x, z); 293 COMPARE(true, <, x, z); 294 COMPARE(true, >, z, x); 295 } 296 } 297 } 298 } 299 #undef COMPARE 300 301 // Sadly, our users often confuse std::string::npos with 302 // absl::string_view::npos; So much so that we test here that they are the same. 303 // They need to both be unsigned, and both be the maximum-valued integer of 304 // their type. 305 306 template <typename T> 307 struct is_type { 308 template <typename U> 309 static bool same(U) { 310 return false; 311 } 312 static bool same(T) { return true; } 313 }; 314 315 TEST(StringViewTest, NposMatchesStdStringView) { 316 EXPECT_EQ(absl::string_view::npos, std::string::npos); 317 318 EXPECT_TRUE(is_type<size_t>::same(absl::string_view::npos)); 319 EXPECT_FALSE(is_type<size_t>::same("")); 320 321 // Make sure absl::string_view::npos continues to be a header constant. 322 char test[absl::string_view::npos & 1] = {0}; 323 EXPECT_EQ(0, test[0]); 324 } 325 326 TEST(StringViewTest, STL1) { 327 const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); 328 const absl::string_view b("abc"); 329 const absl::string_view c("xyz"); 330 const absl::string_view d("foobar"); 331 const absl::string_view e; 332 std::string temp("123"); 333 temp += '\0'; 334 temp += "456"; 335 const absl::string_view f(temp); 336 337 EXPECT_EQ(a[6], 'g'); 338 EXPECT_EQ(b[0], 'a'); 339 EXPECT_EQ(c[2], 'z'); 340 EXPECT_EQ(f[3], '\0'); 341 EXPECT_EQ(f[5], '5'); 342 343 EXPECT_EQ(*d.data(), 'f'); 344 EXPECT_EQ(d.data()[5], 'r'); 345 EXPECT_TRUE(e.data() == nullptr); 346 347 EXPECT_EQ(*a.begin(), 'a'); 348 EXPECT_EQ(*(b.begin() + 2), 'c'); 349 EXPECT_EQ(*(c.end() - 1), 'z'); 350 351 EXPECT_EQ(*a.rbegin(), 'z'); 352 EXPECT_EQ(*(b.rbegin() + 2), 'a'); 353 EXPECT_EQ(*(c.rend() - 1), 'x'); 354 EXPECT_TRUE(a.rbegin() + 26 == a.rend()); 355 356 EXPECT_EQ(a.size(), 26u); 357 EXPECT_EQ(b.size(), 3u); 358 EXPECT_EQ(c.size(), 3u); 359 EXPECT_EQ(d.size(), 6u); 360 EXPECT_EQ(e.size(), 0u); 361 EXPECT_EQ(f.size(), 7u); 362 363 EXPECT_TRUE(!d.empty()); 364 EXPECT_TRUE(d.begin() != d.end()); 365 EXPECT_TRUE(d.begin() + 6 == d.end()); 366 367 EXPECT_TRUE(e.empty()); 368 EXPECT_TRUE(e.begin() == e.end()); 369 370 char buf[4] = { '%', '%', '%', '%' }; 371 EXPECT_EQ(a.copy(buf, 4), 4u); 372 EXPECT_EQ(buf[0], a[0]); 373 EXPECT_EQ(buf[1], a[1]); 374 EXPECT_EQ(buf[2], a[2]); 375 EXPECT_EQ(buf[3], a[3]); 376 EXPECT_EQ(a.copy(buf, 3, 7), 3u); 377 EXPECT_EQ(buf[0], a[7]); 378 EXPECT_EQ(buf[1], a[8]); 379 EXPECT_EQ(buf[2], a[9]); 380 EXPECT_EQ(buf[3], a[3]); 381 EXPECT_EQ(c.copy(buf, 99), 3u); 382 EXPECT_EQ(buf[0], c[0]); 383 EXPECT_EQ(buf[1], c[1]); 384 EXPECT_EQ(buf[2], c[2]); 385 EXPECT_EQ(buf[3], a[3]); 386 #ifdef ABSL_HAVE_EXCEPTIONS 387 EXPECT_THROW(a.copy(buf, 1, 27), std::out_of_range); 388 #else 389 ABSL_EXPECT_DEATH_IF_SUPPORTED(a.copy(buf, 1, 27), "absl::string_view::copy"); 390 #endif 391 } 392 393 // Separated from STL1() because some compilers produce an overly 394 // large stack frame for the combined function. 395 TEST(StringViewTest, STL2) { 396 const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); 397 const absl::string_view b("abc"); 398 const absl::string_view c("xyz"); 399 absl::string_view d("foobar"); 400 const absl::string_view e; 401 const absl::string_view f( 402 "123" 403 "\0" 404 "456", 405 7); 406 407 d = absl::string_view(); 408 EXPECT_EQ(d.size(), 0u); 409 EXPECT_TRUE(d.empty()); 410 EXPECT_TRUE(d.data() == nullptr); 411 EXPECT_TRUE(d.begin() == d.end()); 412 413 EXPECT_EQ(a.find(b), 0u); 414 EXPECT_EQ(a.find(b, 1), absl::string_view::npos); 415 EXPECT_EQ(a.find(c), 23u); 416 EXPECT_EQ(a.find(c, 9), 23u); 417 EXPECT_EQ(a.find(c, absl::string_view::npos), absl::string_view::npos); 418 EXPECT_EQ(b.find(c), absl::string_view::npos); 419 EXPECT_EQ(b.find(c, absl::string_view::npos), absl::string_view::npos); 420 EXPECT_EQ(a.find(d), 0u); 421 EXPECT_EQ(a.find(e), 0u); 422 EXPECT_EQ(a.find(d, 12), 12u); 423 EXPECT_EQ(a.find(e, 17), 17u); 424 absl::string_view g("xx not found bb"); 425 EXPECT_EQ(a.find(g), absl::string_view::npos); 426 // empty string nonsense 427 EXPECT_EQ(d.find(b), absl::string_view::npos); 428 EXPECT_EQ(e.find(b), absl::string_view::npos); 429 EXPECT_EQ(d.find(b, 4), absl::string_view::npos); 430 EXPECT_EQ(e.find(b, 7), absl::string_view::npos); 431 432 size_t empty_search_pos = std::string().find(std::string()); 433 EXPECT_EQ(d.find(d), empty_search_pos); 434 EXPECT_EQ(d.find(e), empty_search_pos); 435 EXPECT_EQ(e.find(d), empty_search_pos); 436 EXPECT_EQ(e.find(e), empty_search_pos); 437 EXPECT_EQ(d.find(d, 4), std::string().find(std::string(), 4)); 438 EXPECT_EQ(d.find(e, 4), std::string().find(std::string(), 4)); 439 EXPECT_EQ(e.find(d, 4), std::string().find(std::string(), 4)); 440 EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4)); 441 442 EXPECT_EQ(a.find('a'), 0u); 443 EXPECT_EQ(a.find('c'), 2u); 444 EXPECT_EQ(a.find('z'), 25u); 445 EXPECT_EQ(a.find('$'), absl::string_view::npos); 446 EXPECT_EQ(a.find('\0'), absl::string_view::npos); 447 EXPECT_EQ(f.find('\0'), 3u); 448 EXPECT_EQ(f.find('3'), 2u); 449 EXPECT_EQ(f.find('5'), 5u); 450 EXPECT_EQ(g.find('o'), 4u); 451 EXPECT_EQ(g.find('o', 4), 4u); 452 EXPECT_EQ(g.find('o', 5), 8u); 453 EXPECT_EQ(a.find('b', 5), absl::string_view::npos); 454 // empty string nonsense 455 EXPECT_EQ(d.find('\0'), absl::string_view::npos); 456 EXPECT_EQ(e.find('\0'), absl::string_view::npos); 457 EXPECT_EQ(d.find('\0', 4), absl::string_view::npos); 458 EXPECT_EQ(e.find('\0', 7), absl::string_view::npos); 459 EXPECT_EQ(d.find('x'), absl::string_view::npos); 460 EXPECT_EQ(e.find('x'), absl::string_view::npos); 461 EXPECT_EQ(d.find('x', 4), absl::string_view::npos); 462 EXPECT_EQ(e.find('x', 7), absl::string_view::npos); 463 464 EXPECT_EQ(a.find(b.data(), 1, 0), 1u); 465 EXPECT_EQ(a.find(c.data(), 9, 0), 9u); 466 EXPECT_EQ(a.find(c.data(), absl::string_view::npos, 0), 467 absl::string_view::npos); 468 EXPECT_EQ(b.find(c.data(), absl::string_view::npos, 0), 469 absl::string_view::npos); 470 // empty string nonsense 471 EXPECT_EQ(d.find(b.data(), 4, 0), absl::string_view::npos); 472 EXPECT_EQ(e.find(b.data(), 7, 0), absl::string_view::npos); 473 474 EXPECT_EQ(a.find(b.data(), 1), absl::string_view::npos); 475 EXPECT_EQ(a.find(c.data(), 9), 23u); 476 EXPECT_EQ(a.find(c.data(), absl::string_view::npos), absl::string_view::npos); 477 EXPECT_EQ(b.find(c.data(), absl::string_view::npos), absl::string_view::npos); 478 // empty string nonsense 479 EXPECT_EQ(d.find(b.data(), 4), absl::string_view::npos); 480 EXPECT_EQ(e.find(b.data(), 7), absl::string_view::npos); 481 482 EXPECT_EQ(a.rfind(b), 0u); 483 EXPECT_EQ(a.rfind(b, 1), 0u); 484 EXPECT_EQ(a.rfind(c), 23u); 485 EXPECT_EQ(a.rfind(c, 22), absl::string_view::npos); 486 EXPECT_EQ(a.rfind(c, 1), absl::string_view::npos); 487 EXPECT_EQ(a.rfind(c, 0), absl::string_view::npos); 488 EXPECT_EQ(b.rfind(c), absl::string_view::npos); 489 EXPECT_EQ(b.rfind(c, 0), absl::string_view::npos); 490 EXPECT_EQ(a.rfind(d), std::string(a).rfind(std::string())); 491 EXPECT_EQ(a.rfind(e), std::string(a).rfind(std::string())); 492 EXPECT_EQ(a.rfind(d, 12), 12u); 493 EXPECT_EQ(a.rfind(e, 17), 17u); 494 EXPECT_EQ(a.rfind(g), absl::string_view::npos); 495 EXPECT_EQ(d.rfind(b), absl::string_view::npos); 496 EXPECT_EQ(e.rfind(b), absl::string_view::npos); 497 EXPECT_EQ(d.rfind(b, 4), absl::string_view::npos); 498 EXPECT_EQ(e.rfind(b, 7), absl::string_view::npos); 499 // empty string nonsense 500 EXPECT_EQ(d.rfind(d, 4), std::string().rfind(std::string())); 501 EXPECT_EQ(e.rfind(d, 7), std::string().rfind(std::string())); 502 EXPECT_EQ(d.rfind(e, 4), std::string().rfind(std::string())); 503 EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string())); 504 EXPECT_EQ(d.rfind(d), std::string().rfind(std::string())); 505 EXPECT_EQ(e.rfind(d), std::string().rfind(std::string())); 506 EXPECT_EQ(d.rfind(e), std::string().rfind(std::string())); 507 EXPECT_EQ(e.rfind(e), std::string().rfind(std::string())); 508 509 EXPECT_EQ(g.rfind('o'), 8u); 510 EXPECT_EQ(g.rfind('q'), absl::string_view::npos); 511 EXPECT_EQ(g.rfind('o', 8), 8u); 512 EXPECT_EQ(g.rfind('o', 7), 4u); 513 EXPECT_EQ(g.rfind('o', 3), absl::string_view::npos); 514 EXPECT_EQ(f.rfind('\0'), 3u); 515 EXPECT_EQ(f.rfind('\0', 12), 3u); 516 EXPECT_EQ(f.rfind('3'), 2u); 517 EXPECT_EQ(f.rfind('5'), 5u); 518 // empty string nonsense 519 EXPECT_EQ(d.rfind('o'), absl::string_view::npos); 520 EXPECT_EQ(e.rfind('o'), absl::string_view::npos); 521 EXPECT_EQ(d.rfind('o', 4), absl::string_view::npos); 522 EXPECT_EQ(e.rfind('o', 7), absl::string_view::npos); 523 524 EXPECT_EQ(a.rfind(b.data(), 1, 0), 1u); 525 EXPECT_EQ(a.rfind(c.data(), 22, 0), 22u); 526 EXPECT_EQ(a.rfind(c.data(), 1, 0), 1u); 527 EXPECT_EQ(a.rfind(c.data(), 0, 0), 0u); 528 EXPECT_EQ(b.rfind(c.data(), 0, 0), 0u); 529 EXPECT_EQ(d.rfind(b.data(), 4, 0), 0u); 530 EXPECT_EQ(e.rfind(b.data(), 7, 0), 0u); 531 } 532 533 // Continued from STL2 534 TEST(StringViewTest, STL2FindFirst) { 535 const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); 536 const absl::string_view b("abc"); 537 const absl::string_view c("xyz"); 538 absl::string_view d("foobar"); 539 const absl::string_view e; 540 const absl::string_view f( 541 "123" 542 "\0" 543 "456", 544 7); 545 absl::string_view g("xx not found bb"); 546 547 d = absl::string_view(); 548 EXPECT_EQ(a.find_first_of(b), 0u); 549 EXPECT_EQ(a.find_first_of(b, 0), 0u); 550 EXPECT_EQ(a.find_first_of(b, 1), 1u); 551 EXPECT_EQ(a.find_first_of(b, 2), 2u); 552 EXPECT_EQ(a.find_first_of(b, 3), absl::string_view::npos); 553 EXPECT_EQ(a.find_first_of(c), 23u); 554 EXPECT_EQ(a.find_first_of(c, 23), 23u); 555 EXPECT_EQ(a.find_first_of(c, 24), 24u); 556 EXPECT_EQ(a.find_first_of(c, 25), 25u); 557 EXPECT_EQ(a.find_first_of(c, 26), absl::string_view::npos); 558 EXPECT_EQ(g.find_first_of(b), 13u); 559 EXPECT_EQ(g.find_first_of(c), 0u); 560 EXPECT_EQ(a.find_first_of(f), absl::string_view::npos); 561 EXPECT_EQ(f.find_first_of(a), absl::string_view::npos); 562 // empty string nonsense 563 EXPECT_EQ(a.find_first_of(d), absl::string_view::npos); 564 EXPECT_EQ(a.find_first_of(e), absl::string_view::npos); 565 EXPECT_EQ(d.find_first_of(b), absl::string_view::npos); 566 EXPECT_EQ(e.find_first_of(b), absl::string_view::npos); 567 EXPECT_EQ(d.find_first_of(d), absl::string_view::npos); 568 EXPECT_EQ(e.find_first_of(d), absl::string_view::npos); 569 EXPECT_EQ(d.find_first_of(e), absl::string_view::npos); 570 EXPECT_EQ(e.find_first_of(e), absl::string_view::npos); 571 572 EXPECT_EQ(a.find_first_not_of(b), 3u); 573 EXPECT_EQ(a.find_first_not_of(c), 0u); 574 EXPECT_EQ(b.find_first_not_of(a), absl::string_view::npos); 575 EXPECT_EQ(c.find_first_not_of(a), absl::string_view::npos); 576 EXPECT_EQ(f.find_first_not_of(a), 0u); 577 EXPECT_EQ(a.find_first_not_of(f), 0u); 578 EXPECT_EQ(a.find_first_not_of(d), 0u); 579 EXPECT_EQ(a.find_first_not_of(e), 0u); 580 // empty string nonsense 581 EXPECT_EQ(a.find_first_not_of(d), 0u); 582 EXPECT_EQ(a.find_first_not_of(e), 0u); 583 EXPECT_EQ(a.find_first_not_of(d, 1), 1u); 584 EXPECT_EQ(a.find_first_not_of(e, 1), 1u); 585 EXPECT_EQ(a.find_first_not_of(d, a.size() - 1), a.size() - 1); 586 EXPECT_EQ(a.find_first_not_of(e, a.size() - 1), a.size() - 1); 587 EXPECT_EQ(a.find_first_not_of(d, a.size()), absl::string_view::npos); 588 EXPECT_EQ(a.find_first_not_of(e, a.size()), absl::string_view::npos); 589 EXPECT_EQ(a.find_first_not_of(d, absl::string_view::npos), 590 absl::string_view::npos); 591 EXPECT_EQ(a.find_first_not_of(e, absl::string_view::npos), 592 absl::string_view::npos); 593 EXPECT_EQ(d.find_first_not_of(a), absl::string_view::npos); 594 EXPECT_EQ(e.find_first_not_of(a), absl::string_view::npos); 595 EXPECT_EQ(d.find_first_not_of(d), absl::string_view::npos); 596 EXPECT_EQ(e.find_first_not_of(d), absl::string_view::npos); 597 EXPECT_EQ(d.find_first_not_of(e), absl::string_view::npos); 598 EXPECT_EQ(e.find_first_not_of(e), absl::string_view::npos); 599 600 absl::string_view h("===="); 601 EXPECT_EQ(h.find_first_not_of('='), absl::string_view::npos); 602 EXPECT_EQ(h.find_first_not_of('=', 3), absl::string_view::npos); 603 EXPECT_EQ(h.find_first_not_of('\0'), 0u); 604 EXPECT_EQ(g.find_first_not_of('x'), 2u); 605 EXPECT_EQ(f.find_first_not_of('\0'), 0u); 606 EXPECT_EQ(f.find_first_not_of('\0', 3), 4u); 607 EXPECT_EQ(f.find_first_not_of('\0', 2), 2u); 608 // empty string nonsense 609 EXPECT_EQ(d.find_first_not_of('x'), absl::string_view::npos); 610 EXPECT_EQ(e.find_first_not_of('x'), absl::string_view::npos); 611 EXPECT_EQ(d.find_first_not_of('\0'), absl::string_view::npos); 612 EXPECT_EQ(e.find_first_not_of('\0'), absl::string_view::npos); 613 } 614 615 // Continued from STL2 616 TEST(StringViewTest, STL2FindLast) { 617 const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); 618 const absl::string_view b("abc"); 619 const absl::string_view c("xyz"); 620 absl::string_view d("foobar"); 621 const absl::string_view e; 622 const absl::string_view f( 623 "123" 624 "\0" 625 "456", 626 7); 627 absl::string_view g("xx not found bb"); 628 absl::string_view h("===="); 629 absl::string_view i("56"); 630 631 d = absl::string_view(); 632 EXPECT_EQ(h.find_last_of(a), absl::string_view::npos); 633 EXPECT_EQ(g.find_last_of(a), g.size() - 1); 634 EXPECT_EQ(a.find_last_of(b), 2u); 635 EXPECT_EQ(a.find_last_of(c), a.size() - 1); 636 EXPECT_EQ(f.find_last_of(i), 6u); 637 EXPECT_EQ(a.find_last_of('a'), 0u); 638 EXPECT_EQ(a.find_last_of('b'), 1u); 639 EXPECT_EQ(a.find_last_of('z'), 25u); 640 EXPECT_EQ(a.find_last_of('a', 5), 0u); 641 EXPECT_EQ(a.find_last_of('b', 5), 1u); 642 EXPECT_EQ(a.find_last_of('b', 0), absl::string_view::npos); 643 EXPECT_EQ(a.find_last_of('z', 25), 25u); 644 EXPECT_EQ(a.find_last_of('z', 24), absl::string_view::npos); 645 EXPECT_EQ(f.find_last_of(i, 5), 5u); 646 EXPECT_EQ(f.find_last_of(i, 6), 6u); 647 EXPECT_EQ(f.find_last_of(a, 4), absl::string_view::npos); 648 // empty string nonsense 649 EXPECT_EQ(f.find_last_of(d), absl::string_view::npos); 650 EXPECT_EQ(f.find_last_of(e), absl::string_view::npos); 651 EXPECT_EQ(f.find_last_of(d, 4), absl::string_view::npos); 652 EXPECT_EQ(f.find_last_of(e, 4), absl::string_view::npos); 653 EXPECT_EQ(d.find_last_of(d), absl::string_view::npos); 654 EXPECT_EQ(d.find_last_of(e), absl::string_view::npos); 655 EXPECT_EQ(e.find_last_of(d), absl::string_view::npos); 656 EXPECT_EQ(e.find_last_of(e), absl::string_view::npos); 657 EXPECT_EQ(d.find_last_of(f), absl::string_view::npos); 658 EXPECT_EQ(e.find_last_of(f), absl::string_view::npos); 659 EXPECT_EQ(d.find_last_of(d, 4), absl::string_view::npos); 660 EXPECT_EQ(d.find_last_of(e, 4), absl::string_view::npos); 661 EXPECT_EQ(e.find_last_of(d, 4), absl::string_view::npos); 662 EXPECT_EQ(e.find_last_of(e, 4), absl::string_view::npos); 663 EXPECT_EQ(d.find_last_of(f, 4), absl::string_view::npos); 664 EXPECT_EQ(e.find_last_of(f, 4), absl::string_view::npos); 665 666 EXPECT_EQ(a.find_last_not_of(b), a.size() - 1); 667 EXPECT_EQ(a.find_last_not_of(c), 22u); 668 EXPECT_EQ(b.find_last_not_of(a), absl::string_view::npos); 669 EXPECT_EQ(b.find_last_not_of(b), absl::string_view::npos); 670 EXPECT_EQ(f.find_last_not_of(i), 4u); 671 EXPECT_EQ(a.find_last_not_of(c, 24), 22u); 672 EXPECT_EQ(a.find_last_not_of(b, 3), 3u); 673 EXPECT_EQ(a.find_last_not_of(b, 2), absl::string_view::npos); 674 // empty string nonsense 675 EXPECT_EQ(f.find_last_not_of(d), f.size() - 1); 676 EXPECT_EQ(f.find_last_not_of(e), f.size() - 1); 677 EXPECT_EQ(f.find_last_not_of(d, 4), 4u); 678 EXPECT_EQ(f.find_last_not_of(e, 4), 4u); 679 EXPECT_EQ(d.find_last_not_of(d), absl::string_view::npos); 680 EXPECT_EQ(d.find_last_not_of(e), absl::string_view::npos); 681 EXPECT_EQ(e.find_last_not_of(d), absl::string_view::npos); 682 EXPECT_EQ(e.find_last_not_of(e), absl::string_view::npos); 683 EXPECT_EQ(d.find_last_not_of(f), absl::string_view::npos); 684 EXPECT_EQ(e.find_last_not_of(f), absl::string_view::npos); 685 EXPECT_EQ(d.find_last_not_of(d, 4), absl::string_view::npos); 686 EXPECT_EQ(d.find_last_not_of(e, 4), absl::string_view::npos); 687 EXPECT_EQ(e.find_last_not_of(d, 4), absl::string_view::npos); 688 EXPECT_EQ(e.find_last_not_of(e, 4), absl::string_view::npos); 689 EXPECT_EQ(d.find_last_not_of(f, 4), absl::string_view::npos); 690 EXPECT_EQ(e.find_last_not_of(f, 4), absl::string_view::npos); 691 692 EXPECT_EQ(h.find_last_not_of('x'), h.size() - 1); 693 EXPECT_EQ(h.find_last_not_of('='), absl::string_view::npos); 694 EXPECT_EQ(b.find_last_not_of('c'), 1u); 695 EXPECT_EQ(h.find_last_not_of('x', 2), 2u); 696 EXPECT_EQ(h.find_last_not_of('=', 2), absl::string_view::npos); 697 EXPECT_EQ(b.find_last_not_of('b', 1), 0u); 698 // empty string nonsense 699 EXPECT_EQ(d.find_last_not_of('x'), absl::string_view::npos); 700 EXPECT_EQ(e.find_last_not_of('x'), absl::string_view::npos); 701 EXPECT_EQ(d.find_last_not_of('\0'), absl::string_view::npos); 702 EXPECT_EQ(e.find_last_not_of('\0'), absl::string_view::npos); 703 } 704 705 // Continued from STL2 706 TEST(StringViewTest, STL2Substr) { 707 const absl::string_view a("abcdefghijklmnopqrstuvwxyz"); 708 const absl::string_view b("abc"); 709 const absl::string_view c("xyz"); 710 absl::string_view d("foobar"); 711 const absl::string_view e; 712 713 d = absl::string_view(); 714 EXPECT_EQ(a.substr(0, 3), b); 715 EXPECT_EQ(a.substr(23), c); 716 EXPECT_EQ(a.substr(23, 3), c); 717 EXPECT_EQ(a.substr(23, 99), c); 718 EXPECT_EQ(a.substr(0), a); 719 EXPECT_EQ(a.substr(), a); 720 EXPECT_EQ(a.substr(3, 2), "de"); 721 // empty string nonsense 722 EXPECT_EQ(d.substr(0, 99), e); 723 // use of npos 724 EXPECT_EQ(a.substr(0, absl::string_view::npos), a); 725 EXPECT_EQ(a.substr(23, absl::string_view::npos), c); 726 // throw exception 727 #ifdef ABSL_HAVE_EXCEPTIONS 728 EXPECT_THROW((void)a.substr(99, 2), std::out_of_range); 729 #else 730 ABSL_EXPECT_DEATH_IF_SUPPORTED((void)a.substr(99, 2), 731 "absl::string_view::substr"); 732 #endif 733 } 734 735 TEST(StringViewTest, TruncSubstr) { 736 const absl::string_view hi("hi"); 737 EXPECT_EQ("", absl::ClippedSubstr(hi, 0, 0)); 738 EXPECT_EQ("h", absl::ClippedSubstr(hi, 0, 1)); 739 EXPECT_EQ("hi", absl::ClippedSubstr(hi, 0)); 740 EXPECT_EQ("i", absl::ClippedSubstr(hi, 1)); 741 EXPECT_EQ("", absl::ClippedSubstr(hi, 2)); 742 EXPECT_EQ("", absl::ClippedSubstr(hi, 3)); // truncation 743 EXPECT_EQ("", absl::ClippedSubstr(hi, 3, 2)); // truncation 744 } 745 746 TEST(StringViewTest, UTF8) { 747 std::string utf8 = "\u00E1"; 748 std::string utf8_twice = utf8 + " " + utf8; 749 size_t utf8_len = strlen(utf8.data()); 750 EXPECT_EQ(utf8_len, absl::string_view(utf8_twice).find_first_of(" ")); 751 EXPECT_EQ(utf8_len, absl::string_view(utf8_twice).find_first_of(" \t")); 752 } 753 754 TEST(StringViewTest, FindConformance) { 755 struct { 756 std::string haystack; 757 std::string needle; 758 } specs[] = { 759 {"", ""}, 760 {"", "a"}, 761 {"a", ""}, 762 {"a", "a"}, 763 {"a", "b"}, 764 {"aa", ""}, 765 {"aa", "a"}, 766 {"aa", "b"}, 767 {"ab", "a"}, 768 {"ab", "b"}, 769 {"abcd", ""}, 770 {"abcd", "a"}, 771 {"abcd", "d"}, 772 {"abcd", "ab"}, 773 {"abcd", "bc"}, 774 {"abcd", "cd"}, 775 {"abcd", "abcd"}, 776 }; 777 for (const auto& s : specs) { 778 SCOPED_TRACE(s.haystack); 779 SCOPED_TRACE(s.needle); 780 std::string st = s.haystack; 781 absl::string_view sp = s.haystack; 782 for (size_t i = 0; i <= sp.size(); ++i) { 783 size_t pos = (i == sp.size()) ? absl::string_view::npos : i; 784 SCOPED_TRACE(pos); 785 EXPECT_EQ(sp.find(s.needle, pos), 786 st.find(s.needle, pos)); 787 EXPECT_EQ(sp.rfind(s.needle, pos), 788 st.rfind(s.needle, pos)); 789 EXPECT_EQ(sp.find_first_of(s.needle, pos), 790 st.find_first_of(s.needle, pos)); 791 EXPECT_EQ(sp.find_first_not_of(s.needle, pos), 792 st.find_first_not_of(s.needle, pos)); 793 EXPECT_EQ(sp.find_last_of(s.needle, pos), 794 st.find_last_of(s.needle, pos)); 795 EXPECT_EQ(sp.find_last_not_of(s.needle, pos), 796 st.find_last_not_of(s.needle, pos)); 797 } 798 } 799 } 800 801 TEST(StringViewTest, Remove) { 802 absl::string_view a("foobar"); 803 std::string s1("123"); 804 s1 += '\0'; 805 s1 += "456"; 806 absl::string_view e; 807 std::string s2; 808 809 // remove_prefix 810 absl::string_view c(a); 811 c.remove_prefix(3); 812 EXPECT_EQ(c, "bar"); 813 c = a; 814 c.remove_prefix(0); 815 EXPECT_EQ(c, a); 816 c.remove_prefix(c.size()); 817 EXPECT_EQ(c, e); 818 819 // remove_suffix 820 c = a; 821 c.remove_suffix(3); 822 EXPECT_EQ(c, "foo"); 823 c = a; 824 c.remove_suffix(0); 825 EXPECT_EQ(c, a); 826 c.remove_suffix(c.size()); 827 EXPECT_EQ(c, e); 828 } 829 830 TEST(StringViewTest, Set) { 831 absl::string_view a("foobar"); 832 absl::string_view empty; 833 absl::string_view b; 834 835 // set 836 b = absl::string_view("foobar", 6); 837 EXPECT_EQ(b, a); 838 b = absl::string_view("foobar", 0); 839 EXPECT_EQ(b, empty); 840 b = absl::string_view("foobar", 7); 841 EXPECT_NE(b, a); 842 843 b = absl::string_view("foobar"); 844 EXPECT_EQ(b, a); 845 } 846 847 TEST(StringViewTest, FrontBack) { 848 static const char arr[] = "abcd"; 849 const absl::string_view csp(arr, 4); 850 EXPECT_EQ(&arr[0], &csp.front()); 851 EXPECT_EQ(&arr[3], &csp.back()); 852 } 853 854 TEST(StringViewTest, FrontBackSingleChar) { 855 static const char c = 'a'; 856 const absl::string_view csp(&c, 1); 857 EXPECT_EQ(&c, &csp.front()); 858 EXPECT_EQ(&c, &csp.back()); 859 } 860 861 TEST(StringViewTest, FrontBackEmpty) { 862 #ifndef ABSL_USES_STD_STRING_VIEW 863 #if !defined(NDEBUG) || ABSL_OPTION_HARDENED 864 // Abseil's string_view implementation has debug assertions that check that 865 // front() and back() are not called on an empty string_view. 866 absl::string_view sv; 867 ABSL_EXPECT_DEATH_IF_SUPPORTED(sv.front(), ""); 868 ABSL_EXPECT_DEATH_IF_SUPPORTED(sv.back(), ""); 869 #endif 870 #endif 871 } 872 873 // `std::string_view::string_view(const char*)` calls 874 // `std::char_traits<char>::length(const char*)` to get the string length. In 875 // libc++, it doesn't allow `nullptr` in the constexpr context, with the error 876 // "read of dereferenced null pointer is not allowed in a constant expression". 877 // At run time, the behavior of `std::char_traits::length()` on `nullptr` is 878 // undefined by the standard and usually results in crash with libc++. 879 // GCC also started rejected this in libstdc++ starting in GCC9. 880 // In MSVC, creating a constexpr string_view from nullptr also triggers an 881 // "unevaluable pointer value" error. This compiler implementation conforms 882 // to the standard, but `absl::string_view` implements a different 883 // behavior for historical reasons. We work around tests that construct 884 // `string_view` from `nullptr` when using libc++. 885 #if !defined(ABSL_USES_STD_STRING_VIEW) || \ 886 (!(defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 9) && \ 887 !defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) 888 #define ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 1 889 #endif 890 891 TEST(StringViewTest, NULLInput) { 892 absl::string_view s; 893 EXPECT_EQ(s.data(), nullptr); 894 EXPECT_EQ(s.size(), 0u); 895 896 #ifdef ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 897 // The `str` parameter is annotated nonnull, but we want to test the defensive 898 // null check. Use a variable instead of passing nullptr directly to avoid a 899 // `-Wnonnull` warning. 900 char* null_str = nullptr; 901 s = absl::string_view(null_str); 902 EXPECT_EQ(s.data(), nullptr); 903 EXPECT_EQ(s.size(), 0u); 904 905 // .ToString() on a absl::string_view with nullptr should produce the empty 906 // string. 907 EXPECT_EQ("", std::string(s)); 908 #endif // ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 909 } 910 911 TEST(StringViewTest, Comparisons2) { 912 // The `compare` member has 6 overloads (v: string_view, s: const char*): 913 // (1) compare(v) 914 // (2) compare(pos1, count1, v) 915 // (3) compare(pos1, count1, v, pos2, count2) 916 // (4) compare(s) 917 // (5) compare(pos1, count1, s) 918 // (6) compare(pos1, count1, s, count2) 919 920 absl::string_view abc("abcdefghijklmnopqrstuvwxyz"); 921 922 // check comparison operations on strings longer than 4 bytes. 923 EXPECT_EQ(abc, absl::string_view("abcdefghijklmnopqrstuvwxyz")); 924 EXPECT_EQ(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxyz")), 0); 925 926 EXPECT_LT(abc, absl::string_view("abcdefghijklmnopqrstuvwxzz")); 927 EXPECT_LT(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxzz")), 0); 928 929 EXPECT_GT(abc, absl::string_view("abcdefghijklmnopqrstuvwxyy")); 930 EXPECT_GT(abc.compare(absl::string_view("abcdefghijklmnopqrstuvwxyy")), 0); 931 932 // The "substr" variants of `compare`. 933 absl::string_view digits("0123456789"); 934 auto npos = absl::string_view::npos; 935 936 // Taking string_view 937 EXPECT_EQ(digits.compare(3, npos, absl::string_view("3456789")), 0); // 2 938 EXPECT_EQ(digits.compare(3, 4, absl::string_view("3456")), 0); // 2 939 EXPECT_EQ(digits.compare(10, 0, absl::string_view()), 0); // 2 940 EXPECT_EQ(digits.compare(3, 4, absl::string_view("0123456789"), 3, 4), 941 0); // 3 942 EXPECT_LT(digits.compare(3, 4, absl::string_view("0123456789"), 3, 5), 943 0); // 3 944 EXPECT_LT(digits.compare(0, npos, absl::string_view("0123456789"), 3, 5), 945 0); // 3 946 // Taking const char* 947 EXPECT_EQ(digits.compare(3, 4, "3456"), 0); // 5 948 EXPECT_EQ(digits.compare(3, npos, "3456789"), 0); // 5 949 EXPECT_EQ(digits.compare(10, 0, ""), 0); // 5 950 EXPECT_EQ(digits.compare(3, 4, "0123456789", 3, 4), 0); // 6 951 EXPECT_LT(digits.compare(3, 4, "0123456789", 3, 5), 0); // 6 952 EXPECT_LT(digits.compare(0, npos, "0123456789", 3, 5), 0); // 6 953 } 954 955 TEST(StringViewTest, At) { 956 absl::string_view abc = "abc"; 957 EXPECT_EQ(abc.at(0), 'a'); 958 EXPECT_EQ(abc.at(1), 'b'); 959 EXPECT_EQ(abc.at(2), 'c'); 960 #ifdef ABSL_HAVE_EXCEPTIONS 961 EXPECT_THROW((void)abc.at(3), std::out_of_range); 962 #else 963 ABSL_EXPECT_DEATH_IF_SUPPORTED((void)abc.at(3), "absl::string_view::at"); 964 #endif 965 } 966 967 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L 968 TEST(StringViewTest, StartsWith) { 969 const absl::string_view a("foobar"); 970 const absl::string_view b("123\0abc", 7); 971 const absl::string_view e; 972 EXPECT_TRUE(a.starts_with(a)); 973 EXPECT_TRUE(a.starts_with("foo")); 974 EXPECT_TRUE(a.starts_with('f')); 975 EXPECT_TRUE(a.starts_with(e)); 976 EXPECT_TRUE(b.starts_with(b)); 977 EXPECT_TRUE(b.starts_with('1')); 978 EXPECT_TRUE(b.starts_with(e)); 979 EXPECT_TRUE(e.starts_with("")); 980 EXPECT_FALSE(a.starts_with(b)); 981 EXPECT_FALSE(b.starts_with(a)); 982 EXPECT_FALSE(e.starts_with(a)); 983 EXPECT_FALSE(a.starts_with('r')); 984 EXPECT_FALSE(a.starts_with('\0')); 985 EXPECT_FALSE(e.starts_with('r')); 986 EXPECT_FALSE(e.starts_with('\0')); 987 988 // Test that constexpr compiles. 989 constexpr absl::string_view kFooBar("foobar"); 990 constexpr absl::string_view kFoo("foo"); 991 constexpr absl::string_view kBar("bar"); 992 constexpr bool k1 = kFooBar.starts_with(kFoo); 993 EXPECT_TRUE(k1); 994 constexpr bool k2 = kFooBar.starts_with(kBar); 995 EXPECT_FALSE(k2); 996 constexpr bool k3 = kFooBar.starts_with('f'); 997 EXPECT_TRUE(k3); 998 constexpr bool k4 = kFooBar.starts_with("fo"); 999 EXPECT_TRUE(k4); 1000 } 1001 1002 TEST(StringViewTest, EndsWith) { 1003 const absl::string_view a("foobar"); 1004 const absl::string_view b("123\0abc", 7); 1005 const absl::string_view e; 1006 EXPECT_TRUE(a.ends_with(a)); 1007 EXPECT_TRUE(a.ends_with('r')); 1008 EXPECT_TRUE(a.ends_with("bar")); 1009 EXPECT_TRUE(a.ends_with(e)); 1010 EXPECT_TRUE(b.ends_with(b)); 1011 EXPECT_TRUE(b.ends_with('c')); 1012 EXPECT_TRUE(b.ends_with(e)); 1013 EXPECT_TRUE(e.ends_with("")); 1014 EXPECT_FALSE(a.ends_with(b)); 1015 EXPECT_FALSE(b.ends_with(a)); 1016 EXPECT_FALSE(e.ends_with(a)); 1017 EXPECT_FALSE(a.ends_with('f')); 1018 EXPECT_FALSE(a.ends_with('\0')); 1019 EXPECT_FALSE(e.ends_with('r')); 1020 EXPECT_FALSE(e.ends_with('\0')); 1021 1022 // Test that constexpr compiles. 1023 constexpr absl::string_view kFooBar("foobar"); 1024 constexpr absl::string_view kFoo("foo"); 1025 constexpr absl::string_view kBar("bar"); 1026 constexpr bool k1 = kFooBar.ends_with(kFoo); 1027 EXPECT_FALSE(k1); 1028 constexpr bool k2 = kFooBar.ends_with(kBar); 1029 EXPECT_TRUE(k2); 1030 constexpr bool k3 = kFooBar.ends_with('r'); 1031 EXPECT_TRUE(k3); 1032 constexpr bool k4 = kFooBar.ends_with("ar"); 1033 EXPECT_TRUE(k4); 1034 } 1035 #endif // ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L 1036 1037 struct MyCharAlloc : std::allocator<char> {}; 1038 1039 TEST(StringViewTest, ExplicitConversionOperator) { 1040 absl::string_view sp = "hi"; 1041 EXPECT_EQ(sp, std::string(sp)); 1042 } 1043 1044 TEST(StringViewTest, NullSafeStringView) { 1045 { 1046 absl::string_view s = absl::NullSafeStringView(nullptr); 1047 EXPECT_EQ(nullptr, s.data()); 1048 EXPECT_EQ(0u, s.size()); 1049 EXPECT_EQ(absl::string_view(), s); 1050 } 1051 { 1052 static const char kHi[] = "hi"; 1053 absl::string_view s = absl::NullSafeStringView(kHi); 1054 EXPECT_EQ(kHi, s.data()); 1055 EXPECT_EQ(strlen(kHi), s.size()); 1056 EXPECT_EQ(absl::string_view("hi"), s); 1057 } 1058 } 1059 1060 TEST(StringViewTest, ConstexprNullSafeStringView) { 1061 { 1062 constexpr absl::string_view s = absl::NullSafeStringView(nullptr); 1063 EXPECT_EQ(nullptr, s.data()); 1064 EXPECT_EQ(0u, s.size()); 1065 EXPECT_EQ(absl::string_view(), s); 1066 } 1067 { 1068 static constexpr char kHi[] = "hi"; 1069 absl::string_view s = absl::NullSafeStringView(kHi); 1070 EXPECT_EQ(kHi, s.data()); 1071 EXPECT_EQ(strlen(kHi), s.size()); 1072 EXPECT_EQ(absl::string_view("hi"), s); 1073 } 1074 { 1075 constexpr absl::string_view s = absl::NullSafeStringView("hello"); 1076 EXPECT_EQ(s.size(), 5u); 1077 EXPECT_EQ("hello", s); 1078 } 1079 } 1080 1081 TEST(StringViewTest, ConstexprCompiles) { 1082 constexpr absl::string_view sp; 1083 // With `-Wnonnull` turned on, there is no way to test the defensive null 1084 // check in the `string_view(const char*)` constructor in a constexpr context, 1085 // as the argument needs to be constexpr. The compiler will therefore always 1086 // know at compile time that the argument is nullptr and complain because the 1087 // parameter is annotated nonnull. We hence turn the warning off for this 1088 // test. 1089 #if defined(__clang__) 1090 #pragma clang diagnostic push 1091 #pragma clang diagnostic ignored "-Wnonnull" 1092 #endif 1093 #ifdef ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 1094 constexpr absl::string_view cstr(nullptr); 1095 #endif 1096 #if defined(__clang__) 1097 #pragma clang diagnostic pop 1098 #endif 1099 constexpr absl::string_view cstr_len("cstr", 4); 1100 1101 #if defined(ABSL_USES_STD_STRING_VIEW) 1102 // In libstdc++ (as of 7.2), `std::string_view::string_view(const char*)` 1103 // calls `std::char_traits<char>::length(const char*)` to get the string 1104 // length, but it is not marked constexpr yet. See GCC bug: 1105 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78156 1106 // Also, there is a LWG issue that adds constexpr to length() which was just 1107 // resolved 2017-06-02. See 1108 // http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2232 1109 // TODO(zhangxy): Update the condition when libstdc++ adopts the constexpr 1110 // length(). 1111 #if !defined(__GLIBCXX__) 1112 #define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1 1113 #endif // !__GLIBCXX__ 1114 1115 #else // ABSL_USES_STD_STRING_VIEW 1116 1117 // This duplicates the check for __builtin_strlen in the header. 1118 #if ABSL_HAVE_BUILTIN(__builtin_strlen) || \ 1119 (defined(__GNUC__) && !defined(__clang__)) 1120 #define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1 1121 #elif defined(__GNUC__) // GCC or clang 1122 #error GCC/clang should have constexpr string_view. 1123 #endif 1124 1125 // MSVC 2017+ should be able to construct a constexpr string_view from a cstr. 1126 #if defined(_MSC_VER) 1127 #define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1 1128 #endif 1129 1130 #endif // ABSL_USES_STD_STRING_VIEW 1131 1132 #ifdef ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1133 constexpr absl::string_view cstr_strlen("foo"); 1134 EXPECT_EQ(cstr_strlen.length(), 3u); 1135 constexpr absl::string_view cstr_strlen2 = "bar"; 1136 EXPECT_EQ(cstr_strlen2, "bar"); 1137 1138 #if ABSL_HAVE_BUILTIN(__builtin_memcmp) || \ 1139 (defined(__GNUC__) && !defined(__clang__)) 1140 #define ABSL_HAVE_CONSTEXPR_STRING_VIEW_COMPARISON 1 1141 #endif 1142 #ifdef ABSL_HAVE_CONSTEXPR_STRING_VIEW_COMPARISON 1143 constexpr absl::string_view foo = "foo"; 1144 constexpr absl::string_view bar = "bar"; 1145 constexpr bool foo_eq_bar = foo == bar; 1146 constexpr bool foo_ne_bar = foo != bar; 1147 constexpr bool foo_lt_bar = foo < bar; 1148 constexpr bool foo_le_bar = foo <= bar; 1149 constexpr bool foo_gt_bar = foo > bar; 1150 constexpr bool foo_ge_bar = foo >= bar; 1151 constexpr int foo_compare_bar = foo.compare(bar); 1152 EXPECT_FALSE(foo_eq_bar); 1153 EXPECT_TRUE(foo_ne_bar); 1154 EXPECT_FALSE(foo_lt_bar); 1155 EXPECT_FALSE(foo_le_bar); 1156 EXPECT_TRUE(foo_gt_bar); 1157 EXPECT_TRUE(foo_ge_bar); 1158 EXPECT_GT(foo_compare_bar, 0); 1159 #endif 1160 #endif 1161 1162 constexpr absl::string_view::iterator const_begin_empty = sp.begin(); 1163 constexpr absl::string_view::iterator const_end_empty = sp.end(); 1164 EXPECT_EQ(const_begin_empty, const_end_empty); 1165 1166 #ifdef ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 1167 constexpr absl::string_view::iterator const_begin_nullptr = cstr.begin(); 1168 constexpr absl::string_view::iterator const_end_nullptr = cstr.end(); 1169 EXPECT_EQ(const_begin_nullptr, const_end_nullptr); 1170 #endif // ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 1171 1172 constexpr absl::string_view::iterator const_begin = cstr_len.begin(); 1173 constexpr absl::string_view::iterator const_end = cstr_len.end(); 1174 constexpr absl::string_view::size_type const_size = cstr_len.size(); 1175 constexpr absl::string_view::size_type const_length = cstr_len.length(); 1176 static_assert(const_begin + const_size == const_end, 1177 "pointer arithmetic check"); 1178 static_assert(const_begin + const_length == const_end, 1179 "pointer arithmetic check"); 1180 #ifndef _MSC_VER 1181 // MSVC has bugs doing constexpr pointer arithmetic. 1182 // https://developercommunity.visualstudio.com/content/problem/482192/bad-pointer-arithmetic-in-constepxr-2019-rc1-svc1.html 1183 EXPECT_EQ(const_begin + const_size, const_end); 1184 EXPECT_EQ(const_begin + const_length, const_end); 1185 #endif 1186 1187 constexpr bool isempty = sp.empty(); 1188 EXPECT_TRUE(isempty); 1189 1190 constexpr const char c = cstr_len[2]; 1191 EXPECT_EQ(c, 't'); 1192 1193 constexpr const char cfront = cstr_len.front(); 1194 constexpr const char cback = cstr_len.back(); 1195 EXPECT_EQ(cfront, 'c'); 1196 EXPECT_EQ(cback, 'r'); 1197 1198 constexpr const char* np = sp.data(); 1199 constexpr const char* cstr_ptr = cstr_len.data(); 1200 EXPECT_EQ(np, nullptr); 1201 EXPECT_NE(cstr_ptr, nullptr); 1202 1203 constexpr size_t sp_npos = sp.npos; 1204 EXPECT_EQ(sp_npos, static_cast<size_t>(-1)); 1205 } 1206 1207 constexpr char ConstexprMethodsHelper() { 1208 #if defined(__cplusplus) && __cplusplus >= 201402L 1209 absl::string_view str("123", 3); 1210 str.remove_prefix(1); 1211 str.remove_suffix(1); 1212 absl::string_view bar; 1213 str.swap(bar); 1214 return bar.front(); 1215 #else 1216 return '2'; 1217 #endif 1218 } 1219 1220 TEST(StringViewTest, ConstexprMethods) { 1221 // remove_prefix, remove_suffix, swap 1222 static_assert(ConstexprMethodsHelper() == '2', ""); 1223 1224 // substr 1225 constexpr absl::string_view foobar("foobar", 6); 1226 constexpr absl::string_view foo = foobar.substr(0, 3); 1227 constexpr absl::string_view bar = foobar.substr(3); 1228 EXPECT_EQ(foo, "foo"); 1229 EXPECT_EQ(bar, "bar"); 1230 } 1231 1232 TEST(StringViewTest, Noexcept) { 1233 EXPECT_TRUE((std::is_nothrow_constructible<absl::string_view, 1234 const std::string&>::value)); 1235 EXPECT_TRUE((std::is_nothrow_constructible<absl::string_view, 1236 const std::string&>::value)); 1237 EXPECT_TRUE(std::is_nothrow_constructible<absl::string_view>::value); 1238 constexpr absl::string_view sp; 1239 EXPECT_TRUE(noexcept(sp.begin())); 1240 EXPECT_TRUE(noexcept(sp.end())); 1241 EXPECT_TRUE(noexcept(sp.cbegin())); 1242 EXPECT_TRUE(noexcept(sp.cend())); 1243 EXPECT_TRUE(noexcept(sp.rbegin())); 1244 EXPECT_TRUE(noexcept(sp.rend())); 1245 EXPECT_TRUE(noexcept(sp.crbegin())); 1246 EXPECT_TRUE(noexcept(sp.crend())); 1247 EXPECT_TRUE(noexcept(sp.size())); 1248 EXPECT_TRUE(noexcept(sp.length())); 1249 EXPECT_TRUE(noexcept(sp.empty())); 1250 EXPECT_TRUE(noexcept(sp.data())); 1251 EXPECT_TRUE(noexcept(sp.compare(sp))); 1252 EXPECT_TRUE(noexcept(sp.find(sp))); 1253 EXPECT_TRUE(noexcept(sp.find('f'))); 1254 EXPECT_TRUE(noexcept(sp.rfind(sp))); 1255 EXPECT_TRUE(noexcept(sp.rfind('f'))); 1256 EXPECT_TRUE(noexcept(sp.find_first_of(sp))); 1257 EXPECT_TRUE(noexcept(sp.find_first_of('f'))); 1258 EXPECT_TRUE(noexcept(sp.find_last_of(sp))); 1259 EXPECT_TRUE(noexcept(sp.find_last_of('f'))); 1260 EXPECT_TRUE(noexcept(sp.find_first_not_of(sp))); 1261 EXPECT_TRUE(noexcept(sp.find_first_not_of('f'))); 1262 EXPECT_TRUE(noexcept(sp.find_last_not_of(sp))); 1263 EXPECT_TRUE(noexcept(sp.find_last_not_of('f'))); 1264 } 1265 1266 TEST(StringViewTest, BoundsCheck) { 1267 #ifndef ABSL_USES_STD_STRING_VIEW 1268 #if !defined(NDEBUG) || ABSL_OPTION_HARDENED 1269 // Abseil's string_view implementation has bounds-checking in debug mode. 1270 absl::string_view h = "hello"; 1271 ABSL_EXPECT_DEATH_IF_SUPPORTED(h[5], ""); 1272 ABSL_EXPECT_DEATH_IF_SUPPORTED(h[static_cast<size_t>(-1)], ""); 1273 #endif 1274 #endif 1275 } 1276 1277 TEST(ComparisonOpsTest, StringCompareNotAmbiguous) { 1278 EXPECT_EQ("hello", std::string("hello")); 1279 EXPECT_LT("hello", std::string("world")); 1280 } 1281 1282 TEST(ComparisonOpsTest, HeterogeneousStringViewEquals) { 1283 EXPECT_EQ(absl::string_view("hello"), std::string("hello")); 1284 EXPECT_EQ("hello", absl::string_view("hello")); 1285 } 1286 1287 TEST(FindOneCharTest, EdgeCases) { 1288 absl::string_view a("xxyyyxx"); 1289 1290 // Set a = "xyyyx". 1291 a.remove_prefix(1); 1292 a.remove_suffix(1); 1293 1294 EXPECT_EQ(0u, a.find('x')); 1295 EXPECT_EQ(0u, a.find('x', 0)); 1296 EXPECT_EQ(4u, a.find('x', 1)); 1297 EXPECT_EQ(4u, a.find('x', 4)); 1298 EXPECT_EQ(absl::string_view::npos, a.find('x', 5)); 1299 1300 EXPECT_EQ(4u, a.rfind('x')); 1301 EXPECT_EQ(4u, a.rfind('x', 5)); 1302 EXPECT_EQ(4u, a.rfind('x', 4)); 1303 EXPECT_EQ(0u, a.rfind('x', 3)); 1304 EXPECT_EQ(0u, a.rfind('x', 0)); 1305 1306 // Set a = "yyy". 1307 a.remove_prefix(1); 1308 a.remove_suffix(1); 1309 1310 EXPECT_EQ(absl::string_view::npos, a.find('x')); 1311 EXPECT_EQ(absl::string_view::npos, a.rfind('x')); 1312 } 1313 1314 #ifndef ABSL_HAVE_THREAD_SANITIZER // Allocates too much memory for tsan. 1315 TEST(HugeStringView, TwoPointTwoGB) { 1316 if (sizeof(size_t) <= 4) 1317 return; 1318 // Try a huge string piece. 1319 const size_t size = size_t{2200} * 1000 * 1000; 1320 std::string s(size, 'a'); 1321 absl::string_view sp(s); 1322 EXPECT_EQ(size, sp.length()); 1323 sp.remove_prefix(1); 1324 EXPECT_EQ(size - 1, sp.length()); 1325 sp.remove_suffix(2); 1326 EXPECT_EQ(size - 1 - 2, sp.length()); 1327 } 1328 #endif // ABSL_HAVE_THREAD_SANITIZER 1329 1330 #if !defined(NDEBUG) && !defined(ABSL_USES_STD_STRING_VIEW) 1331 TEST(NonNegativeLenTest, NonNegativeLen) { 1332 ABSL_EXPECT_DEATH_IF_SUPPORTED( 1333 absl::string_view("xyz", static_cast<size_t>(-1)), "len <= kMaxSize"); 1334 } 1335 1336 TEST(LenExceedsMaxSizeTest, LenExceedsMaxSize) { 1337 auto max_size = absl::string_view().max_size(); 1338 1339 // This should construct ok (although the view itself is obviously invalid). 1340 absl::string_view ok_view("", max_size); 1341 1342 // Adding one to the max should trigger an assertion. 1343 ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("", max_size + 1), 1344 "len <= kMaxSize"); 1345 } 1346 #endif // !defined(NDEBUG) && !defined(ABSL_USES_STD_STRING_VIEW) 1347 1348 class StringViewStreamTest : public ::testing::Test { 1349 public: 1350 // Set negative 'width' for right justification. 1351 template <typename T> 1352 std::string Pad(const T& s, int width, char fill = 0) { 1353 std::ostringstream oss; 1354 if (fill != 0) { 1355 oss << std::setfill(fill); 1356 } 1357 if (width < 0) { 1358 width = -width; 1359 oss << std::right; 1360 } 1361 oss << std::setw(width) << s; 1362 return oss.str(); 1363 } 1364 }; 1365 1366 TEST_F(StringViewStreamTest, Padding) { 1367 std::string s("hello"); 1368 absl::string_view sp(s); 1369 for (int w = -64; w < 64; ++w) { 1370 SCOPED_TRACE(w); 1371 EXPECT_EQ(Pad(s, w), Pad(sp, w)); 1372 } 1373 for (int w = -64; w < 64; ++w) { 1374 SCOPED_TRACE(w); 1375 EXPECT_EQ(Pad(s, w, '#'), Pad(sp, w, '#')); 1376 } 1377 } 1378 1379 TEST_F(StringViewStreamTest, ResetsWidth) { 1380 // Width should reset after one formatted write. 1381 // If we weren't resetting width after formatting the string_view, 1382 // we'd have width=5 carrying over to the printing of the "]", 1383 // creating "[###hi####]". 1384 std::string s = "hi"; 1385 absl::string_view sp = s; 1386 { 1387 std::ostringstream oss; 1388 oss << "[" << std::setfill('#') << std::setw(5) << s << "]"; 1389 ASSERT_EQ("[###hi]", oss.str()); 1390 } 1391 { 1392 std::ostringstream oss; 1393 oss << "[" << std::setfill('#') << std::setw(5) << sp << "]"; 1394 EXPECT_EQ("[###hi]", oss.str()); 1395 } 1396 } 1397 1398 } // namespace