udf_string_ref.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #pragma once
  2. #include "udf_type_size_check.h"
  3. #include <util/generic/strbuf.h>
  4. #include <algorithm>
  5. #include <string_view>
  6. #include <type_traits>
  7. namespace NYql {
  8. namespace NUdf {
  9. //////////////////////////////////////////////////////////////////////////////
  10. // TStringRefBase
  11. //////////////////////////////////////////////////////////////////////////////
  12. template<bool Const>
  13. class TStringRefBase
  14. {
  15. public:
  16. typedef std::conditional_t<Const, const char*, char*> TDataType;
  17. protected:
  18. inline constexpr TStringRefBase() noexcept = default;
  19. inline constexpr TStringRefBase(TDataType data, ui32 size) noexcept
  20. : Data_(data)
  21. , Size_(size)
  22. {}
  23. public:
  24. inline constexpr operator std::string_view() const noexcept { return { Data_, Size_ }; }
  25. inline constexpr operator TStringBuf() const noexcept { return { Data_, Size_ }; }
  26. inline constexpr TDataType Data() const noexcept { return Data_; }
  27. inline constexpr ui32 Size() const noexcept { return Size_; }
  28. inline constexpr bool Empty() const noexcept { return Size_ == 0; }
  29. inline constexpr TDataType data() const noexcept { return Data_; }
  30. inline constexpr ui32 size() const noexcept { return Size_; }
  31. inline constexpr bool empty() const noexcept { return Size_ == 0; }
  32. protected:
  33. TDataType Data_ = nullptr;
  34. ui32 Size_ = 0U;
  35. ui8 Reserved_[4] = {};
  36. };
  37. //////////////////////////////////////////////////////////////////////////////
  38. // TMutableStringRef
  39. //////////////////////////////////////////////////////////////////////////////
  40. class TMutableStringRef : public TStringRefBase<false>
  41. {
  42. public:
  43. typedef TStringRefBase<false> TBase;
  44. inline constexpr TMutableStringRef(TDataType data, ui32 size) noexcept
  45. : TBase(data, size)
  46. {}
  47. };
  48. UDF_ASSERT_TYPE_SIZE(TMutableStringRef, 16);
  49. //////////////////////////////////////////////////////////////////////////////
  50. // TStringRef
  51. //////////////////////////////////////////////////////////////////////////////
  52. class TStringRef : public TStringRefBase<true>
  53. {
  54. public:
  55. typedef TStringRefBase<true> TBase;
  56. inline constexpr TStringRef() noexcept = default;
  57. inline constexpr TStringRef(TDataType data, ui32 size) noexcept
  58. : TBase(data, size)
  59. {}
  60. template<size_t Size>
  61. inline constexpr TStringRef(const char (&data)[Size]) noexcept
  62. : TBase(data, Size - 1)
  63. {}
  64. inline constexpr TStringRef(const TMutableStringRef& buf) noexcept
  65. : TBase(buf.Data(), buf.Size())
  66. {}
  67. template <typename TStringType>
  68. inline constexpr TStringRef(const TStringType& buf) noexcept
  69. : TBase(TGetData<TStringType>::Get(buf), TGetSize<TStringType>::Get(buf))
  70. {}
  71. template <size_t size>
  72. inline static constexpr TStringRef Of(const char(&str)[size]) noexcept {
  73. return TStringRef(str);
  74. }
  75. inline constexpr TStringRef& Trunc(ui32 len) noexcept {
  76. if (Size_ > len) {
  77. Size_ = len;
  78. }
  79. return *this;
  80. }
  81. inline constexpr TStringRef Substring(ui32 start, ui32 count) const noexcept {
  82. start = std::min(start, Size_);
  83. count = std::min(count, Size_ - start);
  84. return TStringRef(Data_ + start, count);
  85. }
  86. inline constexpr bool operator==(const TStringRef& rhs) const noexcept {
  87. return Compare(*this, rhs) == 0;
  88. }
  89. inline constexpr bool operator!=(const TStringRef& rhs) const noexcept {
  90. return Compare(*this, rhs) != 0;
  91. }
  92. inline constexpr bool operator<(const TStringRef& rhs) const noexcept {
  93. return Compare(*this, rhs) < 0;
  94. }
  95. inline constexpr bool operator<=(const TStringRef& rhs) const noexcept {
  96. return Compare(*this, rhs) <= 0;
  97. }
  98. inline constexpr bool operator>(const TStringRef& rhs) const noexcept {
  99. return Compare(*this, rhs) > 0;
  100. }
  101. inline constexpr bool operator>=(const TStringRef& rhs) const noexcept {
  102. return Compare(*this, rhs) >= 0;
  103. }
  104. inline constexpr i64 Compare(const TStringRef& rhs) const noexcept {
  105. return Compare(*this, rhs);
  106. }
  107. private:
  108. inline static constexpr i64 Compare(const TStringRef& s1, const TStringRef& s2) noexcept {
  109. auto minSize = std::min(s1.Size(), s2.Size());
  110. if (const auto result = minSize > 0 ? std::memcmp(s1.Data(), s2.Data(), minSize) : 0)
  111. return result;
  112. return i64(s1.Size()) - i64(s2.Size());
  113. }
  114. Y_HAS_MEMBER(Data);
  115. Y_HAS_MEMBER(Size);
  116. template<typename TStringType>
  117. struct TByData {
  118. static constexpr auto Get(const TStringType& buf) noexcept {
  119. return buf.data();
  120. }
  121. };
  122. template<typename TStringType>
  123. struct TBySize {
  124. static constexpr auto Get(const TStringType& buf) noexcept {
  125. return buf.size();
  126. }
  127. };
  128. template<typename TStringType>
  129. struct TBydata {
  130. static constexpr auto Get(const TStringType& buf) noexcept {
  131. return buf.data();
  132. }
  133. };
  134. template<typename TStringType>
  135. struct TBysize {
  136. static constexpr auto Get(const TStringType& buf) noexcept {
  137. return buf.size();
  138. }
  139. };
  140. template<typename TStringType>
  141. using TGetData = std::conditional_t<THasData<TStringType>::value, TByData<TStringType>, TBydata<TStringType>>;
  142. template<typename TStringType>
  143. using TGetSize = std::conditional_t<THasSize<TStringType>::value, TBySize<TStringType>, TBysize<TStringType>>;
  144. };
  145. UDF_ASSERT_TYPE_SIZE(TStringRef, 16);
  146. } // namspace NUdf
  147. } // namspace NYql