1919#define THIRD_PARTY_CEL_CPP_COMMON_VALUES_BYTES_VALUE_OUTPUT_STREAM_H_
2020
2121#include < cstdint>
22- #include < new>
2322#include < string>
2423#include < utility>
24+ #include < variant>
2525
26- #include " absl/base/attributes.h"
2726#include " absl/base/nullability.h"
27+ #include " absl/base/optimization.h"
2828#include " absl/functional/overload.h"
2929#include " absl/log/absl_check.h"
3030#include " absl/strings/cord.h"
3131#include " absl/strings/string_view.h"
32- #include " absl/types/variant.h"
33- #include " absl/utility/utility.h"
3432#include " common/internal/byte_string.h"
3533#include " common/values/bytes_value.h"
3634#include " google/protobuf/arena.h"
@@ -41,99 +39,55 @@ namespace cel {
4139
4240class BytesValueOutputStream final : public google::protobuf::io::ZeroCopyOutputStream {
4341 public:
42+ BytesValueOutputStream () { Construct (); }
43+
4444 explicit BytesValueOutputStream (const BytesValue& value) { Construct (value); }
4545
4646 bool Next (void ** data, int * size) override {
47- return absl::visit (absl::Overload (
48- [&data, &size](String& string) -> bool {
49- return string.stream .Next (data, size);
50- },
51- [&data, &size](Cord& cord) -> bool {
52- return cord.stream .Next (data, size);
53- }),
54- AsVariant ());
47+ return stream_->Next (data, size);
5548 }
5649
57- void BackUp (int count) override {
58- absl::visit (
59- absl::Overload (
60- [&count](String& string) -> void { string.stream .BackUp (count); },
61- [&count](Cord& cord) -> void { cord.stream .BackUp (count); }),
62- AsVariant ());
63- }
50+ void BackUp (int count) override { stream_->BackUp (count); }
6451
65- int64_t ByteCount () const override {
66- return absl::visit (absl::Overload (
67- [](const String& string) -> int64_t {
68- return string.stream .ByteCount ();
69- },
70- [](const Cord& cord) -> int64_t {
71- return cord.stream .ByteCount ();
72- }),
73- AsVariant ());
74- }
52+ int64_t ByteCount () const override { return stream_->ByteCount (); }
7553
7654 bool WriteAliasedRaw (const void * data, int size) override {
77- return absl::visit (absl::Overload (
78- [&data, &size](String& string) -> bool {
79- return string.stream .WriteAliasedRaw (data, size);
80- },
81- [&data, &size](Cord& cord) -> bool {
82- return cord.stream .WriteAliasedRaw (data, size);
83- }),
84- AsVariant ());
55+ return stream_->WriteAliasedRaw (data, size);
8556 }
8657
87- bool AllowsAliasing () const override {
88- return absl::visit (absl::Overload (
89- [](const String& string) -> bool {
90- return string.stream .AllowsAliasing ();
91- },
92- [](const Cord& cord) -> bool {
93- return cord.stream .AllowsAliasing ();
94- }),
95- AsVariant ());
96- }
58+ bool AllowsAliasing () const override { return stream_->AllowsAliasing (); }
9759
9860 bool WriteCord (const absl::Cord& out) override {
99- return absl::visit (
100- absl::Overload (
101- [&out](String& string) -> bool {
102- return string.stream .WriteCord (out);
103- },
104- [&out](Cord& cord) -> bool { return cord.stream .WriteCord (out); }),
105- AsVariant ());
61+ return stream_->WriteCord (out);
10662 }
10763
64+ [[nodiscard]]
10865 BytesValue Consume (google::protobuf::Arena* absl_nonnull arena) && {
10966 ABSL_DCHECK (arena != nullptr );
110- return absl::visit (
111- absl::Overload (
112- [arena](String& string) -> BytesValue {
113- return BytesValue::From (std::move (string.target ), arena);
114- },
115- [arena](Cord& cord) -> BytesValue {
116- return BytesValue::From (cord.stream .Consume (), arena);
117- }),
118- AsVariant ());
67+ return std::visit (
68+ absl::Overload ([](std::monostate) -> BytesValue { ABSL_UNREACHABLE (); },
69+ [arena](StringStream& stream) -> BytesValue {
70+ return BytesValue::From (std::move (stream.target ),
71+ arena);
72+ },
73+ [arena](CordStream& stream) -> BytesValue {
74+ return BytesValue::From (stream.Consume (), arena);
75+ }),
76+ variant_);
11977 }
12078
12179 private:
122- struct String final {
123- explicit String (absl::string_view target)
80+ struct StringStream final {
81+ explicit StringStream (absl::string_view target)
12482 : target(target), stream(&this ->target) {}
12583
12684 std::string target;
12785 google::protobuf::io::StringOutputStream stream;
12886 };
87+ using CordStream = google::protobuf::io::CordOutputStream;
88+ using Variant = std::variant<std::monostate, StringStream, CordStream>;
12989
130- struct Cord final {
131- explicit Cord (const absl::Cord& cord) : stream(cord) {}
132-
133- google::protobuf::io::CordOutputStream stream;
134- };
135-
136- using Variant = absl::variant<String, Cord>;
90+ void Construct () { stream_ = &variant_.emplace <CordStream>(); }
13791
13892 void Construct (const BytesValue& value) {
13993 switch (value.value_ .GetKind ()) {
@@ -150,26 +104,15 @@ class BytesValueOutputStream final : public google::protobuf::io::ZeroCopyOutput
150104 }
151105
152106 void Construct (absl::string_view value) {
153- ::new (static_cast <void *>(&impl_[0 ]))
154- Variant (absl::in_place_type<String>, value);
155- }
156-
157- void Construct (const absl::Cord& value) {
158- ::new (static_cast <void *>(&impl_[0 ]))
159- Variant (absl::in_place_type<Cord>, value);
160- }
161-
162- void Destruct () { AsVariant ().~variant (); }
163-
164- Variant& AsVariant () ABSL_ATTRIBUTE_LIFETIME_BOUND {
165- return *std::launder (reinterpret_cast <Variant*>(&impl_[0 ]));
107+ stream_ = &variant_.emplace <StringStream>(value).stream ;
166108 }
167109
168- const Variant& AsVariant () const ABSL_ATTRIBUTE_LIFETIME_BOUND {
169- return * std::launder ( reinterpret_cast < const Variant*>(&impl_[ 0 ] ));
110+ void Construct (absl::Cord value) {
111+ stream_ = &variant_. emplace <CordStream>( std::move (value ));
170112 }
171113
172- alignas (Variant) char impl_[sizeof (Variant)];
114+ google::protobuf::io::ZeroCopyOutputStream* stream_;
115+ Variant variant_;
173116};
174117
175118} // namespace cel
0 commit comments