aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/string/format-inl.h
diff options
context:
space:
mode:
authorarkady-e1ppa <arkady-e1ppa@yandex-team.com>2024-07-02 15:28:09 +0300
committerarkady-e1ppa <arkady-e1ppa@yandex-team.com>2024-07-02 15:40:39 +0300
commit3336f268eb26aa0318cd3fa3f97116c43545f87b (patch)
tree047395a3b7bf0751a86c5676a9c103e168e47e3c /library/cpp/yt/string/format-inl.h
parentaa95a328ada306559bd361a96c5348829d0e562e (diff)
downloadydb-3336f268eb26aa0318cd3fa3f97116c43545f87b.tar.gz
YT-21868: Reorganize files to prevent unclear missing include errors
Moving files around so that include of either `string_builder.h` or `format.h` would result in being able to use both `Format` and `TStringBuilder` 8a2abbea2ae7027c1cd3a243ab3de55bdd5d3d27
Diffstat (limited to 'library/cpp/yt/string/format-inl.h')
-rw-r--r--library/cpp/yt/string/format-inl.h177
1 files changed, 177 insertions, 0 deletions
diff --git a/library/cpp/yt/string/format-inl.h b/library/cpp/yt/string/format-inl.h
index 1ff2d816c5..4eaa70bef2 100644
--- a/library/cpp/yt/string/format-inl.h
+++ b/library/cpp/yt/string/format-inl.h
@@ -4,6 +4,7 @@
#include "format.h"
#endif
+#include "guid.h"
#include "enum.h"
#include "string.h"
@@ -33,6 +34,155 @@ namespace NYT {
////////////////////////////////////////////////////////////////////////////////
+inline char* TStringBuilderBase::Preallocate(size_t size)
+{
+ Reserve(size + GetLength());
+ return Current_;
+}
+
+inline void TStringBuilderBase::Reserve(size_t size)
+{
+ if (Y_UNLIKELY(End_ - Begin_ < static_cast<ssize_t>(size))) {
+ size_t length = GetLength();
+ auto newLength = std::max(size, MinBufferLength);
+ DoReserve(newLength);
+ Current_ = Begin_ + length;
+ }
+}
+
+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, TRuntimeFormat{format}, std::forward<TArgs>(args)...);
+}
+
+template <size_t Length, class... TArgs>
+void TStringBuilderBase::AppendFormat(const char (&format)[Length], TArgs&& ... args)
+{
+ Format(this, TRuntimeFormat{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::DoReserve(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 /*spec*/)
+{
+ builder->AppendString(value.GetBuffer());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+TString ToStringViaBuilder(const T& value, TStringBuf spec)
+{
+ TStringBuilder builder;
+ FormatValue(&builder, value, spec);
+ return builder.Flush();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Compatibility for users of NYT::ToString(nyt_type).
+template <CFormattable T>
+TString ToString(const T& t)
+{
+ return ToStringViaBuilder(t);
+}
+
+// Sometime we want to implement
+// FormatValue using util's ToString
+// However, if we inside the FormatValue
+// we cannot just call the ToString since
+// in this scope T is already CFormattable
+// and ToString will call the very
+// FormatValue we are implementing,
+// causing an infinite recursion loop.
+// This method is basically a call to
+// util's ToString default implementation.
+template <class T>
+TString ToStringIgnoringFormatValue(const T& t)
+{
+ TString s;
+ ::TStringOutput o(s);
+ o << t;
+ return s;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
// Helper functions for formatting.
namespace NDetail {
@@ -887,3 +1037,30 @@ TString FormatVector(
////////////////////////////////////////////////////////////////////////////////
} // namespace NYT
+
+#include <util/string/cast.h>
+
+// util/string/cast.h extension for yt and std types only
+// TODO(arkady-e1ppa): Abolish ::ToString in
+// favour of either NYT::ToString or
+// automatic formatting wherever it is needed.
+namespace NPrivate {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+ requires (
+ (NYT::NDetail::IsNYTName<T>() ||
+ NYT::NDetail::IsStdName<T>()) &&
+ NYT::CFormattable<T>)
+struct TToString<T, false>
+{
+ static TString Cvt(const T& t)
+ {
+ return NYT::ToStringViaBuilder(t);
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NPrivate