diff options
author | Alexander Smirnov <alex@ydb.tech> | 2024-07-08 15:54:05 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2024-07-08 15:54:05 +0000 |
commit | fc7be18c76af2e700641f3598c4856baeef1428e (patch) | |
tree | 11dbca45eb321c3a4dd08b12152acc6ef5dd3fa9 /library/cpp/yt | |
parent | ec0e7ed6da6fb317741fd8468602949a1362eca5 (diff) | |
parent | c92cb9d3a19331916f0c274d80e67f02a62caa9b (diff) | |
download | ydb-fc7be18c76af2e700641f3598c4856baeef1428e.tar.gz |
Merge branch 'rightlib' into mergelibs-240708-1553
Diffstat (limited to 'library/cpp/yt')
-rw-r--r-- | library/cpp/yt/misc/concepts.h | 19 | ||||
-rw-r--r-- | library/cpp/yt/misc/property.h | 17 | ||||
-rw-r--r-- | library/cpp/yt/misc/source_location-inl.h | 25 | ||||
-rw-r--r-- | library/cpp/yt/misc/source_location.cpp | 7 | ||||
-rw-r--r-- | library/cpp/yt/misc/source_location.h | 33 | ||||
-rw-r--r-- | library/cpp/yt/string/enum-inl.h | 1 | ||||
-rw-r--r-- | library/cpp/yt/string/enum.h | 2 | ||||
-rw-r--r-- | library/cpp/yt/string/format-inl.h | 177 | ||||
-rw-r--r-- | library/cpp/yt/string/format.h | 79 | ||||
-rw-r--r-- | library/cpp/yt/string/format_arg.h | 2 | ||||
-rw-r--r-- | library/cpp/yt/string/guid.cpp | 4 | ||||
-rw-r--r-- | library/cpp/yt/string/guid.h | 8 | ||||
-rw-r--r-- | library/cpp/yt/string/string-inl.h | 158 | ||||
-rw-r--r-- | library/cpp/yt/string/string.h | 83 | ||||
-rw-r--r-- | library/cpp/yt/string/string_builder-inl.h | 187 | ||||
-rw-r--r-- | library/cpp/yt/string/string_builder.h | 78 |
16 files changed, 510 insertions, 370 deletions
diff --git a/library/cpp/yt/misc/concepts.h b/library/cpp/yt/misc/concepts.h index 5b84bac905..aecad4fe60 100644 --- a/library/cpp/yt/misc/concepts.h +++ b/library/cpp/yt/misc/concepts.h @@ -62,4 +62,23 @@ concept CAnyMap = requires { //////////////////////////////////////////////////////////////////////////////// +template <class T> +concept CConst = std::is_const_v<T>; + +template <class T> +concept CNonConst = !CConst<T>; + +//////////////////////////////////////////////////////////////////////////////// + +template <class T> +concept CRawPtr = std::is_pointer_v<T>; + +template <class T> +concept CConstRawPtr = CRawPtr<T> && CConst<decltype(*std::declval<T>())>; + +template <class T> +concept CMutRawPtr = CRawPtr<T> && !CConstRawPtr<T>; + +//////////////////////////////////////////////////////////////////////////////// + } // namespace NYT diff --git a/library/cpp/yt/misc/property.h b/library/cpp/yt/misc/property.h index 4d0577f464..3c42693ef3 100644 --- a/library/cpp/yt/misc/property.h +++ b/library/cpp/yt/misc/property.h @@ -157,6 +157,23 @@ public: \ } \ static_assert(true) +//! Defines a trivial public read-write boolean property that is passed by value. +//! All arguments after name are used as default value (via braced-init-list). +#define DEFINE_BYVAL_RW_BOOLEAN_PROPERTY(name, ...) \ +protected: \ + bool name##_ { __VA_ARGS__ }; \ + \ +public: \ + Y_FORCE_INLINE bool Is##name() const \ + { \ + return name##_; \ + } \ + \ + Y_FORCE_INLINE void Set##name(bool value) \ + { \ + name##_ = value; \ + } \ + static_assert(true) //! Defines a trivial public read-write property that is passed by value. //! All arguments after name are used as default value (via braced-init-list). diff --git a/library/cpp/yt/misc/source_location-inl.h b/library/cpp/yt/misc/source_location-inl.h new file mode 100644 index 0000000000..9948260874 --- /dev/null +++ b/library/cpp/yt/misc/source_location-inl.h @@ -0,0 +1,25 @@ +#ifndef SOURCE_LOCATION_INL_H_ +#error "Direct inclusion of this file is not allowed, include source_location.h" +// For the sake of sane code completion. +#include "source_location.h" +#endif + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +inline TSourceLocation::TSourceLocation(const char* fileName, int line) + : FileName_(fileName) + , Line_(line) +{ } + +#ifdef __cpp_lib_source_location +inline TSourceLocation::TSourceLocation(const std::source_location& location) + : FileName_(location.file_name()) + , Line_(location.line()) +{ } +#endif // __cpp_lib_source_location + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace std diff --git a/library/cpp/yt/misc/source_location.cpp b/library/cpp/yt/misc/source_location.cpp index f3f396ee90..598126f5a7 100644 --- a/library/cpp/yt/misc/source_location.cpp +++ b/library/cpp/yt/misc/source_location.cpp @@ -70,13 +70,6 @@ bool TSourceLocation::operator==(const TSourceLocation& other) const Line_ == other.Line_; } -#ifdef __cpp_lib_source_location -TSourceLocation TSourceLocation::FromStd(const std::source_location& location) -{ - return TSourceLocation(location.file_name(), location.line()); -} -#endif // __cpp_lib_source_location - void FormatValue(TStringBuilderBase* builder, const TSourceLocation& location, TStringBuf /*spec*/) { if (location.GetFileName() != nullptr) { diff --git a/library/cpp/yt/misc/source_location.h b/library/cpp/yt/misc/source_location.h index 0496a4e496..286527887a 100644 --- a/library/cpp/yt/misc/source_location.h +++ b/library/cpp/yt/misc/source_location.h @@ -14,9 +14,7 @@ class TStringBuilderBase; // TODO(dgolear): Drop when LLVM-14 is eradicated. #ifdef __cpp_lib_source_location - void FormatValue(TStringBuilderBase* builder, const std::source_location& location, TStringBuf /*spec*/); - #endif // __cpp_lib_source_location //////////////////////////////////////////////////////////////////////////////// @@ -24,15 +22,11 @@ void FormatValue(TStringBuilderBase* builder, const std::source_location& locati class TSourceLocation { public: - TSourceLocation() - : FileName_(nullptr) - , Line_(-1) - { } - - TSourceLocation(const char* fileName, int line) - : FileName_(fileName) - , Line_(line) - { } + TSourceLocation() = default; + TSourceLocation(const char* fileName, int line); +#ifdef __cpp_lib_source_location + explicit TSourceLocation(const std::source_location& location); +#endif // __cpp_lib_source_location const char* GetFileName() const; int GetLine() const; @@ -41,21 +35,16 @@ public: bool operator<(const TSourceLocation& other) const; bool operator==(const TSourceLocation& other) const; -#ifdef __cpp_lib_source_location - static TSourceLocation FromStd(const std::source_location& location); -#endif // __cpp_lib_source_location - private: - const char* FileName_; - int Line_; - + const char* FileName_ = nullptr; + int Line_ = -1; }; //! Defines a macro to record the current source location. #ifdef __cpp_lib_source_location -#define FROM_HERE ::NYT::TSourceLocation::FromStd(std::source_location::current()) +#define YT_CURRENT_SOURCE_LOCATION ::NYT::TSourceLocation(std::source_location::current()) #else -#define FROM_HERE ::NYT::TSourceLocation(__FILE__, __LINE__) +#define YT_CURRENT_SOURCE_LOCATION ::NYT::TSourceLocation(__FILE__, __LINE__) #endif // __cpp_lib_source_location void FormatValue(TStringBuilderBase* builder, const TSourceLocation& location, TStringBuf spec); @@ -63,3 +52,7 @@ void FormatValue(TStringBuilderBase* builder, const TSourceLocation& location, T //////////////////////////////////////////////////////////////////////////////// } // namespace NYT + +#define SOURCE_LOCATION_INL_H_ +#include "source_location-inl.h" +#undef SOURCE_LOCATION_INL_H_ diff --git a/library/cpp/yt/string/enum-inl.h b/library/cpp/yt/string/enum-inl.h index d9f8239cbd..41f7197d15 100644 --- a/library/cpp/yt/string/enum-inl.h +++ b/library/cpp/yt/string/enum-inl.h @@ -9,6 +9,7 @@ #include <library/cpp/yt/exception/exception.h> #include <util/string/printf.h> +#include <util/string/strip.h> namespace NYT { diff --git a/library/cpp/yt/string/enum.h b/library/cpp/yt/string/enum.h index b4b8d59171..792e09402d 100644 --- a/library/cpp/yt/string/enum.h +++ b/library/cpp/yt/string/enum.h @@ -1,6 +1,6 @@ #pragma once -#include "string.h" +#include "format_arg.h" #include <library/cpp/yt/misc/enum.h> 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 diff --git a/library/cpp/yt/string/format.h b/library/cpp/yt/string/format.h index 62b8726ddb..a6ab1f76f4 100644 --- a/library/cpp/yt/string/format.h +++ b/library/cpp/yt/string/format.h @@ -1,6 +1,8 @@ #pragma once -#include "string_builder.h" +#include "format_string.h" + +#include <util/generic/string.h> namespace NYT { @@ -55,12 +57,79 @@ namespace NYT { */ template <class... TArgs> -void Format(TStringBuilderBase* builder, TFormatString<TArgs...> format, TArgs&&... args); -template <class... TArgs> TString Format(TFormatString<TArgs...> format, TArgs&&... args); //////////////////////////////////////////////////////////////////////////////// +// StringBuilder(Base) definition. + +//! A simple helper for constructing strings by a sequence of appends. +class TStringBuilderBase +{ +public: + virtual ~TStringBuilderBase() = default; + + char* Preallocate(size_t size); + + void Reserve(size_t size); + + size_t GetLength() const; + + TStringBuf GetBuffer() const; + + void Advance(size_t size); + + void AppendChar(char ch); + void AppendChar(char ch, int n); + + void AppendString(TStringBuf str); + void AppendString(const char* str); + + template <size_t Length, class... TArgs> + void AppendFormat(const char (&format)[Length], TArgs&&... args); + template <class... TArgs> + void AppendFormat(TStringBuf format, TArgs&&... args); + + void Reset(); + +protected: + char* Begin_ = nullptr; + char* Current_ = nullptr; + char* End_ = nullptr; + + virtual void DoReset() = 0; + virtual void DoReserve(size_t newLength) = 0; + + static constexpr size_t MinBufferLength = 128; +}; + +//////////////////////////////////////////////////////////////////////////////// + +class TStringBuilder + : public TStringBuilderBase +{ +public: + TString Flush(); + +protected: + TString Buffer_; + + void DoReset() override; + void DoReserve(size_t size) override; +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <class... TArgs> +void Format(TStringBuilderBase* builder, TFormatString<TArgs...> format, TArgs&&... args); + +//////////////////////////////////////////////////////////////////////////////// + +template <class T> +TString ToStringViaBuilder(const T& value, TStringBuf spec = TStringBuf("v")); + +//////////////////////////////////////////////////////////////////////////////// + template <class TRange, class TFormatter> struct TFormattableView { @@ -99,11 +168,11 @@ struct TFormatterWrapper // Allows insertion of text conditionally. // Usage: /* - NYT::Format( +NYT::Format( "Value is %v%v", 42, MakeFormatterWrapper([&] (auto* builder) { - If (PossiblyMissingInfo_) { + if (PossiblyMissingInfo_) { builder->AppendString(", PossiblyMissingInfo: "); FormatValue(builder, PossiblyMissingInfo_, "v"); } diff --git a/library/cpp/yt/string/format_arg.h b/library/cpp/yt/string/format_arg.h index 6240059ed9..544e265766 100644 --- a/library/cpp/yt/string/format_arg.h +++ b/library/cpp/yt/string/format_arg.h @@ -27,7 +27,7 @@ constexpr bool IsNYTName(); // Base used for flag checks for each type independently. // Use it for overrides. -struct TFormatArgBase +class TFormatArgBase { public: // TODO(arkady-e1ppa): Consider more strict formatting rules. diff --git a/library/cpp/yt/string/guid.cpp b/library/cpp/yt/string/guid.cpp index 2a781d032d..b18ac3e128 100644 --- a/library/cpp/yt/string/guid.cpp +++ b/library/cpp/yt/string/guid.cpp @@ -1,10 +1,12 @@ #include "guid.h" +#include "format.h" + namespace NYT { //////////////////////////////////////////////////////////////////////////////// -void FormatValue(TStringBuilderBase* builder, TGuid value, TStringBuf /*format*/) +void FormatValue(TStringBuilderBase* builder, TGuid value, TStringBuf /*spec*/) { char* begin = builder->Preallocate(MaxGuidStringSize); char* end = WriteGuidToBuffer(begin, value); diff --git a/library/cpp/yt/string/guid.h b/library/cpp/yt/string/guid.h index de16993486..fd3943bafd 100644 --- a/library/cpp/yt/string/guid.h +++ b/library/cpp/yt/string/guid.h @@ -1,12 +1,14 @@ -#include <library/cpp/yt/misc/guid.h> +#pragma once + +#include "format_arg.h" -#include "format.h" +#include <library/cpp/yt/misc/guid.h> namespace NYT { //////////////////////////////////////////////////////////////////////////////// -void FormatValue(TStringBuilderBase* builder, TGuid value, TStringBuf /*format*/); +void FormatValue(TStringBuilderBase* builder, TGuid value, TStringBuf /*spec*/); //////////////////////////////////////////////////////////////////////////////// diff --git a/library/cpp/yt/string/string-inl.h b/library/cpp/yt/string/string-inl.h new file mode 100644 index 0000000000..baf789b4f1 --- /dev/null +++ b/library/cpp/yt/string/string-inl.h @@ -0,0 +1,158 @@ +#ifndef STRING_INL_H_ +#error "Direct inclusion of this file is not allowed, include string.h" +// For the sake of sane code completion. +#include "string.h" +#endif + +#include "format.h" + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +//! Joins a range of items into a string intermixing them with the delimiter. +/*! + * \param builder String builder where the output goes. + * \param begin Iterator pointing to the first item (inclusive). + * \param end Iterator pointing to the last item (not inclusive). + * \param formatter Formatter to apply to the items. + * \param delimiter A delimiter to be inserted between items: ", " by default. + * \return The resulting combined string. + */ +template <class TIterator, class TFormatter> +void JoinToString( + TStringBuilderBase* builder, + const TIterator& begin, + const TIterator& end, + const TFormatter& formatter, + TStringBuf delimiter) +{ + for (auto current = begin; current != end; ++current) { + if (current != begin) { + builder->AppendString(delimiter); + } + formatter(builder, *current); + } +} + +template <class TIterator, class TFormatter> +TString JoinToString( + const TIterator& begin, + const TIterator& end, + const TFormatter& formatter, + TStringBuf delimiter) +{ + TStringBuilder builder; + JoinToString(&builder, begin, end, formatter, delimiter); + return builder.Flush(); +} + +//! A handy shortcut with default formatter. +template <class TIterator> +TString JoinToString( + const TIterator& begin, + const TIterator& end, + TStringBuf delimiter) +{ + return JoinToString(begin, end, TDefaultFormatter(), delimiter); +} + +//! Joins a collection of given items into a string intermixing them with the delimiter. +/*! + * \param collection A collection containing the items to be joined. + * \param formatter Formatter to apply to the items. + * \param delimiter A delimiter to be inserted between items; ", " by default. + */ +template <class TCollection, class TFormatter> +TString JoinToString( + const TCollection& collection, + const TFormatter& formatter, + TStringBuf delimiter) +{ + using std::begin; + using std::end; + return JoinToString(begin(collection), end(collection), formatter, delimiter); +} + +//! A handy shortcut with the default formatter. +template <class TCollection> +TString JoinToString( + const TCollection& collection, + TStringBuf delimiter) +{ + return JoinToString(collection, TDefaultFormatter(), delimiter); +} + +//! Concatenates a bunch of TStringBuf-like instances into TString. +template <class... Ts> +TString ConcatToString(Ts... args) +{ + size_t length = 0; + ((length += args.length()), ...); + + TString result; + result.reserve(length); + (result.append(args), ...); + + return result; +} + +//! Converts a range of items into strings. +template <class TIter, class TFormatter> +std::vector<TString> ConvertToStrings( + const TIter& begin, + const TIter& end, + const TFormatter& formatter, + size_t maxSize) +{ + std::vector<TString> result; + for (auto it = begin; it != end; ++it) { + TStringBuilder builder; + formatter(&builder, *it); + result.push_back(builder.Flush()); + if (result.size() == maxSize) { + break; + } + } + return result; +} + +//! A handy shortcut with the default formatter. +template <class TIter> +std::vector<TString> ConvertToStrings( + const TIter& begin, + const TIter& end, + size_t maxSize) +{ + return ConvertToStrings(begin, end, TDefaultFormatter(), maxSize); +} + +//! Converts a given collection of items into strings. +/*! + * \param collection A collection containing the items to be converted. + * \param formatter Formatter to apply to the items. + * \param maxSize Size limit for the resulting vector. + */ +template <class TCollection, class TFormatter> +std::vector<TString> ConvertToStrings( + const TCollection& collection, + const TFormatter& formatter, + size_t maxSize) +{ + using std::begin; + using std::end; + return ConvertToStrings(begin(collection), end(collection), formatter, maxSize); +} + +//! A handy shortcut with default formatter. +template <class TCollection> +std::vector<TString> ConvertToStrings( + const TCollection& collection, + size_t maxSize) +{ + return ConvertToStrings(collection, TDefaultFormatter(), maxSize); +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/string/string.h b/library/cpp/yt/string/string.h index a131b40a2a..8257c1a5ea 100644 --- a/library/cpp/yt/string/string.h +++ b/library/cpp/yt/string/string.h @@ -1,6 +1,6 @@ #pragma once -#include "string_builder.h" +#include "format_arg.h" #include <util/datetime/base.h> @@ -52,37 +52,21 @@ void JoinToString( const TIterator& begin, const TIterator& end, const TFormatter& formatter, - TStringBuf delimiter = DefaultJoinToStringDelimiter) -{ - for (auto current = begin; current != end; ++current) { - if (current != begin) { - builder->AppendString(delimiter); - } - formatter(builder, *current); - } -} + TStringBuf delimiter = DefaultJoinToStringDelimiter); template <class TIterator, class TFormatter> TString JoinToString( const TIterator& begin, const TIterator& end, const TFormatter& formatter, - TStringBuf delimiter = DefaultJoinToStringDelimiter) -{ - TStringBuilder builder; - JoinToString(&builder, begin, end, formatter, delimiter); - return builder.Flush(); -} + TStringBuf delimiter = DefaultJoinToStringDelimiter); //! A handy shortcut with default formatter. template <class TIterator> TString JoinToString( const TIterator& begin, const TIterator& end, - TStringBuf delimiter = DefaultJoinToStringDelimiter) -{ - return JoinToString(begin, end, TDefaultFormatter(), delimiter); -} + TStringBuf delimiter = DefaultJoinToStringDelimiter); //! Joins a collection of given items into a string intermixing them with the delimiter. /*! @@ -94,35 +78,17 @@ template <class TCollection, class TFormatter> TString JoinToString( const TCollection& collection, const TFormatter& formatter, - TStringBuf delimiter = DefaultJoinToStringDelimiter) -{ - using std::begin; - using std::end; - return JoinToString(begin(collection), end(collection), formatter, delimiter); -} + TStringBuf delimiter = DefaultJoinToStringDelimiter); //! A handy shortcut with the default formatter. template <class TCollection> TString JoinToString( const TCollection& collection, - TStringBuf delimiter = DefaultJoinToStringDelimiter) -{ - return JoinToString(collection, TDefaultFormatter(), delimiter); -} + TStringBuf delimiter = DefaultJoinToStringDelimiter); //! Concatenates a bunch of TStringBuf-like instances into TString. template <class... Ts> -TString ConcatToString(Ts... args) -{ - size_t length = 0; - ((length += args.length()), ...); - - TString result; - result.reserve(length); - (result.append(args), ...); - - return result; -} +TString ConcatToString(Ts... args); //! Converts a range of items into strings. template <class TIter, class TFormatter> @@ -130,29 +96,14 @@ std::vector<TString> ConvertToStrings( const TIter& begin, const TIter& end, const TFormatter& formatter, - size_t maxSize = std::numeric_limits<size_t>::max()) -{ - std::vector<TString> result; - for (auto it = begin; it != end; ++it) { - TStringBuilder builder; - formatter(&builder, *it); - result.push_back(builder.Flush()); - if (result.size() == maxSize) { - break; - } - } - return result; -} + size_t maxSize = std::numeric_limits<size_t>::max()); //! A handy shortcut with the default formatter. template <class TIter> std::vector<TString> ConvertToStrings( const TIter& begin, const TIter& end, - size_t maxSize = std::numeric_limits<size_t>::max()) -{ - return ConvertToStrings(begin, end, TDefaultFormatter(), maxSize); -} + size_t maxSize = std::numeric_limits<size_t>::max()); //! Converts a given collection of items into strings. /*! @@ -164,21 +115,13 @@ template <class TCollection, class TFormatter> std::vector<TString> ConvertToStrings( const TCollection& collection, const TFormatter& formatter, - size_t maxSize = std::numeric_limits<size_t>::max()) -{ - using std::begin; - using std::end; - return ConvertToStrings(begin(collection), end(collection), formatter, maxSize); -} + size_t maxSize = std::numeric_limits<size_t>::max()); //! A handy shortcut with default formatter. template <class TCollection> std::vector<TString> ConvertToStrings( const TCollection& collection, - size_t maxSize = std::numeric_limits<size_t>::max()) -{ - return ConvertToStrings(collection, TDefaultFormatter(), maxSize); -} + size_t maxSize = std::numeric_limits<size_t>::max()); //////////////////////////////////////////////////////////////////////////////// @@ -222,3 +165,7 @@ TStringBuf FormatBool(bool value); //////////////////////////////////////////////////////////////////////////////// } // namespace NYT + +#define STRING_INL_H_ +#include "string-inl.h" +#undef STRING_INL_H_ diff --git a/library/cpp/yt/string/string_builder-inl.h b/library/cpp/yt/string/string_builder-inl.h deleted file mode 100644 index 9fb3ae94f8..0000000000 --- a/library/cpp/yt/string/string_builder-inl.h +++ /dev/null @@ -1,187 +0,0 @@ -#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> - -#include <util/stream/str.h> - -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; -} - -//////////////////////////////////////////////////////////////////////////////// - -} // 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 diff --git a/library/cpp/yt/string/string_builder.h b/library/cpp/yt/string/string_builder.h index 4cba45bc72..de1c1abb1e 100644 --- a/library/cpp/yt/string/string_builder.h +++ b/library/cpp/yt/string/string_builder.h @@ -1,6 +1,6 @@ #pragma once -#include "format_string.h" +#include "format.h" #include <util/generic/string.h> @@ -8,78 +8,6 @@ namespace NYT { //////////////////////////////////////////////////////////////////////////////// -// Forward declarations. -class TStringBuilderBase; -class TStringBuilder; -class TDelimitedStringBuilderWrapper; - -template <class... TArgs> -void Format(TStringBuilderBase* builder, TFormatString<TArgs...> fmt, TArgs&&... args); - -//////////////////////////////////////////////////////////////////////////////// - -//! A simple helper for constructing strings by a sequence of appends. -class TStringBuilderBase -{ -public: - virtual ~TStringBuilderBase() = default; - - char* Preallocate(size_t size); - - void Reserve(size_t size); - - size_t GetLength() const; - - TStringBuf GetBuffer() const; - - void Advance(size_t size); - - void AppendChar(char ch); - void AppendChar(char ch, int n); - - void AppendString(TStringBuf str); - void AppendString(const char* str); - - template <size_t Length, class... TArgs> - void AppendFormat(const char (&format)[Length], TArgs&&... args); - template <class... TArgs> - void AppendFormat(TStringBuf format, TArgs&&... args); - - void Reset(); - -protected: - char* Begin_ = nullptr; - char* Current_ = nullptr; - char* End_ = nullptr; - - virtual void DoReset() = 0; - virtual void DoReserve(size_t newLength) = 0; - - static constexpr size_t MinBufferLength = 128; -}; - -//////////////////////////////////////////////////////////////////////////////// - -class TStringBuilder - : public TStringBuilderBase -{ -public: - TString Flush(); - -protected: - TString Buffer_; - - void DoReset() override; - void DoReserve(size_t size) override; -}; - -//////////////////////////////////////////////////////////////////////////////// - -template <class T> -TString ToStringViaBuilder(const T& value, TStringBuf spec = TStringBuf("v")); - -//////////////////////////////////////////////////////////////////////////////// - //! Appends a certain delimiter starting from the second call. class TDelimitedStringBuilderWrapper : private TNonCopyable @@ -111,7 +39,3 @@ private: //////////////////////////////////////////////////////////////////////////////// } // namespace NYT - -#define STRING_BUILDER_INL_H_ -#include "string_builder-inl.h" -#undef STRING_BUILDER_INL_H_ |