Add a StringBuilder class.

String builder is similar to SimpleStringBuilder, but the difference is
that StringBuilder is built around a std::string instance and supports
dynamic resizing.

Change-Id: I874d22e69e639ff9ef3d5929366f4ba71c545787
Bug: webrtc:8982
Reviewed-on: https://webrtc-review.googlesource.com/58980
Commit-Queue: Jonas Olsson <jonasolsson@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24526}
diff --git a/rtc_base/strings/string_builder.h b/rtc_base/strings/string_builder.h
index 093954b..d95b29d 100644
--- a/rtc_base/strings/string_builder.h
+++ b/rtc_base/strings/string_builder.h
@@ -15,9 +15,11 @@
 #include <cstring>
 #include <string>
 
+#include "absl/strings/string_view.h"
 #include "api/array_view.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_minmax.h"
+#include "rtc_base/stringencode.h"
 #include "rtc_base/stringutils.h"
 
 namespace rtc {
@@ -82,6 +84,95 @@
   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.
+// Note that this class uses the heap for allocations, so SimpleStringBuilder
+// might be more efficient for some use cases.
+class StringBuilder {
+ public:
+  StringBuilder() {}
+  explicit StringBuilder(absl::string_view s) : str_(s) {}
+
+  // TODO(tommi): Support construction from StringBuilder?
+  StringBuilder(const StringBuilder&) = delete;
+  StringBuilder& operator=(const StringBuilder&) = delete;
+
+  StringBuilder& operator<<(const absl::string_view str) {
+    str_.append(str.data(), str.length());
+    return *this;
+  }
+
+  StringBuilder& operator<<(char c) = delete;
+
+  StringBuilder& operator<<(int i) {
+    str_ += rtc::ToString(i);
+    return *this;
+  }
+
+  StringBuilder& operator<<(unsigned i) {
+    str_ += rtc::ToString(i);
+    return *this;
+  }
+
+  StringBuilder& operator<<(long i) {  // NOLINT
+    str_ += rtc::ToString(i);
+    return *this;
+  }
+
+  StringBuilder& operator<<(long long i) {  // NOLINT
+    str_ += rtc::ToString(i);
+    return *this;
+  }
+
+  StringBuilder& operator<<(unsigned long i) {  // NOLINT
+    str_ += rtc::ToString(i);
+    return *this;
+  }
+
+  StringBuilder& operator<<(unsigned long long i) {  // NOLINT
+    str_ += rtc::ToString(i);
+    return *this;
+  }
+
+  StringBuilder& operator<<(float f) {
+    str_ += rtc::ToString(f);
+    return *this;
+  }
+
+  StringBuilder& operator<<(double f) {
+    str_ += rtc::ToString(f);
+    return *this;
+  }
+
+  StringBuilder& operator<<(long double f) {
+    str_ += rtc::ToString(f);
+    return *this;
+  }
+
+  const std::string& str() const { return str_; }
+
+  void Clear() { str_.clear(); }
+
+  size_t size() const { return str_.size(); }
+
+  std::string Release() {
+    std::string ret;
+    std::swap(str_, ret);
+    return ret;
+  }
+
+  // Allows appending a printf style formatted string.
+  StringBuilder& AppendFormat(const char* fmt, ...)
+#if defined(__GNUC__)
+      __attribute__((__format__(__printf__, 2, 3)))
+#endif
+      ;
+
+ private:
+  std::string str_;
+};
+
 }  // namespace rtc
 
 #endif  // RTC_BASE_STRINGS_STRING_BUILDER_H_