2121#include < cstddef>
2222#include < cstdint>
2323#include < limits>
24- #include < new>
24+ #include < utility>
25+ #include < variant>
2526
26- #include " absl/base/attributes.h"
27- #include " absl/base/nullability.h"
2827#include " absl/log/absl_check.h"
2928#include " absl/strings/cord.h"
3029#include " absl/strings/string_view.h"
31- #include " absl/types/variant.h"
32- #include " absl/utility/utility.h"
3330#include " common/internal/byte_string.h"
3431#include " common/values/bytes_value.h"
3532#include " google/protobuf/io/zero_copy_stream.h"
@@ -39,51 +36,20 @@ namespace cel {
3936
4037class BytesValueInputStream final : public google::protobuf::io::ZeroCopyInputStream {
4138 public:
42- explicit BytesValueInputStream (
43- const BytesValue* absl_nonnull value ABSL_ATTRIBUTE_LIFETIME_BOUND ) {
44- Construct (value);
45- }
46-
47- ~BytesValueInputStream () override { AsVariant ().~variant (); }
39+ explicit BytesValueInputStream (const BytesValue& value) { Construct (value); }
4840
4941 bool Next (const void ** data, int * size) override {
50- return absl::visit (
51- [&data, &size](auto & alternative) -> bool {
52- return alternative.stream .Next (data, size);
53- },
54- AsVariant ());
42+ return stream_->Next (data, size);
5543 }
5644
57- void BackUp (int count) override {
58- absl::visit (
59- [&count](auto & alternative) -> void {
60- alternative.stream .BackUp (count);
61- },
62- AsVariant ());
63- }
45+ void BackUp (int count) override { stream_->BackUp (count); }
6446
65- bool Skip (int count) override {
66- return absl::visit (
67- [&count](auto & alternative) -> bool {
68- return alternative.stream .Skip (count);
69- },
70- AsVariant ());
71- }
47+ bool Skip (int count) override { return stream_->Skip (count); }
7248
73- int64_t ByteCount () const override {
74- return absl::visit (
75- [](const auto & alternative) -> int64_t {
76- return alternative.stream .ByteCount ();
77- },
78- AsVariant ());
79- }
49+ int64_t ByteCount () const override { return stream_->ByteCount (); }
8050
8151 bool ReadCord (absl::Cord* cord, int count) override {
82- return absl::visit (
83- [&cord, &count](auto & alternative) -> bool {
84- return alternative.stream .ReadCord (cord, count);
85- },
86- AsVariant ());
52+ return stream_->ReadCord (cord, count);
8753 }
8854
8955 private:
@@ -93,54 +59,45 @@ class BytesValueInputStream final : public google::protobuf::io::ZeroCopyInputSt
9359 google::protobuf::io::ArrayInputStream stream;
9460 };
9561 struct CordStream {
96- explicit CordStream (const absl::Cord& cord)
97- : cord(cord), stream(&this ->cord) {}
62+ explicit CordStream (absl::Cord cord)
63+ : cord(std::move( cord) ), stream(&this ->cord) {}
9864
9965 absl::Cord cord;
10066 google::protobuf::io::CordInputStream stream;
10167 };
102- using Variant = absl::variant<ArrayStream, CordStream>;
103-
104- void Construct (const BytesValue* absl_nonnull value) {
105- ABSL_DCHECK (value != nullptr );
68+ using Variant = std::variant<std::monostate, ArrayStream, CordStream>;
10669
107- switch (value->value_ .GetKind ()) {
70+ void Construct (const BytesValue& value) {
71+ switch (value.value_ .GetKind ()) {
10872 case common_internal::ByteStringKind::kSmall :
109- Construct (value->value_ .GetSmall ());
73+ small_ = value.value_ .rep_ .small ;
74+ Construct (absl::string_view (small_.data , small_.size ));
11075 break ;
11176 case common_internal::ByteStringKind::kMedium :
112- Construct (value-> value_ .GetMedium ());
77+ Construct (value. value_ .GetMedium ());
11378 break ;
11479 case common_internal::ByteStringKind::kLarge :
115- Construct (value-> value_ .GetLarge ());
80+ Construct (value. value_ .GetLarge ());
11681 break ;
11782 }
11883 }
11984
12085 void Construct (absl::string_view value) {
12186 ABSL_DCHECK_LE (value.size (),
12287 static_cast <size_t >(std::numeric_limits<int >::max ()));
123- ::new (static_cast <void *>(&impl_[0 ]))
124- Variant (absl::in_place_type<ArrayStream>, value.data (),
125- static_cast <int >(value.size ()));
126- }
127-
128- void Construct (const absl::Cord& value) {
129- ::new (static_cast <void *>(&impl_[0 ]))
130- Variant (absl::in_place_type<CordStream>, value);
131- }
132-
133- void Destruct () { AsVariant ().~variant (); }
134-
135- Variant& AsVariant () ABSL_ATTRIBUTE_LIFETIME_BOUND {
136- return *std::launder (reinterpret_cast <Variant*>(&impl_[0 ]));
88+ stream_ =
89+ &variant_
90+ .emplace <ArrayStream>(value.data (), static_cast <int >(value.size ()))
91+ .stream ;
13792 }
13893
139- const Variant& AsVariant () const ABSL_ATTRIBUTE_LIFETIME_BOUND {
140- return * std::launder ( reinterpret_cast < const Variant*>(&impl_[ 0 ])) ;
94+ void Construct (absl::Cord value) {
95+ stream_ = &variant_. emplace <CordStream>( std::move (value)). stream ;
14196 }
14297
143- alignas (Variant) char impl_[sizeof (Variant)];
98+ google::protobuf::io::ZeroCopyInputStream* stream_;
99+ common_internal::SmallByteStringRep small_;
100+ Variant variant_;
144101};
145102
146103} // namespace cel
0 commit comments