string_builder-inl.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #ifndef STRING_BUILDER_INL_H_
  2. #error "Direct inclusion of this file is not allowed, include string.h"
  3. // For the sake of sane code completion.
  4. #include "string_builder.h"
  5. #endif
  6. #include <library/cpp/yt/assert/assert.h>
  7. namespace NYT {
  8. ////////////////////////////////////////////////////////////////////////////////
  9. inline char* TStringBuilderBase::Preallocate(size_t size)
  10. {
  11. Reserve(size + GetLength());
  12. return Current_;
  13. }
  14. inline void TStringBuilderBase::Reserve(size_t size)
  15. {
  16. if (Y_UNLIKELY(End_ - Begin_ < static_cast<ssize_t>(size))) {
  17. size_t length = GetLength();
  18. auto newLength = std::max(size, MinBufferLength);
  19. DoReserve(newLength);
  20. Current_ = Begin_ + length;
  21. }
  22. }
  23. inline size_t TStringBuilderBase::GetLength() const
  24. {
  25. return Current_ ? Current_ - Begin_ : 0;
  26. }
  27. inline TStringBuf TStringBuilderBase::GetBuffer() const
  28. {
  29. return TStringBuf(Begin_, Current_);
  30. }
  31. inline void TStringBuilderBase::Advance(size_t size)
  32. {
  33. Current_ += size;
  34. YT_ASSERT(Current_ <= End_);
  35. }
  36. inline void TStringBuilderBase::AppendChar(char ch)
  37. {
  38. *Preallocate(1) = ch;
  39. Advance(1);
  40. }
  41. inline void TStringBuilderBase::AppendChar(char ch, int n)
  42. {
  43. YT_ASSERT(n >= 0);
  44. if (Y_LIKELY(0 != n)) {
  45. char* dst = Preallocate(n);
  46. ::memset(dst, ch, n);
  47. Advance(n);
  48. }
  49. }
  50. inline void TStringBuilderBase::AppendString(TStringBuf str)
  51. {
  52. if (Y_LIKELY(str)) {
  53. char* dst = Preallocate(str.length());
  54. ::memcpy(dst, str.begin(), str.length());
  55. Advance(str.length());
  56. }
  57. }
  58. inline void TStringBuilderBase::AppendString(const char* str)
  59. {
  60. AppendString(TStringBuf(str));
  61. }
  62. inline void TStringBuilderBase::Reset()
  63. {
  64. Begin_ = Current_ = End_ = nullptr;
  65. DoReset();
  66. }
  67. template <class... TArgs>
  68. void TStringBuilderBase::AppendFormat(TStringBuf format, TArgs&& ... args)
  69. {
  70. Format(this, format, std::forward<TArgs>(args)...);
  71. }
  72. template <size_t Length, class... TArgs>
  73. void TStringBuilderBase::AppendFormat(const char (&format)[Length], TArgs&& ... args)
  74. {
  75. Format(this, format, std::forward<TArgs>(args)...);
  76. }
  77. ////////////////////////////////////////////////////////////////////////////////
  78. inline TString TStringBuilder::Flush()
  79. {
  80. Buffer_.resize(GetLength());
  81. auto result = std::move(Buffer_);
  82. Reset();
  83. return result;
  84. }
  85. inline void TStringBuilder::DoReset()
  86. {
  87. Buffer_ = {};
  88. }
  89. inline void TStringBuilder::DoReserve(size_t newLength)
  90. {
  91. Buffer_.ReserveAndResize(newLength);
  92. auto capacity = Buffer_.capacity();
  93. Buffer_.ReserveAndResize(capacity);
  94. Begin_ = &*Buffer_.begin();
  95. End_ = Begin_ + capacity;
  96. }
  97. ////////////////////////////////////////////////////////////////////////////////
  98. inline void FormatValue(TStringBuilderBase* builder, const TStringBuilder& value, TStringBuf /*format*/)
  99. {
  100. builder->AppendString(value.GetBuffer());
  101. }
  102. template <class T>
  103. TString ToStringViaBuilder(const T& value, TStringBuf spec)
  104. {
  105. TStringBuilder builder;
  106. FormatValue(&builder, value, spec);
  107. return builder.Flush();
  108. }
  109. ////////////////////////////////////////////////////////////////////////////////
  110. } // namespace NYT