string_builder-inl.h 2.8 KB

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