diff options
| author | babenko <[email protected]> | 2024-10-13 17:47:48 +0300 | 
|---|---|---|
| committer | babenko <[email protected]> | 2024-10-13 17:58:33 +0300 | 
| commit | a03ad07f802b86bbf071acbe1358f7e00ca4be34 (patch) | |
| tree | 97119051e524f85854516f141e818b81a0f24a39 /library/cpp | |
| parent | 9a90e464060c2d7a036a1b94b1076f7ea7e0cc95 (diff) | |
Extract string_builder
commit_hash:1573c88f09db79bab2755c9c2c3ffd0bc219b2d2
Diffstat (limited to 'library/cpp')
| -rw-r--r-- | library/cpp/yt/string/format-inl.h | 104 | ||||
| -rw-r--r-- | library/cpp/yt/string/format.h | 60 | ||||
| -rw-r--r-- | library/cpp/yt/string/string_builder-inl.h | 121 | ||||
| -rw-r--r-- | library/cpp/yt/string/string_builder.cpp | 30 | ||||
| -rw-r--r-- | library/cpp/yt/string/string_builder.h | 80 | ||||
| -rw-r--r-- | library/cpp/yt/string/ya.make | 1 | 
6 files changed, 218 insertions, 178 deletions
| diff --git a/library/cpp/yt/string/format-inl.h b/library/cpp/yt/string/format-inl.h index 188a699a3d6..7f1f7259665 100644 --- a/library/cpp/yt/string/format-inl.h +++ b/library/cpp/yt/string/format-inl.h @@ -38,110 +38,6 @@ 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()); diff --git a/library/cpp/yt/string/format.h b/library/cpp/yt/string/format.h index a6ab1f76f49..5e5a76db9d8 100644 --- a/library/cpp/yt/string/format.h +++ b/library/cpp/yt/string/format.h @@ -1,6 +1,7 @@  #pragma once  #include "format_string.h" +#include "string_builder.h"  #include <util/generic/string.h> @@ -61,65 +62,6 @@ 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); 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 00000000000..7027f9acc12 --- /dev/null +++ b/library/cpp/yt/string/string_builder-inl.h @@ -0,0 +1,121 @@ +#ifndef STRING_BUILDER_INL_H_ +#error "Direct inclusion of this file is not allowed, include string_builder.h" +// For the sake of sane code completion. +#include "string_builder.h" +#endif + +#include "format_string.h" + +#include <library/cpp/yt/assert/assert.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; +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/string/string_builder.cpp b/library/cpp/yt/string/string_builder.cpp new file mode 100644 index 00000000000..bca493fa325 --- /dev/null +++ b/library/cpp/yt/string/string_builder.cpp @@ -0,0 +1,30 @@ +#include "string_builder.h" + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +TDelimitedStringBuilderWrapper::TDelimitedStringBuilderWrapper( +    TStringBuilderBase* builder, +    TStringBuf delimiter) +    : Builder_(builder) +    , Delimiter_(delimiter) +{ } + +TStringBuilderBase* TDelimitedStringBuilderWrapper::operator->() +{ +    return operator&(); +} + +TStringBuilderBase* TDelimitedStringBuilderWrapper::operator&() +{ +    if (!FirstCall_) { +        Builder_->AppendString(Delimiter_); +    } +    FirstCall_ = false; +    return Builder_; +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/string/string_builder.h b/library/cpp/yt/string/string_builder.h index de1c1abb1ee..ac3aa26a7c1 100644 --- a/library/cpp/yt/string/string_builder.h +++ b/library/cpp/yt/string/string_builder.h @@ -1,13 +1,68 @@  #pragma once -#include "format.h" -  #include <util/generic/string.h>  namespace NYT {  //////////////////////////////////////////////////////////////////////////////// +//! 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; +}; + +//////////////////////////////////////////////////////////////////////////////// +  //! Appends a certain delimiter starting from the second call.  class TDelimitedStringBuilderWrapper      : private TNonCopyable @@ -15,19 +70,10 @@ class TDelimitedStringBuilderWrapper  public:      TDelimitedStringBuilderWrapper(          TStringBuilderBase* builder, -        TStringBuf delimiter = TStringBuf(", ")) -        : Builder_(builder) -        , Delimiter_(delimiter) -    { } - -    TStringBuilderBase* operator->() -    { -        if (!FirstCall_) { -            Builder_->AppendString(Delimiter_); -        } -        FirstCall_ = false; -        return Builder_; -    } +        TStringBuf delimiter = TStringBuf(", ")); + +    TStringBuilderBase* operator->(); +    TStringBuilderBase* operator&();  private:      TStringBuilderBase* const Builder_; @@ -39,3 +85,7 @@ private:  ////////////////////////////////////////////////////////////////////////////////  } // namespace NYT + +#define STRING_BUILDER_INL_H_ +#include "string_builder-inl.h" +#undef STRING_BUILDER_INL_H_ diff --git a/library/cpp/yt/string/ya.make b/library/cpp/yt/string/ya.make index db3a477b358..2071e0a115a 100644 --- a/library/cpp/yt/string/ya.make +++ b/library/cpp/yt/string/ya.make @@ -8,6 +8,7 @@ SRCS(      string.cpp      format_string.cpp      format.cpp +    string_builder.cpp  )  PEERDIR( | 
