aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/string/string_builder-inl.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/yt/string/string_builder-inl.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/yt/string/string_builder-inl.h')
-rw-r--r--library/cpp/yt/string/string_builder-inl.h129
1 files changed, 129 insertions, 0 deletions
diff --git a/library/cpp/yt/string/string_builder-inl.h b/library/cpp/yt/string/string_builder-inl.h
new file mode 100644
index 0000000000..151fcabf7f
--- /dev/null
+++ b/library/cpp/yt/string/string_builder-inl.h
@@ -0,0 +1,129 @@
+#ifndef STRING_BUILDER_INL_H_
+#error "Direct inclusion of this file is not allowed, include string.h"
+// For the sake of sane code completion.
+#include "string_builder.h"
+#endif
+
+#include <library/cpp/yt/assert/assert.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline char* TStringBuilderBase::Preallocate(size_t size)
+{
+ if (Y_UNLIKELY(End_ - Current_ < static_cast<ssize_t>(size))) {
+ size_t length = GetLength();
+ auto newLength = std::max(length + size, MinBufferLength);
+ DoPreallocate(newLength);
+ Current_ = Begin_ + length;
+ }
+ return Current_;
+}
+
+inline size_t TStringBuilderBase::GetLength() const
+{
+ return Current_ ? Current_ - Begin_ : 0;
+}
+
+inline TStringBuf TStringBuilderBase::GetBuffer() const
+{
+ return TStringBuf(Begin_, Current_);
+}
+
+inline void TStringBuilderBase::Advance(size_t size)
+{
+ Current_ += size;
+ YT_ASSERT(Current_ <= End_);
+}
+
+inline void TStringBuilderBase::AppendChar(char ch)
+{
+ *Preallocate(1) = ch;
+ Advance(1);
+}
+
+inline void TStringBuilderBase::AppendChar(char ch, int n)
+{
+ YT_ASSERT(n >= 0);
+ if (Y_LIKELY(0 != n)) {
+ char* dst = Preallocate(n);
+ ::memset(dst, ch, n);
+ Advance(n);
+ }
+}
+
+inline void TStringBuilderBase::AppendString(TStringBuf str)
+{
+ if (Y_LIKELY(str)) {
+ char* dst = Preallocate(str.length());
+ ::memcpy(dst, str.begin(), str.length());
+ Advance(str.length());
+ }
+}
+
+inline void TStringBuilderBase::AppendString(const char* str)
+{
+ AppendString(TStringBuf(str));
+}
+
+inline void TStringBuilderBase::Reset()
+{
+ Begin_ = Current_ = End_ = nullptr;
+ DoReset();
+}
+
+template <class... TArgs>
+void TStringBuilderBase::AppendFormat(TStringBuf format, TArgs&& ... args)
+{
+ Format(this, format, std::forward<TArgs>(args)...);
+}
+
+template <size_t Length, class... TArgs>
+void TStringBuilderBase::AppendFormat(const char (&format)[Length], TArgs&& ... args)
+{
+ Format(this, format, std::forward<TArgs>(args)...);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline TString TStringBuilder::Flush()
+{
+ Buffer_.resize(GetLength());
+ auto result = std::move(Buffer_);
+ Reset();
+ return result;
+}
+
+inline void TStringBuilder::DoReset()
+{
+ Buffer_ = {};
+}
+
+inline void TStringBuilder::DoPreallocate(size_t newLength)
+{
+ Buffer_.ReserveAndResize(newLength);
+ auto capacity = Buffer_.capacity();
+ Buffer_.ReserveAndResize(capacity);
+ Begin_ = &*Buffer_.begin();
+ End_ = Begin_ + capacity;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline void FormatValue(TStringBuilderBase* builder, const TStringBuilder& value, TStringBuf /*format*/)
+{
+ builder->AppendString(value.GetBuffer());
+}
+
+template <class T>
+TString ToStringViaBuilder(const T& value, TStringBuf spec)
+{
+ TStringBuilder builder;
+ FormatValue(&builder, value, spec);
+ return builder.Flush();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT