3131namespace cel ::common_internal {
3232
3333template class DeletingReferenceCount <google::protobuf::MessageLite>;
34- template class DeletingReferenceCount <Data>;
3534
3635namespace {
3736
3837class ReferenceCountedStdString final : public ReferenceCounted {
3938 public:
39+ static std::pair<absl::Nonnull<const ReferenceCount*>, absl::string_view> New (
40+ std::string&& string) {
41+ const auto * const refcount =
42+ new ReferenceCountedStdString (std::move (string));
43+ const auto * const refcount_string = std::launder (
44+ reinterpret_cast <const std::string*>(&refcount->string_ [0 ]));
45+ return std::pair{
46+ static_cast <absl::Nonnull<const ReferenceCount*>>(refcount),
47+ absl::string_view (*refcount_string)};
48+ }
49+
4050 explicit ReferenceCountedStdString (std::string&& string) {
4151 (::new (static_cast <void *>(&string_[0 ])) std::string (std::move (string)))
4252 ->shrink_to_fit ();
4353 }
4454
45- const char * data () const noexcept {
46- return std::launder (reinterpret_cast <const std::string*>(&string_[0 ]))
47- ->data ();
48- }
49-
50- size_t size () const noexcept {
51- return std::launder (reinterpret_cast <const std::string*>(&string_[0 ]))
52- ->size ();
53- }
54-
5555 private:
5656 void Finalize () noexcept override {
5757 std::destroy_at (std::launder (reinterpret_cast <std::string*>(&string_[0 ])));
@@ -60,6 +60,19 @@ class ReferenceCountedStdString final : public ReferenceCounted {
6060 alignas (std::string) char string_[sizeof (std::string)];
6161};
6262
63+ class ReferenceCountedString final : public ReferenceCounted {
64+ public:
65+ static std::pair<absl::Nonnull<const ReferenceCount*>, absl::string_view> New (
66+ absl::string_view string) {
67+ const auto * const refcount =
68+ ::new (internal::New (Overhead () + string.size ()))
69+ ReferenceCountedString (string);
70+ return std::pair{
71+ static_cast <absl::Nonnull<const ReferenceCount*>>(refcount),
72+ absl::string_view (refcount->data_ , refcount->size_ )};
73+ }
74+
75+ private:
6376// ReferenceCountedString is non-standard-layout due to having virtual functions
6477// from a base class. This causes compilers to warn about the use of offsetof(),
6578// but it still works here, so silence the warning and proceed.
@@ -68,54 +81,40 @@ class ReferenceCountedStdString final : public ReferenceCounted {
6881#pragma GCC diagnostic ignored "-Winvalid-offsetof"
6982#endif
7083
71- class ReferenceCountedString final : public ReferenceCounted {
72- public:
73- static const ReferenceCountedString* New (const char * data, size_t size) {
74- return ::new (internal::New (offsetof (ReferenceCountedString, data_) + size))
75- ReferenceCountedString (size, data);
76- }
77-
78- const char * data () const noexcept { return data_; }
84+ static size_t Overhead () { return offsetof (ReferenceCountedString, data_); }
7985
80- size_t size () const noexcept { return size_; }
86+ #if defined(__GNUC__) || defined(__clang__)
87+ #pragma GCC diagnostic pop
88+ #endif
8189
82- private:
83- ReferenceCountedString ( size_t size, const char * data) noexcept : size_(size) {
84- std::memcpy (data_, data, size );
90+ explicit ReferenceCountedString (absl::string_view string)
91+ : size_(string. size() ) {
92+ std::memcpy (data_, string. data (), size_ );
8593 }
8694
8795 void Delete () noexcept override {
8896 void * const that = this ;
8997 const auto size = size_;
9098 std::destroy_at (this );
91- internal::SizedDelete (that, offsetof (ReferenceCountedString, data_ ) + size);
99+ internal::SizedDelete (that, Overhead ( ) + size);
92100 }
93101
94102 const size_t size_;
95103 char data_[];
96104};
97105
98- #if defined(__GNUC__) || defined(__clang__)
99- #pragma GCC diagnostic pop
100- #endif
101-
102106} // namespace
103107
104108std::pair<absl::Nonnull<const ReferenceCount*>, absl::string_view>
105109MakeReferenceCountedString (absl::string_view value) {
106110 ABSL_DCHECK (!value.empty ());
107- const auto * refcount =
108- ReferenceCountedString::New (value.data (), value.size ());
109- return std::pair{refcount,
110- absl::string_view (refcount->data (), refcount->size ())};
111+ return ReferenceCountedString::New (value);
111112}
112113
113114std::pair<absl::Nonnull<const ReferenceCount*>, absl::string_view>
114115MakeReferenceCountedString (std::string&& value) {
115116 ABSL_DCHECK (!value.empty ());
116- const auto * refcount = new ReferenceCountedStdString (std::move (value));
117- return std::pair{refcount,
118- absl::string_view (refcount->data (), refcount->size ())};
117+ return ReferenceCountedStdString::New (std::move (value));
119118}
120119
121120} // namespace cel::common_internal
0 commit comments