Changeset 174271 in webkit
- Timestamp:
- Oct 3, 2014, 10:43:32 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/wtf/text/StringView.h (modified) (3 diffs)
-
Tools/TestWebKitAPI/Tests/WTF/StringView.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r174268 r174271 1 2014-10-03 Myles C. Maxfield <mmaxfield@apple.com> 2 3 Support modern for loops over StringViews 4 https://bugs.webkit.org/show_bug.cgi?id=137165 5 6 Reviewed by Darin Adler. 7 8 This patch adds two functions, codePoints() and codeUnits(), on StringView. 9 These two functions return small objects which have begin() and end() functions, 10 which means it can be used by the modern for loop style. This small class also 11 has an inner iterator class which can be incremented, dereferenced, and 12 compared. 13 14 Using these new objects looks like this: 15 for (UChar codeunit : stringView.codeUnits()) { } and 16 for (UChar32 codepoint : stringView.codePoints()) { }. 17 18 * wtf/text/StringView.h: 19 (WTF::StringView::codepoints): 20 (WTF::StringView::codeunits): 21 (WTF::StringViewCodePointIterator::StringViewCodePointIterator): 22 (WTF::StringViewCodePointIterator::Iterator::Iterator): 23 (WTF::StringViewCodePointIterator::Iterator::operator*): 24 (WTF::StringViewCodePointIterator::Iterator::operator!=): 25 (WTF::StringViewCodeUnitIterator::StringViewCodeUnitIterator): 26 (WTF::StringViewCodeUnitIterator::Iterator::Iterator): 27 (WTF::StringViewCodeUnitIterator::Iterator::operator*): 28 (WTF::StringViewCodeUnitIterator::Iterator::operator!=): 29 1 30 2014-09-28 Sam Weinig <sam@webkit.org> 2 31 -
trunk/Source/WTF/wtf/text/StringView.h
r174234 r174271 139 139 bool contains(UChar c) const { return find(c) != notFound; } 140 140 141 class CodePoints; 142 class CodeUnits; 143 144 CodePoints codePoints() const; 145 CodeUnits codeUnits() const; 146 141 147 #if USE(CF) 142 148 // This function converts null strings to empty strings. … … 200 206 initialize(string.characters16(), string.length()); 201 207 } 208 209 class StringView::CodePoints { 210 public: 211 class Iterator { 212 public: 213 Iterator(const StringView&, unsigned index); 214 Iterator& operator++(); 215 UChar32 operator*() const; 216 bool operator==(const Iterator&) const; 217 bool operator!=(const Iterator&) const; 218 219 private: 220 const StringView& m_stringView; 221 mutable unsigned m_index; 222 #if !ASSERT_DISABLED 223 mutable bool m_alreadyIncremented; 224 #endif 225 }; 226 227 explicit CodePoints(const StringView&); 228 Iterator begin() const; 229 Iterator end() const; 230 231 private: 232 StringView m_stringView; 233 }; 234 235 class StringView::CodeUnits { 236 public: 237 class Iterator { 238 public: 239 Iterator(const StringView&, unsigned index); 240 Iterator& operator++(); 241 UChar operator*() const; 242 bool operator==(const Iterator&) const; 243 bool operator!=(const Iterator&) const; 244 245 private: 246 const StringView& m_stringView; 247 unsigned m_index; 248 }; 249 250 explicit CodeUnits(const StringView&); 251 Iterator begin() const; 252 Iterator end() const; 253 254 private: 255 StringView m_stringView; 256 }; 202 257 203 258 inline void StringView::getCharactersWithUpconvert(LChar* destination) const … … 295 350 } 296 351 352 inline auto StringView::codePoints() const -> CodePoints 353 { 354 return CodePoints(*this); 355 } 356 357 inline auto StringView::codeUnits() const -> CodeUnits 358 { 359 return CodeUnits(*this); 360 } 361 362 inline StringView::CodePoints::CodePoints(const StringView& stringView) 363 : m_stringView(stringView) 364 { 365 } 366 367 inline StringView::CodePoints::Iterator::Iterator(const StringView& stringView, unsigned index) 368 : m_stringView(stringView) 369 , m_index(index) 370 #if !ASSERT_DISABLED 371 , m_alreadyIncremented(false) 372 #endif 373 { 374 } 375 376 inline auto StringView::CodePoints::Iterator::operator++() -> Iterator& 377 { 378 #if !ASSERT_DISABLED 379 ASSERT(m_alreadyIncremented); 380 m_alreadyIncremented = false; 381 #endif 382 return *this; 383 } 384 385 inline UChar32 StringView::CodePoints::Iterator::operator*() const 386 { 387 #if !ASSERT_DISABLED 388 ASSERT(!m_alreadyIncremented); 389 m_alreadyIncremented = true; 390 #endif 391 392 if (m_stringView.is8Bit()) 393 return m_stringView.characters8()[m_index++]; 394 395 UChar32 codePoint; 396 U16_NEXT(m_stringView.characters16(), m_index, m_stringView.length(), codePoint); 397 return codePoint; 398 } 399 400 inline bool StringView::CodePoints::Iterator::operator==(const Iterator& other) const 401 { 402 ASSERT(&m_stringView == &other.m_stringView); 403 ASSERT(!m_alreadyIncremented); 404 return m_index == other.m_index; 405 } 406 407 inline bool StringView::CodePoints::Iterator::operator!=(const Iterator& other) const 408 { 409 return !(*this == other); 410 } 411 412 inline auto StringView::CodePoints::begin() const -> Iterator 413 { 414 return Iterator(m_stringView, 0); 415 } 416 417 inline auto StringView::CodePoints::end() const -> Iterator 418 { 419 return Iterator(m_stringView, m_stringView.length()); 420 } 421 422 inline StringView::CodeUnits::CodeUnits(const StringView& stringView) 423 : m_stringView(stringView) 424 { 425 } 426 427 inline StringView::CodeUnits::Iterator::Iterator(const StringView& stringView, unsigned index) 428 : m_stringView(stringView) 429 , m_index(index) 430 { 431 } 432 433 inline auto StringView::CodeUnits::Iterator::operator++() -> Iterator& 434 { 435 ++m_index; 436 return *this; 437 } 438 439 inline UChar StringView::CodeUnits::Iterator::operator*() const 440 { 441 return m_stringView[m_index]; 442 } 443 444 inline bool StringView::CodeUnits::Iterator::operator==(const Iterator& other) const 445 { 446 ASSERT(&m_stringView == &other.m_stringView); 447 return m_index == other.m_index; 448 } 449 450 inline bool StringView::CodeUnits::Iterator::operator!=(const Iterator& other) const 451 { 452 return !(*this == other); 453 } 454 455 inline auto StringView::CodeUnits::begin() const -> Iterator 456 { 457 return Iterator(m_stringView, 0); 458 } 459 460 inline auto StringView::CodeUnits::end() const -> Iterator 461 { 462 return Iterator(m_stringView, m_stringView.length()); 463 } 464 297 465 } // namespace WTF 298 466 -
trunk/Tools/TestWebKitAPI/Tests/WTF/StringView.cpp
r167209 r174271 26 26 #include "config.h" 27 27 28 #include <wtf/text/StringBuilder.h> 28 29 #include <wtf/text/StringView.h> 29 30 … … 78 79 } 79 80 81 bool compareLoopIterations(StringView::CodePoints codePoints, std::vector<UChar32> expected) 82 { 83 std::vector<UChar32> actual; 84 for (auto codePoint : codePoints) 85 actual.push_back(codePoint); 86 return actual == expected; 87 } 88 89 static bool compareLoopIterations(StringView::CodeUnits codeUnits, std::vector<UChar> expected) 90 { 91 std::vector<UChar> actual; 92 for (auto codeUnit : codeUnits) 93 actual.push_back(codeUnit); 94 return actual == expected; 95 } 96 97 static void build(StringBuilder& builder, std::vector<UChar> input) 98 { 99 builder.clear(); 100 for (auto codeUnit : input) 101 builder.append(codeUnit); 102 } 103 104 TEST(WTF, StringViewIterators) 105 { 106 compareLoopIterations(StringView().codePoints(), { }); 107 compareLoopIterations(StringView().codeUnits(), { }); 108 109 compareLoopIterations(StringView::empty().codePoints(), { }); 110 compareLoopIterations(StringView::empty().codeUnits(), { }); 111 112 compareLoopIterations(StringView(String("hello")).codePoints(), {'h', 'e', 'l', 'l', 'o'}); 113 compareLoopIterations(StringView(String("hello")).codeUnits(), {'h', 'e', 'l', 'l', 'o'}); 114 115 StringBuilder b; 116 build(b, {0xD800, 0xDD55}); // Surrogates for unicode code point U+10155 117 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0x10155})); 118 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800, 0xDD55})); 119 120 build(b, {0xD800}); // Leading surrogate only 121 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xD800})); 122 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800})); 123 124 build(b, {0xD800, 0xD801}); // Two leading surrogates 125 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xD800, 0xD801})); 126 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800, 0xD801})); 127 128 build(b, {0xDD55}); // Trailing surrogate only 129 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xDD55})); 130 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xDD55})); 131 132 build(b, {0xD800, 'h'}); // Leading surrogate followed by non-surrogate 133 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xD800, 'h'})); 134 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800, 'h'})); 135 136 build(b, {0x0306}); // "COMBINING BREVE" 137 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0x0306})); 138 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0x0306})); 139 140 build(b, {0x0306, 0xD800, 0xDD55, 'h', 'e', 'l', 'o'}); // Mix of single code unit and multi code unit code points 141 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0x0306, 0x10155, 'h', 'e', 'l', 'o'})); 142 EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0x0306, 0xD800, 0xDD55, 'h', 'e', 'l', 'o'})); 143 } 144 80 145 } // namespace TestWebKitAPI
Note:
See TracChangeset
for help on using the changeset viewer.