diff options
author | arkady-e1ppa <arkady-e1ppa@yandex-team.com> | 2024-07-02 15:28:09 +0300 |
---|---|---|
committer | arkady-e1ppa <arkady-e1ppa@yandex-team.com> | 2024-07-02 15:40:39 +0300 |
commit | 3336f268eb26aa0318cd3fa3f97116c43545f87b (patch) | |
tree | 047395a3b7bf0751a86c5676a9c103e168e47e3c /library/cpp/yt/string/format-inl.h | |
parent | aa95a328ada306559bd361a96c5348829d0e562e (diff) | |
download | ydb-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.h | 177 |
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 |