Remove SimpleStringBuilder and move StringBuilder impl to cc

- Removed deprecated SimpleStringBuilder class.
- Moved StringBuilder implementation to CC file.
- Updated documentation to recommend StringBuilder.

Some benefits of moving parts of the implementation to the cc file:

- Help with enforcing correct build dependencies
  (including in downstream code)
- Moves into the direction of making absl::StrCat an implementation
  detail of StringBuilder (helps with iwyu). This CL doesn't remove
  the include though for other reasons, just a step.
- Small binary size benefits.

Bug: none
Change-Id: I4b9efdba45c3c4923233188ff38476e0ca2257c1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/466380
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#47544}
diff --git a/g3doc/abseil-in-webrtc.md b/g3doc/abseil-in-webrtc.md
index e824447..b21bc3c 100644
--- a/g3doc/abseil-in-webrtc.md
+++ b/g3doc/abseil-in-webrtc.md
@@ -83,7 +83,7 @@
 
 ### `absl::StrCat`, `absl::StrAppend`, `absl::StrJoin`, `absl::StrSplit`
 
-*Use `webrtc::SimpleStringBuilder` to build strings.*
+*Use `webrtc::StringBuilder` to build strings.*
 
 These are optimized for speed, not binary size. Even `StrCat` calls with a
 modest number of arguments can easily add several hundred bytes to the binary.
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 3850f30..abbc798 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -625,6 +625,7 @@
   deps = [
     ":checks",
     ":safe_minmax",
+    "system:rtc_export",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
diff --git a/rtc_base/strings/string_builder.cc b/rtc_base/strings/string_builder.cc
index 8d12167..6f31b83 100644
--- a/rtc_base/strings/string_builder.cc
+++ b/rtc_base/strings/string_builder.cc
@@ -13,98 +13,60 @@
 #include <cstdarg>
 #include <cstdio>
 #include <cstring>
-#include <span>
 
+#include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/numerics/safe_minmax.h"
 
 namespace webrtc {
 
-SimpleStringBuilder::SimpleStringBuilder(std::span<char> buffer)
-    : buffer_(buffer) {
-  buffer_[0] = '\0';
-  RTC_CHECK(IsConsistent());
-}
-
-SimpleStringBuilder& SimpleStringBuilder::operator<<(char ch) {
-  return operator<<(absl::string_view(&ch, 1));
-}
-
-SimpleStringBuilder& SimpleStringBuilder::operator<<(absl::string_view str) {
-  RTC_CHECK_LT(size_ + str.length(), buffer_.size())
-      << "Buffer size was insufficient";
-  const size_t chars_added = SafeMin(str.length(), buffer_.size() - size_ - 1);
-  memcpy(&buffer_[size_], str.data(), chars_added);
-  size_ += chars_added;
-  buffer_[size_] = '\0';
-  RTC_CHECK(IsConsistent());
+StringBuilder& StringBuilder::operator<<(const absl::string_view str) {
+  str_.append(str.data(), str.length());
   return *this;
 }
 
-// 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).
-SimpleStringBuilder& SimpleStringBuilder::operator<<(int i) {
-  return AppendFormat("%d", i);
+StringBuilder& StringBuilder::operator<<(char c) {
+  str_ += c;
+  return *this;
 }
 
-SimpleStringBuilder& SimpleStringBuilder::operator<<(unsigned i) {
-  return AppendFormat("%u", i);
+StringBuilder& StringBuilder::operator<<(int i) {
+  str_ += absl::StrCat(i);
+  return *this;
 }
 
-SimpleStringBuilder& SimpleStringBuilder::operator<<(long i) {  // NOLINT
-  return AppendFormat("%ld", i);
+StringBuilder& StringBuilder::operator<<(unsigned i) {
+  str_ += absl::StrCat(i);
+  return *this;
 }
 
-SimpleStringBuilder& SimpleStringBuilder::operator<<(long long i) {  // NOLINT
-  return AppendFormat("%lld", i);
+StringBuilder& StringBuilder::operator<<(long i) {
+  str_ += absl::StrCat(i);
+  return *this;
 }
 
-SimpleStringBuilder& SimpleStringBuilder::operator<<(
-    unsigned long i) {  // NOLINT
-  return AppendFormat("%lu", i);
+StringBuilder& StringBuilder::operator<<(long long i) {
+  str_ += absl::StrCat(i);
+  return *this;
 }
 
-SimpleStringBuilder& SimpleStringBuilder::operator<<(
-    unsigned long long i) {  // NOLINT
-  return AppendFormat("%llu", i);
+StringBuilder& StringBuilder::operator<<(unsigned long i) {
+  str_ += absl::StrCat(i);
+  return *this;
 }
 
-SimpleStringBuilder& SimpleStringBuilder::operator<<(float f) {
-  return AppendFormat("%g", f);
+StringBuilder& StringBuilder::operator<<(unsigned long long i) {
+  str_ += absl::StrCat(i);
+  return *this;
 }
 
-SimpleStringBuilder& SimpleStringBuilder::operator<<(double f) {
-  return AppendFormat("%g", f);
+StringBuilder& StringBuilder::operator<<(float f) {
+  str_ += absl::StrCat(f);
+  return *this;
 }
 
-SimpleStringBuilder& SimpleStringBuilder::operator<<(long double f) {
-  return AppendFormat("%Lg", 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 = SafeMin(len, buffer_.size() - 1 - size_);
-    size_ += chars_added;
-    RTC_CHECK_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_DCHECK_NOTREACHED();
-    buffer_[size_] = '\0';
-  }
-  va_end(args);
-  RTC_CHECK(IsConsistent());
+StringBuilder& StringBuilder::operator<<(double f) {
+  str_ += absl::StrCat(f);
   return *this;
 }
 
diff --git a/rtc_base/strings/string_builder.h b/rtc_base/strings/string_builder.h
index a3e0f0a..5254626d 100644
--- a/rtc_base/strings/string_builder.h
+++ b/rtc_base/strings/string_builder.h
@@ -12,129 +12,36 @@
 #define RTC_BASE_STRINGS_STRING_BUILDER_H_
 
 #include <cstdio>
-#include <span>
 #include <string>
 #include <utility>
 
 #include "absl/strings/has_absl_stringify.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
 
-// This is a minimalistic string builder class meant to cover the most cases of
-// when you might otherwise be tempted to use a stringstream (discouraged for
-// anything except logging). It uses a fixed-size buffer provided by the caller
-// and concatenates strings and numbers into it, allowing the results to be
-// read via `str()`.
-class [[deprecated("Use webrtc::StringBuilder instead")]] SimpleStringBuilder {
- public:
-  explicit SimpleStringBuilder(std::span<char> buffer);
-  SimpleStringBuilder(const SimpleStringBuilder&) = delete;
-  SimpleStringBuilder& operator=(const SimpleStringBuilder&) = delete;
-
-  SimpleStringBuilder& operator<<(char ch);
-  SimpleStringBuilder& operator<<(absl::string_view 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);
-
-  template <typename T>
-    requires absl::HasAbslStringify<T>::value
-  SimpleStringBuilder& operator<<(const T& value) {
-    return *this << absl::StrCat(value);
-  }
-
-  // Returns a pointer to the built string. The name `str()` is borrowed for
-  // compatibility reasons as we replace usage of stringstream throughout the
-  // code base.
-  const char* str() const { return buffer_.data(); }
-
-  // Returns the length of the string. The name `size()` is picked for STL
-  // compatibility reasons.
-  size_t size() const { return size_; }
-
-// Allows appending a printf style formatted string.
-#if defined(__GNUC__)
-  __attribute__((__format__(__printf__, 2, 3)))
-#endif
-  SimpleStringBuilder&
-  AppendFormat(const char* fmt, ...);
-
- private:
-  bool IsConsistent() const {
-    return size_ <= buffer_.size() - 1 && buffer_[size_] == '\0';
-  }
-
-  const std::span<char> buffer_;
-  size_t size_ = 0;
-};
-
 // A string builder that supports dynamic resizing while building a string.
 // The class is based around an instance of std::string and allows moving
 // ownership out of the class once the string has been built.
-class StringBuilder {
+class RTC_EXPORT StringBuilder {
  public:
   StringBuilder() = default;
   explicit StringBuilder(absl::string_view s) : str_(s) {}
   StringBuilder(const StringBuilder&) = default;
   StringBuilder& operator=(const StringBuilder&) = default;
 
-  StringBuilder& operator<<(const absl::string_view str) {
-    str_.append(str.data(), str.length());
-    return *this;
-  }
-
-  StringBuilder& operator<<(char c) {
-    str_ += c;
-    return *this;
-  }
-
-  StringBuilder& operator<<(int i) {
-    str_ += absl::StrCat(i);
-    return *this;
-  }
-
-  StringBuilder& operator<<(unsigned i) {
-    str_ += absl::StrCat(i);
-    return *this;
-  }
-
-  StringBuilder& operator<<(long i) {  // NOLINT
-    str_ += absl::StrCat(i);
-    return *this;
-  }
-
-  StringBuilder& operator<<(long long i) {  // NOLINT
-    str_ += absl::StrCat(i);
-    return *this;
-  }
-
-  StringBuilder& operator<<(unsigned long i) {  // NOLINT
-    str_ += absl::StrCat(i);
-    return *this;
-  }
-
-  StringBuilder& operator<<(unsigned long long i) {  // NOLINT
-    str_ += absl::StrCat(i);
-    return *this;
-  }
-
-  StringBuilder& operator<<(float f) {
-    str_ += absl::StrCat(f);
-    return *this;
-  }
-
-  StringBuilder& operator<<(double f) {
-    str_ += absl::StrCat(f);
-    return *this;
-  }
+  StringBuilder& operator<<(absl::string_view str);
+  StringBuilder& operator<<(char c);
+  StringBuilder& operator<<(int i);
+  StringBuilder& operator<<(unsigned i);
+  StringBuilder& operator<<(long i);                // NOLINT
+  StringBuilder& operator<<(long long i);           // NOLINT
+  StringBuilder& operator<<(unsigned long i);       // NOLINT
+  StringBuilder& operator<<(unsigned long long i);  // NOLINT
+  StringBuilder& operator<<(float f);
+  StringBuilder& operator<<(double f);
 
   template <typename T>
     requires absl::HasAbslStringify<T>::value
diff --git a/rtc_base/strings/string_builder_unittest.cc b/rtc_base/strings/string_builder_unittest.cc
index 185ff1a..e8222f8 100644
--- a/rtc_base/strings/string_builder_unittest.cc
+++ b/rtc_base/strings/string_builder_unittest.cc
@@ -33,104 +33,7 @@
   std::string value_;
 };
 
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
 
-TEST(SimpleStringBuilder, Limit) {
-  char sb_buf[10];
-  SimpleStringBuilder sb(sb_buf);
-  EXPECT_EQ(0u, strlen(sb.str()));
-
-  // Test that for a SSB with a buffer size of 10, that we can write 9 chars
-  // into it.
-  sb << "012345678";  // 9 characters + '\0'.
-  EXPECT_EQ(0, strcmp(sb.str(), "012345678"));
-}
-
-TEST(SimpleStringBuilder, NumbersAndChars) {
-  char sb_buf[100];
-  SimpleStringBuilder sb(sb_buf);
-  sb << 1 << ':' << 2.1 << ":" << 2.2f << ':' << 78187493520ll << ':'
-     << 78187493520ul;
-  EXPECT_EQ(0, strcmp(sb.str(), "1:2.1:2.2:78187493520:78187493520"));
-}
-
-TEST(SimpleStringBuilder, Format) {
-  char sb_buf[100];
-  SimpleStringBuilder sb(sb_buf);
-  sb << "Here we go - ";
-  sb.AppendFormat("This is a hex formatted value: 0x%08llx", 3735928559ULL);
-  EXPECT_EQ(0,
-            strcmp(sb.str(),
-                   "Here we go - This is a hex formatted value: 0xdeadbeef"));
-}
-
-TEST(SimpleStringBuilder, StdString) {
-  char sb_buf[100];
-  SimpleStringBuilder sb(sb_buf);
-  std::string str = "does this work?";
-  sb << str;
-  EXPECT_EQ(str, sb.str());
-}
-
-TEST(SimpleStringBuilder, CanUseAbslStringForCustomTypes) {
-  char sb_buf[100];
-  SimpleStringBuilder sb(sb_buf);
-  StructWithAbslStringify value("absl-stringify");
-  sb << value;
-  EXPECT_STREQ(sb.str(), "absl-stringify");
-}
-
-#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
-
-TEST(SimpleStringBuilderDeathTest, BufferOverrunConstCharP) {
-  char sb_buf[4];
-  SimpleStringBuilder sb(sb_buf);
-  const char* const msg = "This is just too much";
-  EXPECT_DEATH(sb << msg, "");
-}
-
-TEST(SimpleStringBuilderDeathTest, BufferOverrunStdString) {
-  char sb_buf[4];
-  SimpleStringBuilder sb(sb_buf);
-  sb << 12;
-  const std::string msg = "Aw, come on!";
-  EXPECT_DEATH(sb << msg, "");
-}
-
-TEST(SimpleStringBuilderDeathTest, BufferOverrunInt) {
-  char sb_buf[4];
-  SimpleStringBuilder sb(sb_buf);
-  constexpr int num = -12345;
-  EXPECT_DEATH(sb << num, "");
-}
-
-TEST(SimpleStringBuilderDeathTest, BufferOverrunDouble) {
-  char sb_buf[5];
-  SimpleStringBuilder sb(sb_buf);
-  constexpr double num = 123.456;
-  EXPECT_DEATH(sb << num, "");
-}
-
-TEST(SimpleStringBuilderDeathTest, BufferOverrunConstCharPAlreadyFull) {
-  char sb_buf[4];
-  SimpleStringBuilder sb(sb_buf);
-  sb << 123;
-  const char* const msg = "This is just too much";
-  EXPECT_DEATH(sb << msg, "");
-}
-
-TEST(SimpleStringBuilderDeathTest, BufferOverrunIntAlreadyFull) {
-  char sb_buf[4];
-  SimpleStringBuilder sb(sb_buf);
-  sb << "xyz";
-  constexpr int num = -12345;
-  EXPECT_DEATH(sb << num, "");
-}
-
-#endif
-
-#pragma clang diagnostic pop
 
 ////////////////////////////////////////////////////////////////////////////////
 // StringBuilder.