Changeset 247286 in webkit
- Timestamp:
- Jul 9, 2019 4:54:07 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r247269 r247286 1 2019-07-09 Sam Weinig <weinig@apple.com> 2 3 Add StringBuilder member function which allows makeString() style variadic argument construction 4 https://bugs.webkit.org/show_bug.cgi?id=198997 5 6 Reviewed by Darin Adler. 7 8 Adds new StringBuilder::flexibleAppend(...) member function which allows passing one or more 9 string-adaptable (in the sense that there is StringTypeAdapter specialization for the 10 type) parameters. This re-ususes the variadic template infrastructure in StringConcatenate.h 11 that is used for makeString(...) allowing for improvements in one to benefit the other. 12 13 The advantage of StringBuilder::flexibleAppend(...) over calling StringBuilder::append(...) 14 multiple times (beyond the code sharing with makeString(...) is that it can avoid unnecessary 15 additional re-allocations when the StringBuilder needs to expand it's capacity. It does this 16 by computing the complete required length for all the passed arguments and then ensuring enough 17 capacity is available. It also reduces the allocation overhead versus the anti-pattern of 18 builder.append(makeString(...)). 19 20 Ideally, this member function should eventually just be called StringBuilder::append(...), but 21 the current overload set for StringBuilder::append(...) makes this complicated due to overloads 22 that take two arguments such as StringBuilder::append(const UChar*, unsigned). Going forward, we 23 should rename or remove those overloads and move to a standard interface. 24 25 * wtf/posix/FileSystemPOSIX.cpp: 26 (WTF::FileSystemImpl::pathByAppendingComponents): 27 Adopt StringBuilder::flexibleAppend, using to combine the append of '/' and component. 28 29 * wtf/text/StringBuilder.cpp: 30 (WTF::StringBuilder::appendUninitialized): 31 (WTF::StringBuilder::appendUninitializedWithoutOverflowCheck): 32 Extract the part of appendUnitialized that doesn't do the overflow check 33 into it's own member function to allow callers that have already done the 34 overflow check to bypass it. 35 36 (WTF::StringBuilder::appendUninitializedWithoutOverflowCheckForUChar): 37 (WTF::StringBuilder::appendUninitializedWithoutOverflowCheckForLChar): 38 Added to allow template member function flexibleAppendFromAdapters to call 39 appendUninitializedWithoutOverflowCheck without moving it to the header. 40 41 * wtf/text/StringBuilder.h: 42 (WTF::StringBuilder::flexibleAppendFromAdapters): 43 (WTF::StringBuilder::flexibleAppend): 44 Modeled on tryMakeStringFromAdapters in StringConcatenate.h, these 45 eagerly compute the required length, expand the buffer and then use 46 the existing string type adaptor accumulation functions used by makeString. 47 48 * wtf/text/StringConcatenate.h: 49 (WTF::stringTypeAdapterAccumulator): 50 (WTF::tryMakeStringFromAdapters): 51 (WTF::makeStringAccumulator): Deleted. 52 Renames makeStringAccumulator to stringTypeAdapterAccumulator now that it is used 53 by more than just makeString. 54 1 55 2019-07-09 Alex Christensen <achristensen@webkit.org> 2 56 -
trunk/Source/WTF/wtf/posix/FileSystemPOSIX.cpp
r245186 r247286 302 302 StringBuilder builder; 303 303 builder.append(path); 304 for (auto& component : components) { 305 builder.append('/'); 306 builder.append(component); 307 } 304 for (auto& component : components) 305 builder.flexibleAppend('/', component); 308 306 return builder.toString(); 309 307 } -
trunk/Source/WTF/wtf/text/StringBuilder.cpp
r246034 r247286 164 164 } 165 165 166 template 166 template<> 167 167 void StringBuilder::reallocateBuffer<LChar>(unsigned requiredLength) 168 168 { … … 184 184 } 185 185 186 template 186 template<> 187 187 void StringBuilder::reallocateBuffer<UChar>(unsigned requiredLength) 188 188 { … … 232 232 } 233 233 234 // Make ' length' additional capacity be available in m_buffer, update m_string & m_length,234 // Make 'additionalLength' additional capacity be available in m_buffer, update m_string & m_length, 235 235 // return a pointer to the newly allocated storage. 236 236 // Returns nullptr if the size of the new builder would have overflowed 237 template <typename CharType>238 ALWAYS_INLINE Char Type* StringBuilder::appendUninitialized(unsigned length)239 { 240 ASSERT( length);237 template<typename CharacterType> 238 ALWAYS_INLINE CharacterType* StringBuilder::appendUninitialized(unsigned additionalLength) 239 { 240 ASSERT(additionalLength); 241 241 242 242 // Calculate the new size of the builder after appending. 243 CheckedInt32 requiredLength = m_length + length;243 CheckedInt32 requiredLength = m_length + additionalLength; 244 244 if (requiredLength.hasOverflowed()) { 245 245 didOverflow(); 246 246 return nullptr; 247 247 } 248 249 return appendUninitializedWithoutOverflowCheck<CharacterType>(requiredLength); 250 } 251 252 template<typename CharacterType> 253 ALWAYS_INLINE CharacterType* StringBuilder::appendUninitializedWithoutOverflowCheck(CheckedInt32 requiredLength) 254 { 255 ASSERT(!requiredLength.hasOverflowed()); 248 256 249 257 if (m_buffer && (requiredLength.unsafeGet<unsigned>() <= m_buffer->length())) { … … 253 261 m_string = String(); 254 262 m_length = requiredLength; 255 return getBufferCharacters<CharType>() + currentLength; 256 } 257 258 return appendUninitializedSlow<CharType>(requiredLength.unsafeGet()); 259 } 260 261 // Make 'length' additional capacity be available in m_buffer, update m_string & m_length, 263 return getBufferCharacters<CharacterType>() + currentLength; 264 } 265 266 return appendUninitializedSlow<CharacterType>(requiredLength.unsafeGet()); 267 } 268 269 UChar* StringBuilder::appendUninitializedWithoutOverflowCheckForUChar(CheckedInt32 requiredLength) 270 { 271 return appendUninitializedWithoutOverflowCheck<UChar>(requiredLength); 272 } 273 274 LChar* StringBuilder::appendUninitializedWithoutOverflowCheckForLChar(CheckedInt32 requiredLength) 275 { 276 return appendUninitializedWithoutOverflowCheck<LChar>(requiredLength); 277 } 278 279 // Make 'requiredLength' capacity be available in m_buffer, update m_string & m_length, 262 280 // return a pointer to the newly allocated storage. 263 template <typename CharType>264 Char Type* StringBuilder::appendUninitializedSlow(unsigned requiredLength)281 template<typename CharacterType> 282 CharacterType* StringBuilder::appendUninitializedSlow(unsigned requiredLength) 265 283 { 266 284 ASSERT(!hasOverflowed()); … … 271 289 ASSERT(m_buffer->length() >= m_length.unsafeGet<unsigned>()); 272 290 273 reallocateBuffer<Char Type>(expandedCapacity(capacity(), requiredLength));291 reallocateBuffer<CharacterType>(expandedCapacity(capacity(), requiredLength)); 274 292 } else { 275 293 ASSERT(m_string.length() == m_length.unsafeGet<unsigned>()); 276 allocateBuffer(m_length ? m_string.characters<Char Type>() : nullptr, expandedCapacity(capacity(), requiredLength));294 allocateBuffer(m_length ? m_string.characters<CharacterType>() : nullptr, expandedCapacity(capacity(), requiredLength)); 277 295 } 278 296 if (UNLIKELY(hasOverflowed())) 279 297 return nullptr; 280 298 281 Char Type* result = getBufferCharacters<CharType>() + m_length.unsafeGet();299 CharacterType* result = getBufferCharacters<CharacterType>() + m_length.unsafeGet(); 282 300 m_length = requiredLength; 283 301 ASSERT(!hasOverflowed()); -
trunk/Source/WTF/wtf/text/StringBuilder.h
r246596 r247286 232 232 WTF_EXPORT_PRIVATE void appendFixedWidthNumber(double, unsigned decimalPlaces); 233 233 234 // FIXME: Rename to append(...) after renaming any overloads of append that take more than one argument. 235 template<typename... StringTypes> void flexibleAppend(StringTypes...); 236 234 237 String toString() 235 238 { … … 351 354 void allocateBuffer(const UChar* currentCharacters, unsigned requiredLength); 352 355 void allocateBufferUpConvert(const LChar* currentCharacters, unsigned requiredLength); 353 template <typename CharType> 354 void reallocateBuffer(unsigned requiredLength); 355 template <typename CharType> 356 ALWAYS_INLINE CharType* appendUninitialized(unsigned length); 357 template <typename CharType> 358 CharType* appendUninitializedSlow(unsigned length); 359 template <typename CharType> 360 ALWAYS_INLINE CharType * getBufferCharacters(); 356 template<typename CharacterType> void reallocateBuffer(unsigned requiredLength); 357 template<typename CharacterType> ALWAYS_INLINE CharacterType* appendUninitialized(unsigned additionalLength); 358 template<typename CharacterType> ALWAYS_INLINE CharacterType* appendUninitializedWithoutOverflowCheck(CheckedInt32 requiredLength); 359 template<typename CharacterType> CharacterType* appendUninitializedSlow(unsigned requiredLength); 360 361 WTF_EXPORT_PRIVATE UChar* appendUninitializedWithoutOverflowCheckForUChar(CheckedInt32 requiredLength); 362 WTF_EXPORT_PRIVATE LChar* appendUninitializedWithoutOverflowCheckForLChar(CheckedInt32 requiredLength); 363 364 template<typename CharacterType> ALWAYS_INLINE CharacterType* getBufferCharacters(); 361 365 WTF_EXPORT_PRIVATE void reifyString() const; 366 367 template<typename... StringTypeAdapters> void flexibleAppendFromAdapters(StringTypeAdapters...); 362 368 363 369 mutable String m_string; … … 375 381 }; 376 382 377 template 383 template<> 378 384 ALWAYS_INLINE LChar* StringBuilder::getBufferCharacters<LChar>() 379 385 { … … 382 388 } 383 389 384 template 390 template<> 385 391 ALWAYS_INLINE UChar* StringBuilder::getBufferCharacters<UChar>() 386 392 { … … 389 395 } 390 396 391 template <typename CharType> 392 bool equal(const StringBuilder& s, const CharType* buffer, unsigned length) 397 template<typename... StringTypeAdapters> 398 void StringBuilder::flexibleAppendFromAdapters(StringTypeAdapters... adapters) 399 { 400 auto requiredLength = checkedSum<int32_t>(m_length, adapters.length()...); 401 if (requiredLength.hasOverflowed()) { 402 didOverflow(); 403 return; 404 } 405 406 if (m_is8Bit && are8Bit(adapters...)) { 407 LChar* dest = appendUninitializedWithoutOverflowCheckForLChar(requiredLength); 408 if (!dest) { 409 ASSERT(hasOverflowed()); 410 return; 411 } 412 stringTypeAdapterAccumulator(dest, adapters...); 413 } else { 414 UChar* dest = appendUninitializedWithoutOverflowCheckForUChar(requiredLength); 415 if (!dest) { 416 ASSERT(hasOverflowed()); 417 return; 418 } 419 stringTypeAdapterAccumulator(dest, adapters...); 420 } 421 } 422 423 template<typename... StringTypes> 424 void StringBuilder::flexibleAppend(StringTypes... strings) 425 { 426 flexibleAppendFromAdapters(StringTypeAdapter<StringTypes>(strings)...); 427 } 428 429 template<typename CharacterType> 430 bool equal(const StringBuilder& s, const CharacterType* buffer, unsigned length) 393 431 { 394 432 if (s.length() != length) … … 401 439 } 402 440 403 template 441 template<typename StringType> 404 442 bool equal(const StringBuilder& a, const StringType& b) 405 443 { -
trunk/Source/WTF/wtf/text/StringConcatenate.h
r246490 r247286 249 249 250 250 template<typename ResultType, typename Adapter> 251 inline void makeStringAccumulator(ResultType* result, Adapter adapter)251 inline void stringTypeAdapterAccumulator(ResultType* result, Adapter adapter) 252 252 { 253 253 adapter.writeTo(result); … … 255 255 256 256 template<typename ResultType, typename Adapter, typename... Adapters> 257 inline void makeStringAccumulator(ResultType* result, Adapter adapter, Adapters ...adapters)257 inline void stringTypeAdapterAccumulator(ResultType* result, Adapter adapter, Adapters ...adapters) 258 258 { 259 259 adapter.writeTo(result); 260 makeStringAccumulator(result + adapter.length(), adapters...);260 stringTypeAdapterAccumulator(result + adapter.length(), adapters...); 261 261 } 262 262 … … 277 277 return String(); 278 278 279 makeStringAccumulator(buffer, adapter, adapters...);279 stringTypeAdapterAccumulator(buffer, adapter, adapters...); 280 280 281 281 return resultImpl; … … 287 287 return String(); 288 288 289 makeStringAccumulator(buffer, adapter, adapters...);289 stringTypeAdapterAccumulator(buffer, adapter, adapters...); 290 290 291 291 return resultImpl; -
trunk/Tools/ChangeLog
r247270 r247286 1 2019-07-09 Sam Weinig <weinig@apple.com> 2 3 Add StringBuilder member function which allows makeString() style variadic argument construction 4 https://bugs.webkit.org/show_bug.cgi?id=198997 5 6 Reviewed by Darin Adler. 7 8 * TestWebKitAPI/Tests/WTF/StringBuilder.cpp: 9 Add basic test showing that StringBuilder::flexibleAppend can be used to 10 append one or more string adaptable types. 11 1 12 2019-07-09 Sihui Liu <sihui_liu@apple.com> 2 13 -
trunk/Tools/TestWebKitAPI/Tests/WTF/StringBuilder.cpp
r246490 r247286 117 117 } 118 118 119 TEST(StringBuilderTest, FlexibleAppend) 120 { 121 { 122 StringBuilder builder; 123 builder.flexibleAppend(String("0123456789")); 124 expectBuilderContent("0123456789", builder); 125 builder.flexibleAppend("abcd"); 126 expectBuilderContent("0123456789abcd", builder); 127 builder.flexibleAppend('e'); 128 expectBuilderContent("0123456789abcde", builder); 129 builder.flexibleAppend(""); 130 expectBuilderContent("0123456789abcde", builder); 131 } 132 133 { 134 StringBuilder builder; 135 builder.flexibleAppend(String("0123456789"), "abcd", 'e', ""); 136 expectBuilderContent("0123456789abcde", builder); 137 builder.flexibleAppend(String("A"), "B", 'C', ""); 138 expectBuilderContent("0123456789abcdeABC", builder); 139 } 140 } 141 119 142 TEST(StringBuilderTest, ToString) 120 143 {
Note: See TracChangeset
for help on using the changeset viewer.