diff --git a/common/internal/BUILD b/common/internal/BUILD index 571f1ef14..99097fb12 100644 --- a/common/internal/BUILD +++ b/common/internal/BUILD @@ -25,7 +25,6 @@ cc_library( "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/base:nullability", "@com_google_absl//absl/functional:overload", - "@com_google_absl//absl/hash", "@com_google_absl//absl/log:absl_check", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:cord", diff --git a/common/internal/byte_string.cc b/common/internal/byte_string.cc index 2b713b7b1..4daaa66a1 100644 --- a/common/internal/byte_string.cc +++ b/common/internal/byte_string.cc @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -24,10 +23,8 @@ #include "absl/base/nullability.h" #include "absl/base/optimization.h" #include "absl/functional/overload.h" -#include "absl/hash/hash.h" #include "absl/log/absl_check.h" #include "absl/strings/cord.h" -#include "absl/strings/match.h" #include "absl/strings/resize_and_overwrite.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" @@ -35,69 +32,6 @@ namespace cel::common_internal { -namespace { - -char* CopyCordToArray(const absl::Cord& cord, size_t offset, size_t size, - char* data) { - for (auto chunk : cord.Chunks()) { - if (size == 0) { - break; - } - if (offset > 0) { - size_t min_offset = std::min(chunk.size(), offset); - offset -= min_offset; - if (offset > 0) { - continue; - } - chunk.remove_prefix(min_offset); - } - size_t min_size = std::min(size, chunk.size()); - std::memcpy(data, chunk.data(), min_size); - data += min_size; - size -= min_size; - } - return data; -} - -char* CopyCordToArray(const absl::Cord& cord, char* data) { - return (CopyCordToArray)(cord, 0, cord.size(), data); -} - -void AppendCordToString(const absl::Cord& cord, size_t offset, size_t size, - std::string& data) { - data.reserve(data.size() + size); - for (auto chunk : cord.Chunks()) { - if (size == 0) { - break; - } - if (offset > 0) { - size_t min_offset = std::min(chunk.size(), offset); - offset -= min_offset; - if (offset > 0) { - continue; - } - chunk.remove_prefix(min_offset); - } - size_t min_size = std::min(size, chunk.size()); - data.append(absl::string_view(chunk.data(), min_size)); - size -= min_size; - } -} - -template -T ConsumeAndDestroy(T& object) { - T consumed = std::move(object); - object.~T(); // NOLINT(bugprone-use-after-move) - return consumed; -} - -} // namespace - -ByteString ByteString::From(const char* absl_nullable value, - google::protobuf::Arena* absl_nonnull arena) { - return From(absl::NullSafeStringView(value), arena); -} - ByteString ByteString::From(absl::string_view value, google::protobuf::Arena* absl_nonnull arena) { ABSL_DCHECK(arena != nullptr); @@ -113,14 +47,15 @@ ByteString ByteString::From(absl::string_view value, return result; } -ByteString ByteString::From(const absl::Cord& value, +ByteString ByteString::From(absl::Cord value, google::protobuf::Arena* absl_nonnull arena) { ABSL_DCHECK(arena != nullptr); ByteString result(UninitializedTag{}); if (value.size() <= kSmallByteStringCapacity) { result.SetSmall(arena, value); } else { - result.SetLarge(arena, google::protobuf::Arena::Create(arena, value)); + result.SetLarge(arena, + google::protobuf::Arena::Create(arena, std::move(value))); } return result; } @@ -144,29 +79,6 @@ ByteString ByteString::From(std::string&& value, return result; } -ByteString ByteString::Wrap(absl::string_view value, - google::protobuf::Arena* absl_nullable arena) { - ByteString result(UninitializedTag{}); - result.SetMedium(arena, value); - return result; -} - -ByteString ByteString::Wrap(const absl::Cord* absl_nonnull value, size_t offset, - size_t size, google::protobuf::Arena* absl_nullable arena) { - ByteString result(UninitializedTag{}); - result.SetLarge(arena, value, offset, size); - return result; -} - -ByteString ByteString::WrapUnsafe(absl::string_view value) { - return Wrap(value, static_cast(nullptr)); -} - -ByteString ByteString::WrapUnsafe(const absl::Cord* absl_nonnull value, - size_t offset, size_t size) { - return Wrap(value, offset, size, static_cast(nullptr)); -} - ByteString ByteString::Concat(const ByteString& lhs, const ByteString& rhs, google::protobuf::Arena* absl_nonnull arena) { ABSL_DCHECK(arena != nullptr); @@ -212,39 +124,6 @@ ByteString ByteString::Concat(const ByteString& lhs, const ByteString& rhs, return result; } -google::protobuf::Arena* absl_nullable ByteString::GetArena() const { - switch (GetKind()) { - case ByteStringKind::kSmall: - return GetSmallArena(); - case ByteStringKind::kMedium: - return GetMediumArena(); - case ByteStringKind::kLarge: - return GetLargeArena(); - } -} - -bool ByteString::empty() const { - switch (GetKind()) { - case ByteStringKind::kSmall: - return rep_.small.size == 0; - case ByteStringKind::kMedium: - return rep_.medium.size == 0; - case ByteStringKind::kLarge: - return rep_.large.size == 0; - } -} - -size_t ByteString::size() const { - switch (GetKind()) { - case ByteStringKind::kSmall: - return rep_.small.size; - case ByteStringKind::kMedium: - return rep_.medium.size; - case ByteStringKind::kLarge: - return rep_.large.size; - } -} - absl::optional ByteString::TryFlat() const { switch (GetKind()) { case ByteStringKind::kSmall: @@ -260,63 +139,6 @@ absl::optional ByteString::TryFlat() const { } } -bool ByteString::Equals(absl::string_view rhs) const { - return Visit(absl::Overload( - [&rhs](absl::string_view lhs) -> bool { return lhs == rhs; }, - [&rhs](const absl::Cord& lhs) -> bool { return lhs == rhs; })); -} - -bool ByteString::Equals(const absl::Cord& rhs) const { - return Visit(absl::Overload( - [&rhs](absl::string_view lhs) -> bool { return lhs == rhs; }, - [&rhs](const absl::Cord& lhs) -> bool { return lhs == rhs; })); -} - -int ByteString::Compare(absl::string_view rhs) const { - return Visit(absl::Overload( - [&rhs](absl::string_view lhs) -> int { return lhs.compare(rhs); }, - [&rhs](const absl::Cord& lhs) -> int { return lhs.Compare(rhs); })); -} - -int ByteString::Compare(const absl::Cord& rhs) const { - return Visit(absl::Overload( - [&rhs](absl::string_view lhs) -> int { return -rhs.Compare(lhs); }, - [&rhs](const absl::Cord& lhs) -> int { return lhs.Compare(rhs); })); -} - -bool ByteString::StartsWith(absl::string_view rhs) const { - return Visit(absl::Overload( - [&rhs](absl::string_view lhs) -> bool { - return absl::StartsWith(lhs, rhs); - }, - [&rhs](const absl::Cord& lhs) -> bool { return lhs.StartsWith(rhs); })); -} - -bool ByteString::StartsWith(const absl::Cord& rhs) const { - return Visit(absl::Overload( - [&rhs](absl::string_view lhs) -> bool { - return lhs.size() >= rhs.size() && lhs.substr(0, rhs.size()) == rhs; - }, - [&rhs](const absl::Cord& lhs) -> bool { return lhs.StartsWith(rhs); })); -} - -bool ByteString::EndsWith(absl::string_view rhs) const { - return Visit(absl::Overload( - [&rhs](absl::string_view lhs) -> bool { - return absl::EndsWith(lhs, rhs); - }, - [&rhs](const absl::Cord& lhs) -> bool { return lhs.EndsWith(rhs); })); -} - -bool ByteString::EndsWith(const absl::Cord& rhs) const { - return Visit(absl::Overload( - [&rhs](absl::string_view lhs) -> bool { - return lhs.size() >= rhs.size() && - lhs.substr(lhs.size() - rhs.size()) == rhs; - }, - [&rhs](const absl::Cord& lhs) -> bool { return lhs.EndsWith(rhs); })); -} - absl::optional ByteString::Find(absl::string_view needle, size_t pos) const { ABSL_DCHECK_LE(pos, size()); @@ -505,8 +327,8 @@ void ByteString::CopyToString(std::string* absl_nonnull out) const { absl::StringResizeAndOverwrite( *out, rep_.large.size, [this](char* buffer, size_t buffer_size) -> size_t { - (CopyCordToArray)(*rep_.large.data, rep_.large.offset, - rep_.large.size, buffer); + CopyCordToArray(*rep_.large.data, rep_.large.offset, + rep_.large.size, buffer); return rep_.large.size; }); break; @@ -523,24 +345,13 @@ void ByteString::AppendToString(std::string* absl_nonnull out) const { out->append(GetMedium()); break; case ByteStringKind::kLarge: - (AppendCordToString)(*rep_.large.data, rep_.large.offset, rep_.large.size, - *out); + AppendCordToString(*rep_.large.data, rep_.large.offset, rep_.large.size, + *out); break; } } -absl::Cord ByteString::ToCord() const& { - switch (GetKind()) { - case ByteStringKind::kSmall: - return absl::Cord(GetSmall()); - case ByteStringKind::kMedium: - return absl::Cord(GetMedium()); - case ByteStringKind::kLarge: - return GetLarge(); - } -} - -absl::Cord ByteString::ToCord() && { +absl::Cord ByteString::ToCord() const { switch (GetKind()) { case ByteStringKind::kSmall: return absl::Cord(GetSmall()); @@ -596,28 +407,14 @@ absl::string_view ByteString::ToStringView( absl::StringResizeAndOverwrite( *scratch, rep_.large.size, [this](char* buffer, size_t buffer_size) -> size_t { - (CopyCordToArray)(*rep_.large.data, rep_.large.offset, - rep_.large.size, buffer); + CopyCordToArray(*rep_.large.data, rep_.large.offset, + rep_.large.size, buffer); return rep_.large.size; }); return absl::string_view(*scratch); } } -absl::string_view ByteString::AsStringView() const { - const ByteStringKind kind = GetKind(); - ABSL_CHECK(kind == ByteStringKind::kSmall || // Crash OK - kind == ByteStringKind::kMedium); - switch (kind) { - case ByteStringKind::kSmall: - return GetSmall(); - case ByteStringKind::kMedium: - return GetMedium(); - case ByteStringKind::kLarge: - ABSL_UNREACHABLE(); - } -} - ByteString ByteString::Clone(google::protobuf::Arena* absl_nonnull arena) const { ABSL_DCHECK(arena != nullptr); switch (GetKind()) { @@ -643,63 +440,38 @@ ByteString ByteString::Clone(google::protobuf::Arena* absl_nonnull arena) const } } -void ByteString::HashValue(absl::HashState state) const { - switch (GetKind()) { - case ByteStringKind::kSmall: - absl::HashState::combine(std::move(state), GetSmall()); - break; - case ByteStringKind::kMedium: - absl::HashState::combine(std::move(state), GetMedium()); - break; - case ByteStringKind::kLarge: - absl::HashState::combine(std::move(state), GetLarge()); +void ByteString::CopyCordToArray(const absl::Cord& cord, size_t offset, + size_t size, char* data) { + for (auto chunk : cord.Chunks()) { + if (size == 0) { break; + } + if (offset > 0) { + size_t min_offset = std::min(chunk.size(), offset); + offset -= min_offset; + if (offset > 0) { + continue; + } + chunk.remove_prefix(min_offset); + } + size_t min_size = std::min(size, chunk.size()); + std::memcpy(data, chunk.data(), min_size); + data += min_size; + size -= min_size; } } -void ByteString::SetSmall(google::protobuf::Arena* absl_nullable arena, - absl::string_view string) { - ABSL_DCHECK_LE(string.size(), kSmallByteStringCapacity); - rep_.header.kind = ByteStringKind::kSmall; - rep_.small.size = string.size(); - rep_.small.arena = arena; - if (!string.empty()) { - std::memcpy(rep_.small.data, string.data(), rep_.small.size); - } -} - -void ByteString::SetSmall(google::protobuf::Arena* absl_nullable arena, - const absl::Cord& cord) { - ABSL_DCHECK_LE(cord.size(), kSmallByteStringCapacity); - rep_.header.kind = ByteStringKind::kSmall; - rep_.small.size = cord.size(); - rep_.small.arena = arena; - (CopyCordToArray)(cord, rep_.small.data); -} - -void ByteString::SetMedium(google::protobuf::Arena* absl_nullable arena, - absl::string_view string) { - rep_.header.kind = ByteStringKind::kMedium; - rep_.medium.size = string.size(); - rep_.medium.data = string.data(); - rep_.medium.arena = arena; -} - -void ByteString::SetLarge(google::protobuf::Arena* absl_nullable arena, - const absl::Cord* absl_nonnull cord, size_t offset, - size_t size) { - ABSL_DCHECK_LE(offset, cord->size()); - ABSL_DCHECK_LE(offset, kLargeByteStringMaxSize); - rep_.header.kind = ByteStringKind::kLarge; - rep_.large.offset = offset; - if (size == static_cast(-1)) { - size = cord->size() - offset; - } - ABSL_DCHECK_LE(size, cord->size() - offset); - ABSL_DCHECK_LE(size, kLargeByteStringMaxSize); - rep_.large.size = size; - rep_.large.data = cord; - rep_.large.arena = arena; +void ByteString::AppendCordToString(const absl::Cord& cord, size_t offset, + size_t size, std::string& data) { + size_t original_size = data.size(); + size_t target_size = original_size + size; + absl::StringResizeAndOverwrite( + data, original_size + size, + [&cord, offset, size, original_size, target_size]( + char* buf, size_t buf_size) -> size_t { + CopyCordToArray(cord, offset, size, buf + original_size); + return target_size; + }); } absl::string_view LegacyByteString(const ByteString& string, bool stable, diff --git a/common/internal/byte_string.h b/common/internal/byte_string.h index de11f8a9e..6027d08ec 100644 --- a/common/internal/byte_string.h +++ b/common/internal/byte_string.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -25,9 +26,9 @@ #include "absl/base/attributes.h" #include "absl/base/nullability.h" #include "absl/functional/overload.h" -#include "absl/hash/hash.h" #include "absl/log/absl_check.h" #include "absl/strings/cord.h" +#include "absl/strings/match.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "google/protobuf/arena.h" @@ -161,20 +162,25 @@ class [[nodiscard]] ByteString final { public: static ByteString From(const char* absl_nullable value, google::protobuf::Arena* absl_nonnull arena - ABSL_ATTRIBUTE_LIFETIME_BOUND); + ABSL_ATTRIBUTE_LIFETIME_BOUND) { + return From(absl::NullSafeStringView(value), arena); + } static ByteString From(absl::string_view value, google::protobuf::Arena* absl_nonnull arena ABSL_ATTRIBUTE_LIFETIME_BOUND); - static ByteString From(const absl::Cord& value, - google::protobuf::Arena* absl_nonnull arena - ABSL_ATTRIBUTE_LIFETIME_BOUND); + static ByteString From(absl::Cord value, google::protobuf::Arena* absl_nonnull arena + ABSL_ATTRIBUTE_LIFETIME_BOUND); static ByteString From(std::string&& value, google::protobuf::Arena* absl_nonnull arena ABSL_ATTRIBUTE_LIFETIME_BOUND); static ByteString Wrap(absl::string_view value, google::protobuf::Arena* absl_nullable arena - ABSL_ATTRIBUTE_LIFETIME_BOUND); + ABSL_ATTRIBUTE_LIFETIME_BOUND) { + ByteString result(UninitializedTag{}); + result.SetMedium(arena, value); + return result; + } static ByteString Wrap( const absl::Cord* absl_nonnull value ABSL_ATTRIBUTE_LIFETIME_BOUND, google::protobuf::Arena* absl_nullable arena ABSL_ATTRIBUTE_LIFETIME_BOUND) { @@ -183,18 +189,26 @@ class [[nodiscard]] ByteString final { static ByteString Wrap( const absl::Cord* absl_nonnull value ABSL_ATTRIBUTE_LIFETIME_BOUND, size_t offset, size_t size, - google::protobuf::Arena* absl_nullable arena ABSL_ATTRIBUTE_LIFETIME_BOUND); + google::protobuf::Arena* absl_nullable arena ABSL_ATTRIBUTE_LIFETIME_BOUND) { + ByteString result(UninitializedTag{}); + result.SetLarge(arena, value, offset, size); + return result; + } static ByteString Wrap(std::nullptr_t, google::protobuf::Arena*) = delete; static ByteString Wrap(std::nullptr_t, size_t, size_t, google::protobuf::Arena*) = delete; static ByteString Wrap(std::string&& value, google::protobuf::Arena*) = delete; - static ByteString WrapUnsafe(absl::string_view value); + static ByteString WrapUnsafe(absl::string_view value) { + return Wrap(value, static_cast(nullptr)); + } static ByteString WrapUnsafe(const absl::Cord* absl_nonnull value) { return WrapUnsafe(value, 0, value->size()); } static ByteString WrapUnsafe(const absl::Cord* absl_nonnull value, - size_t offset, size_t size); + size_t offset, size_t size) { + return Wrap(value, offset, size, static_cast(nullptr)); + } static ByteString WrapUnsafe(std::nullptr_t) = delete; static ByteString WrapUnsafe(std::nullptr_t, size_t, size_t) = delete; @@ -208,9 +222,27 @@ class [[nodiscard]] ByteString final { ByteString& operator=(const ByteString&) = default; ByteString& operator=(ByteString&&) = default; - bool empty() const; + bool empty() const { + switch (GetKind()) { + case ByteStringKind::kSmall: + return rep_.small.size == 0; + case ByteStringKind::kMedium: + return rep_.medium.size == 0; + case ByteStringKind::kLarge: + return rep_.large.size == 0; + } + } - size_t size() const; + size_t size() const { + switch (GetKind()) { + case ByteStringKind::kSmall: + return rep_.small.size; + case ByteStringKind::kMedium: + return rep_.medium.size; + case ByteStringKind::kLarge: + return rep_.large.size; + } + } size_t max_size() const { return kByteStringViewMaxSize; } @@ -261,9 +293,7 @@ class [[nodiscard]] ByteString final { void AppendToString(std::string* absl_nonnull out) const; - absl::Cord ToCord() const&; - - absl::Cord ToCord() &&; + absl::Cord ToCord() const; void CopyToCord(absl::Cord* absl_nonnull out) const; @@ -273,24 +303,25 @@ class [[nodiscard]] ByteString final { std::string* absl_nonnull scratch ABSL_ATTRIBUTE_LIFETIME_BOUND) const ABSL_ATTRIBUTE_LIFETIME_BOUND; - absl::string_view AsStringView() const ABSL_ATTRIBUTE_LIFETIME_BOUND; - - google::protobuf::Arena* absl_nullable GetArena() const; + google::protobuf::Arena* absl_nullable GetArena() const { + switch (GetKind()) { + case ByteStringKind::kSmall: + return GetSmallArena(); + case ByteStringKind::kMedium: + return GetMediumArena(); + case ByteStringKind::kLarge: + return GetLargeArena(); + } + } ByteString Clone(google::protobuf::Arena* absl_nonnull arena) const; - void HashValue(absl::HashState state) const; - template decltype(auto) Visit(Visitor&& visitor) const { - switch (GetKind()) { - case ByteStringKind::kSmall: - return std::forward(visitor)(GetSmall()); - case ByteStringKind::kMedium: - return std::forward(visitor)(GetMedium()); - case ByteStringKind::kLarge: - return std::forward(visitor)(GetLarge()); + if (auto string_view = AsStringView(); string_view) { + return std::forward(visitor)(*string_view); } + return std::forward(visitor)(GetLarge()); } friend void swap(ByteString& lhs, ByteString& rhs) noexcept { @@ -300,8 +331,10 @@ class [[nodiscard]] ByteString final { template friend H AbslHashValue(H state, const ByteString& byte_string) { - byte_string.HashValue(absl::HashState::Create(&state)); - return state; + if (auto string_view = byte_string.AsStringView(); string_view) { + return H::combine(std::move(state), *string_view); + } + return H::combine(std::move(state), byte_string.GetLarge()); } private: @@ -386,11 +419,30 @@ class [[nodiscard]] ByteString final { rep_.small.arena = arena; } - void SetSmall(google::protobuf::Arena* absl_nullable arena, absl::string_view string); + void SetSmall(google::protobuf::Arena* absl_nullable arena, absl::string_view string) { + ABSL_DCHECK_LE(string.size(), kSmallByteStringCapacity); + rep_.header.kind = ByteStringKind::kSmall; + rep_.small.size = string.size(); + rep_.small.arena = arena; + if (!string.empty()) { + std::memcpy(rep_.small.data, string.data(), rep_.small.size); + } + } - void SetSmall(google::protobuf::Arena* absl_nullable arena, const absl::Cord& cord); + void SetSmall(google::protobuf::Arena* absl_nullable arena, const absl::Cord& cord) { + ABSL_DCHECK_LE(cord.size(), kSmallByteStringCapacity); + rep_.header.kind = ByteStringKind::kSmall; + rep_.small.size = cord.size(); + rep_.small.arena = arena; + CopyCordToArray(cord, rep_.small.data); + } - void SetMedium(google::protobuf::Arena* absl_nullable arena, absl::string_view string); + void SetMedium(google::protobuf::Arena* absl_nullable arena, absl::string_view string) { + rep_.header.kind = ByteStringKind::kMedium; + rep_.medium.size = string.size(); + rep_.medium.data = string.data(); + rep_.medium.arena = arena; + } void SetMedium(google::protobuf::Arena* absl_nullable arena, const std::string* absl_nonnull string) { @@ -399,31 +451,125 @@ class [[nodiscard]] ByteString final { void SetLarge(google::protobuf::Arena* absl_nullable arena, const absl::Cord* absl_nonnull cord, size_t offset = 0, - size_t size = static_cast(-1)); + size_t size = static_cast(-1)) { + ABSL_DCHECK_LE(offset, cord->size()); + ABSL_DCHECK_LE(offset, kLargeByteStringMaxSize); + rep_.header.kind = ByteStringKind::kLarge; + rep_.large.offset = offset; + if (size == static_cast(-1)) { + size = cord->size() - offset; + } + ABSL_DCHECK_LE(size, cord->size() - offset); + ABSL_DCHECK_LE(size, kLargeByteStringMaxSize); + rep_.large.size = size; + rep_.large.data = cord; + rep_.large.arena = arena; + } + + static void CopyCordToArray(const absl::Cord& cord, char* data) { + for (absl::string_view chunk : cord.Chunks()) { + std::memcpy(data, chunk.data(), chunk.size()); + data += chunk.size(); + } + } + + static void CopyCordToArray(const absl::Cord& cord, size_t offset, + size_t size, char* data); + + static void AppendCordToString(const absl::Cord& cord, size_t offset, + size_t size, std::string& data); void CopyToArray(char* absl_nonnull out) const; + std::optional AsStringView() const { + switch (GetKind()) { + case ByteStringKind::kSmall: + return GetSmall(); + case ByteStringKind::kMedium: + return GetMedium(); + case ByteStringKind::kLarge: + return std::nullopt; + } + } + ByteStringRep rep_; }; +inline bool ByteString::Equals(absl::string_view rhs) const { + return Visit(absl::Overload( + [&rhs](absl::string_view lhs) -> bool { return lhs == rhs; }, + [&rhs](const absl::Cord& lhs) -> bool { return lhs == rhs; })); +} + +inline bool ByteString::Equals(const absl::Cord& rhs) const { + return Visit(absl::Overload( + [&rhs](absl::string_view lhs) -> bool { return lhs == rhs; }, + [&rhs](const absl::Cord& lhs) -> bool { return lhs == rhs; })); +} + inline bool ByteString::Equals(const ByteString& rhs) const { return rhs.Visit(absl::Overload( [this](absl::string_view rhs) -> bool { return Equals(rhs); }, [this](const absl::Cord& rhs) -> bool { return Equals(rhs); })); } +inline int ByteString::Compare(absl::string_view rhs) const { + return Visit(absl::Overload( + [&rhs](absl::string_view lhs) -> int { return lhs.compare(rhs); }, + [&rhs](const absl::Cord& lhs) -> int { return lhs.Compare(rhs); })); +} + +inline int ByteString::Compare(const absl::Cord& rhs) const { + return Visit(absl::Overload( + [&rhs](absl::string_view lhs) -> int { return -rhs.Compare(lhs); }, + [&rhs](const absl::Cord& lhs) -> int { return lhs.Compare(rhs); })); +} + inline int ByteString::Compare(const ByteString& rhs) const { return rhs.Visit(absl::Overload( [this](absl::string_view rhs) -> int { return Compare(rhs); }, [this](const absl::Cord& rhs) -> int { return Compare(rhs); })); } +inline bool ByteString::StartsWith(absl::string_view rhs) const { + return Visit(absl::Overload( + [&rhs](absl::string_view lhs) -> bool { + return absl::StartsWith(lhs, rhs); + }, + [&rhs](const absl::Cord& lhs) -> bool { return lhs.StartsWith(rhs); })); +} + +inline bool ByteString::StartsWith(const absl::Cord& rhs) const { + return Visit(absl::Overload( + [&rhs](absl::string_view lhs) -> bool { + return lhs.size() >= rhs.size() && lhs.substr(0, rhs.size()) == rhs; + }, + [&rhs](const absl::Cord& lhs) -> bool { return lhs.StartsWith(rhs); })); +} + inline bool ByteString::StartsWith(const ByteString& rhs) const { return rhs.Visit(absl::Overload( [this](absl::string_view rhs) -> bool { return StartsWith(rhs); }, [this](const absl::Cord& rhs) -> bool { return StartsWith(rhs); })); } +inline bool ByteString::EndsWith(absl::string_view rhs) const { + return Visit(absl::Overload( + [&rhs](absl::string_view lhs) -> bool { + return absl::EndsWith(lhs, rhs); + }, + [&rhs](const absl::Cord& lhs) -> bool { return lhs.EndsWith(rhs); })); +} + +inline bool ByteString::EndsWith(const absl::Cord& rhs) const { + return Visit(absl::Overload( + [&rhs](absl::string_view lhs) -> bool { + return lhs.size() >= rhs.size() && + lhs.substr(lhs.size() - rhs.size()) == rhs; + }, + [&rhs](const absl::Cord& lhs) -> bool { return lhs.EndsWith(rhs); })); +} + inline bool ByteString::EndsWith(const ByteString& rhs) const { return rhs.Visit(absl::Overload( [this](absl::string_view rhs) -> bool { return EndsWith(rhs); }, diff --git a/common/internal/byte_string_test.cc b/common/internal/byte_string_test.cc index b2353ac2d..121158ada 100644 --- a/common/internal/byte_string_test.cc +++ b/common/internal/byte_string_test.cc @@ -43,7 +43,6 @@ using ::testing::IsEmpty; using ::testing::Not; using ::testing::Optional; using ::testing::SizeIs; -using ::testing::TestWithParam; TEST(ByteStringKind, Ostream) { { @@ -496,21 +495,6 @@ TEST_F(ByteStringTest, ToStringViewLarge) { EXPECT_EQ(byte_string.ToStringView(&scratch), GetMediumOrLargeCord()); } -TEST_F(ByteStringTest, AsStringViewSmall) { - ByteString byte_string = ByteString::WrapUnsafe(GetSmallStringView()); - EXPECT_EQ(byte_string.AsStringView(), GetSmallStringView()); -} - -TEST_F(ByteStringTest, AsStringViewMedium) { - ByteString byte_string = ByteString::WrapUnsafe(GetMediumStringView()); - EXPECT_EQ(byte_string.AsStringView(), GetMediumStringView()); -} - -TEST_F(ByteStringTest, AsStringViewLarge) { - ByteString byte_string = ByteString::WrapUnsafe(&GetMediumOrLargeCord()); - EXPECT_DEATH(byte_string.AsStringView(), _); -} - TEST_F(ByteStringTest, CopyToStringSmall) { std::string out; diff --git a/common/values/bytes_value.cc b/common/values/bytes_value.cc index c9fc32ac2..5c57bd740 100644 --- a/common/values/bytes_value.cc +++ b/common/values/bytes_value.cc @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include #include #include "google/protobuf/wrappers.pb.h" @@ -123,72 +122,4 @@ absl::Status BytesValue::Equal( return absl::OkStatus(); } -BytesValue BytesValue::Clone(google::protobuf::Arena* absl_nonnull arena) const { - return BytesValue(value_.Clone(arena)); -} - -size_t BytesValue::Size() const { - return NativeValue( - [](const auto& alternative) -> size_t { return alternative.size(); }); -} - -bool BytesValue::IsEmpty() const { - return NativeValue( - [](const auto& alternative) -> bool { return alternative.empty(); }); -} - -bool BytesValue::Equals(absl::string_view bytes) const { - return NativeValue([bytes](const auto& alternative) -> bool { - return alternative == bytes; - }); -} - -bool BytesValue::Equals(const absl::Cord& bytes) const { - return NativeValue([&bytes](const auto& alternative) -> bool { - return alternative == bytes; - }); -} - -bool BytesValue::Equals(const BytesValue& bytes) const { - return bytes.NativeValue( - [this](const auto& alternative) -> bool { return Equals(alternative); }); -} - -namespace { - -int CompareImpl(absl::string_view lhs, absl::string_view rhs) { - return lhs.compare(rhs); -} - -int CompareImpl(absl::string_view lhs, const absl::Cord& rhs) { - return -rhs.Compare(lhs); -} - -int CompareImpl(const absl::Cord& lhs, absl::string_view rhs) { - return lhs.Compare(rhs); -} - -int CompareImpl(const absl::Cord& lhs, const absl::Cord& rhs) { - return lhs.Compare(rhs); -} - -} // namespace - -int BytesValue::Compare(absl::string_view bytes) const { - return NativeValue([bytes](const auto& alternative) -> int { - return CompareImpl(alternative, bytes); - }); -} - -int BytesValue::Compare(const absl::Cord& bytes) const { - return NativeValue([&bytes](const auto& alternative) -> int { - return CompareImpl(alternative, bytes); - }); -} - -int BytesValue::Compare(const BytesValue& bytes) const { - return bytes.NativeValue( - [this](const auto& alternative) -> int { return Compare(alternative); }); -} - } // namespace cel diff --git a/common/values/bytes_value.h b/common/values/bytes_value.h index 461e5d8c6..42be2120e 100644 --- a/common/values/bytes_value.h +++ b/common/values/bytes_value.h @@ -138,11 +138,11 @@ class BytesValue final : private common_internal::ValueMixin { Value* absl_nonnull result) const; using ValueMixin::Equal; - bool IsZeroValue() const { - return NativeValue([](const auto& value) -> bool { return value.empty(); }); - } + bool IsZeroValue() const { return value_.empty(); } - BytesValue Clone(google::protobuf::Arena* absl_nonnull arena) const; + BytesValue Clone(google::protobuf::Arena* absl_nonnull arena) const { + return BytesValue(value_.Clone(arena)); + } ABSL_DEPRECATED("Use ToString()") std::string NativeString() const { return value_.ToString(); } @@ -172,17 +172,21 @@ class BytesValue final : private common_internal::ValueMixin { swap(lhs.value_, rhs.value_); } - size_t Size() const; + size_t Size() const { return value_.size(); } - bool IsEmpty() const; + bool IsEmpty() const { return value_.empty(); } - bool Equals(absl::string_view bytes) const; - bool Equals(const absl::Cord& bytes) const; - bool Equals(const BytesValue& bytes) const; + bool Equals(absl::string_view bytes) const { return value_.Equals(bytes); } + bool Equals(const absl::Cord& bytes) const { return value_.Equals(bytes); } + bool Equals(const BytesValue& bytes) const { + return value_.Equals(bytes.value_); + } - int Compare(absl::string_view bytes) const; - int Compare(const absl::Cord& bytes) const; - int Compare(const BytesValue& bytes) const; + int Compare(absl::string_view bytes) const { return value_.Compare(bytes); } + int Compare(const absl::Cord& bytes) const { return value_.Compare(bytes); } + int Compare(const BytesValue& bytes) const { + return value_.Compare(bytes.value_); + } absl::optional TryFlat() const ABSL_ATTRIBUTE_LIFETIME_BOUND { diff --git a/common/values/string_value.cc b/common/values/string_value.cc index 053a456bd..6aa7ac543 100644 --- a/common/values/string_value.cc +++ b/common/values/string_value.cc @@ -138,68 +138,11 @@ absl::Status StringValue::Equal( } size_t StringValue::Size() const { - return NativeValue([](const auto& alternative) -> size_t { + return value_.Visit([](const auto& alternative) -> size_t { return internal::Utf8CodePointCount(alternative); }); } -bool StringValue::IsEmpty() const { - return NativeValue( - [](const auto& alternative) -> bool { return alternative.empty(); }); -} - -bool StringValue::Equals(absl::string_view string) const { - return value_.Equals(string); -} - -bool StringValue::Equals(const absl::Cord& string) const { - return value_.Equals(string); -} - -bool StringValue::Equals(const StringValue& string) const { - return value_.Equals(string.value_); -} - -StringValue StringValue::Clone(google::protobuf::Arena* absl_nonnull arena) const { - return StringValue(value_.Clone(arena)); -} - -int StringValue::Compare(absl::string_view string) const { - return value_.Compare(string); -} - -int StringValue::Compare(const absl::Cord& string) const { - return value_.Compare(string); -} - -int StringValue::Compare(const StringValue& string) const { - return value_.Compare(string.value_); -} - -bool StringValue::StartsWith(absl::string_view string) const { - return value_.StartsWith(string); -} - -bool StringValue::StartsWith(const absl::Cord& string) const { - return value_.StartsWith(string); -} - -bool StringValue::StartsWith(const StringValue& string) const { - return value_.StartsWith(string.value_); -} - -bool StringValue::EndsWith(absl::string_view string) const { - return value_.EndsWith(string); -} - -bool StringValue::EndsWith(const absl::Cord& string) const { - return value_.EndsWith(string); -} - -bool StringValue::EndsWith(const StringValue& string) const { - return value_.EndsWith(string.value_); -} - bool StringValue::Contains(absl::string_view string) const { return value_.Visit(absl::Overload( [&](absl::string_view lhs) -> bool { diff --git a/common/values/string_value.h b/common/values/string_value.h index 98ca43234..0959cc556 100644 --- a/common/values/string_value.h +++ b/common/values/string_value.h @@ -27,6 +27,7 @@ #include "absl/base/attributes.h" #include "absl/base/nullability.h" +#include "absl/log/absl_check.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/cord.h" @@ -174,12 +175,12 @@ class StringValue final : private common_internal::ValueMixin { Value* absl_nonnull result) const; using ValueMixin::Equal; - StringValue Clone(google::protobuf::Arena* absl_nonnull arena) const; - - bool IsZeroValue() const { - return NativeValue([](const auto& value) -> bool { return value.empty(); }); + StringValue Clone(google::protobuf::Arena* absl_nonnull arena) const { + return StringValue(value_.Clone(arena)); } + bool IsZeroValue() const { return value_.empty(); } + ABSL_DEPRECATED("Use ToString()") std::string NativeString() const { return value_.ToString(); } @@ -210,23 +211,39 @@ class StringValue final : private common_internal::ValueMixin { size_t Size() const; - bool IsEmpty() const; + bool IsEmpty() const { return value_.empty(); } - bool Equals(absl::string_view string) const; - bool Equals(const absl::Cord& string) const; - bool Equals(const StringValue& string) const; + bool Equals(absl::string_view string) const { return value_.Equals(string); } + bool Equals(const absl::Cord& string) const { return value_.Equals(string); } + bool Equals(const StringValue& string) const { + return value_.Equals(string.value_); + } - int Compare(absl::string_view string) const; - int Compare(const absl::Cord& string) const; - int Compare(const StringValue& string) const; + int Compare(absl::string_view string) const { return value_.Compare(string); } + int Compare(const absl::Cord& string) const { return value_.Compare(string); } + int Compare(const StringValue& string) const { + return value_.Compare(string.value_); + } - bool StartsWith(absl::string_view string) const; - bool StartsWith(const absl::Cord& string) const; - bool StartsWith(const StringValue& string) const; + bool StartsWith(absl::string_view string) const { + return value_.StartsWith(string); + } + bool StartsWith(const absl::Cord& string) const { + return value_.StartsWith(string); + } + bool StartsWith(const StringValue& string) const { + return value_.StartsWith(string.value_); + } - bool EndsWith(absl::string_view string) const; - bool EndsWith(const absl::Cord& string) const; - bool EndsWith(const StringValue& string) const; + bool EndsWith(absl::string_view string) const { + return value_.EndsWith(string); + } + bool EndsWith(const absl::Cord& string) const { + return value_.EndsWith(string); + } + bool EndsWith(const StringValue& string) const { + return value_.EndsWith(string.value_); + } bool Contains(absl::string_view string) const; bool Contains(const absl::Cord& string) const;