From abff7dd7c9e0908ea7dff62db2cfe61b8a3ca58e Mon Sep 17 00:00:00 2001 From: Karl Wiberg Date: Fri, 9 Mar 2018 15:26:24 +0100 Subject: [PATCH] De-inline SimpleStringBuilder methods Bug: webrtc:8982 Change-Id: Iadc83f6de48aad9e66952b6d3ff917672e87e247 Reviewed-on: https://webrtc-review.googlesource.com/61042 Commit-Queue: Tommi Reviewed-by: Tommi Cr-Commit-Position: refs/heads/master@{#22378} --- rtc_base/strings/string_builder.cc | 91 ++++++++++++++++++++++++++++++ rtc_base/strings/string_builder.h | 88 +++++------------------------ 2 files changed, 105 insertions(+), 74 deletions(-) diff --git a/rtc_base/strings/string_builder.cc b/rtc_base/strings/string_builder.cc index 499fb9a25b..528f099560 100644 --- a/rtc_base/strings/string_builder.cc +++ b/rtc_base/strings/string_builder.cc @@ -18,4 +18,95 @@ SimpleStringBuilder::SimpleStringBuilder(rtc::ArrayView buffer) RTC_DCHECK(IsConsistent()); } +SimpleStringBuilder& SimpleStringBuilder::operator<<(const char* str) { + return Append(str); +} + +SimpleStringBuilder& SimpleStringBuilder::operator<<(char ch) { + return Append(&ch, 1); +} + +SimpleStringBuilder& SimpleStringBuilder::operator<<(const std::string& str) { + return Append(str.c_str(), str.length()); +} + +// Numeric conversion routines. +// +// We use std::[v]snprintf instead of std::to_string because: +// * std::to_string relies on the current locale for formatting purposes, +// and therefore concurrent calls to std::to_string from multiple threads +// may result in partial serialization of calls +// * snprintf allows us to print the number directly into our buffer. +// * avoid allocating a std::string (potential heap alloc). +// TODO(tommi): Switch to std::to_chars in C++17. + +SimpleStringBuilder& SimpleStringBuilder::operator<<(int i) { + return AppendFormat("%d", i); +} + +SimpleStringBuilder& SimpleStringBuilder::operator<<(unsigned i) { + return AppendFormat("%u", i); +} + +SimpleStringBuilder& SimpleStringBuilder::operator<<(long i) { // NOLINT + return AppendFormat("%ld", i); +} + +SimpleStringBuilder& SimpleStringBuilder::operator<<(long long i) { // NOLINT + return AppendFormat("%lld", i); +} + +SimpleStringBuilder& SimpleStringBuilder::operator<<( + unsigned long i) { // NOLINT + return AppendFormat("%lu", i); +} + +SimpleStringBuilder& SimpleStringBuilder::operator<<( + unsigned long long i) { // NOLINT + return AppendFormat("%llu", i); +} + +SimpleStringBuilder& SimpleStringBuilder::operator<<(float f) { + return AppendFormat("%f", f); +} + +SimpleStringBuilder& SimpleStringBuilder::operator<<(double f) { + return AppendFormat("%f", f); +} + +SimpleStringBuilder& SimpleStringBuilder::operator<<(long double f) { + return AppendFormat("%Lf", f); +} + +SimpleStringBuilder& SimpleStringBuilder::AppendFormat(const char* fmt, ...) { + va_list args; + va_start(args, fmt); + const int len = + std::vsnprintf(&buffer_[size_], buffer_.size() - size_, fmt, args); + if (len >= 0) { + const size_t chars_added = rtc::SafeMin(len, buffer_.size() - 1 - size_); + size_ += chars_added; + RTC_DCHECK_EQ(len, chars_added) << "Buffer size was insufficient"; + } else { + // This should never happen, but we're paranoid, so re-write the + // terminator in case vsnprintf() overwrote it. + RTC_NOTREACHED(); + buffer_[size_] = '\0'; + } + va_end(args); + RTC_DCHECK(IsConsistent()); + return *this; +} + +SimpleStringBuilder& SimpleStringBuilder::Append(const char* str, + size_t length) { + const size_t chars_added = + rtc::strcpyn(&buffer_[size_], buffer_.size() - size_, str, length); + size_ += chars_added; + RTC_DCHECK_EQ(chars_added, length == SIZE_UNKNOWN ? std::strlen(str) : length) + << "Buffer size was insufficient"; + RTC_DCHECK(IsConsistent()); + return *this; +} + } // namespace rtc diff --git a/rtc_base/strings/string_builder.h b/rtc_base/strings/string_builder.h index b450a995b0..d095385ab4 100644 --- a/rtc_base/strings/string_builder.h +++ b/rtc_base/strings/string_builder.h @@ -33,51 +33,18 @@ class SimpleStringBuilder { SimpleStringBuilder(const SimpleStringBuilder&) = delete; SimpleStringBuilder& operator=(const SimpleStringBuilder&) = delete; - SimpleStringBuilder& operator<<(const char* str) { return Append(str); } - - SimpleStringBuilder& operator<<(char ch) { return Append(&ch, 1); } - - SimpleStringBuilder& operator<<(const std::string& str) { - return Append(str.c_str(), str.length()); - } - - // Numeric conversion routines. - // - // We use std::[v]snprintf instead of std::to_string because: - // * std::to_string relies on the current locale for formatting purposes, - // and therefore concurrent calls to std::to_string from multiple threads - // may result in partial serialization of calls - // * snprintf allows us to print the number directly into our buffer. - // * avoid allocating a std::string (potential heap alloc). - // TODO(tommi): Switch to std::to_chars in C++17. - - SimpleStringBuilder& operator<<(int i) { return AppendFormat("%d", i); } - - SimpleStringBuilder& operator<<(unsigned i) { return AppendFormat("%u", i); } - - SimpleStringBuilder& operator<<(long i) { // NOLINT - return AppendFormat("%ld", i); - } - - SimpleStringBuilder& operator<<(long long i) { // NOLINT - return AppendFormat("%lld", i); - } - - SimpleStringBuilder& operator<<(unsigned long i) { // NOLINT - return AppendFormat("%lu", i); - } - - SimpleStringBuilder& operator<<(unsigned long long i) { // NOLINT - return AppendFormat("%llu", i); - } - - SimpleStringBuilder& operator<<(float f) { return AppendFormat("%f", f); } - - SimpleStringBuilder& operator<<(double f) { return AppendFormat("%f", f); } - - SimpleStringBuilder& operator<<(long double f) { - return AppendFormat("%Lf", f); - } + SimpleStringBuilder& operator<<(const char* str); + SimpleStringBuilder& operator<<(char ch); + SimpleStringBuilder& operator<<(const std::string& str); + SimpleStringBuilder& operator<<(int i); + SimpleStringBuilder& operator<<(unsigned i); + SimpleStringBuilder& operator<<(long i); // NOLINT + SimpleStringBuilder& operator<<(long long i); // NOLINT + SimpleStringBuilder& operator<<(unsigned long i); // NOLINT + SimpleStringBuilder& operator<<(unsigned long long i); // NOLINT + SimpleStringBuilder& operator<<(float f); + SimpleStringBuilder& operator<<(double f); + SimpleStringBuilder& operator<<(long double f); // Returns a pointer to the built string. The name |str()| is borrowed for // compatibility reasons as we replace usage of stringstream throughout the @@ -93,38 +60,11 @@ class SimpleStringBuilder { __attribute__((__format__(__printf__, 2, 3))) #endif SimpleStringBuilder& - AppendFormat(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - const int len = - std::vsnprintf(&buffer_[size_], buffer_.size() - size_, fmt, args); - if (len >= 0) { - const size_t chars_added = rtc::SafeMin(len, buffer_.size() - 1 - size_); - size_ += chars_added; - RTC_DCHECK_EQ(len, chars_added) << "Buffer size was insufficient"; - } else { - // This should never happen, but we're paranoid, so re-write the - // terminator in case vsnprintf() overwrote it. - RTC_NOTREACHED(); - buffer_[size_] = '\0'; - } - va_end(args); - RTC_DCHECK(IsConsistent()); - return *this; - } + AppendFormat(const char* fmt, ...); // An alternate way from operator<<() to append a string. This variant is // slightly more efficient when the length of the string to append, is known. - SimpleStringBuilder& Append(const char* str, size_t length = SIZE_UNKNOWN) { - const size_t chars_added = - rtc::strcpyn(&buffer_[size_], buffer_.size() - size_, str, length); - size_ += chars_added; - RTC_DCHECK_EQ(chars_added, - length == SIZE_UNKNOWN ? std::strlen(str) : length) - << "Buffer size was insufficient"; - RTC_DCHECK(IsConsistent()); - return *this; - } + SimpleStringBuilder& Append(const char* str, size_t length = SIZE_UNKNOWN); private: bool IsConsistent() const {