23
23
#include " absl/base/attributes.h"
24
24
#include " absl/status/status.h"
25
25
#include " absl/status/statusor.h"
26
+ #include " absl/types/variant.h"
27
+ #include " absl/utility/utility.h"
26
28
#include " base/memory.h"
27
29
#include " base/value_factory.h"
28
30
#include " base/values/list_value.h"
31
+ #include " internal/overloaded.h"
29
32
30
33
namespace cel {
31
34
@@ -75,6 +78,53 @@ class ListValueBuilder;
75
78
76
79
namespace base_internal {
77
80
81
+ // ComposableListType is a variant which represents either the ListType or the
82
+ // element Type for creating a ListType.
83
+ template <typename T>
84
+ using ComposableListType = absl::variant<Handle <T>, Handle <ListType>>;
85
+
86
+ // Create a ListType from ComposableListType.
87
+ template <typename T>
88
+ absl::StatusOr<Handle <ListType>> ComposeListType (
89
+ ValueFactory& value_factory, ComposableListType<T>&& composable) {
90
+ return absl::visit (
91
+ internal::Overloaded{
92
+ [&value_factory](
93
+ Handle <T>&& element) -> absl::StatusOr<Handle <ListType>> {
94
+ return value_factory.type_factory ().CreateListType (
95
+ std::move (element));
96
+ },
97
+ [](Handle <ListType>&& list) -> absl::StatusOr<Handle <ListType>> {
98
+ return std::move (list);
99
+ },
100
+ },
101
+ std::move (composable));
102
+ }
103
+
104
+ template <typename List, typename DebugStringer>
105
+ std::string ComposeListValueDebugString (const List& list,
106
+ const DebugStringer& debug_stringer) {
107
+ std::string out;
108
+ out.push_back (' [' );
109
+ auto current = list.begin ();
110
+ if (current != list.end ()) {
111
+ out.append (debug_stringer (*current));
112
+ ++current;
113
+ for (; current != list.end (); ++current) {
114
+ out.append (" , " );
115
+ out.append (debug_stringer (*current));
116
+ }
117
+ }
118
+ out.push_back (' ]' );
119
+ return out;
120
+ }
121
+
122
+ struct ComposedListType {
123
+ explicit ComposedListType () = default;
124
+ };
125
+
126
+ inline constexpr ComposedListType kComposedListType {};
127
+
78
128
// Implementation of ListValueBuilder. Specialized to store some value types as
79
129
// C++ primitives, avoiding Handle overhead. Anything that does not have a C++
80
130
// primitive is stored as Handle<Value>.
@@ -92,22 +142,22 @@ class ListValueBuilderImpl<T, void> : public ListValueBuilderInterface {
92
142
ABSL_ATTRIBUTE_LIFETIME_BOUND ValueFactory& value_factory,
93
143
Handle <typename ValueTraits<T>::type_type> type)
94
144
: ListValueBuilderInterface(value_factory),
95
- type_ (std::move(type)),
145
+ type_ (absl::in_place_type<Handle <typename ValueTraits<T>::type_type>>,
146
+ std::move (type)),
147
+ storage_(Allocator<Handle <Value>>{value_factory.memory_manager ()}) {}
148
+
149
+ ListValueBuilderImpl (
150
+ ComposedListType,
151
+ ABSL_ATTRIBUTE_LIFETIME_BOUND ValueFactory& value_factory,
152
+ Handle <ListType> type)
153
+ : ListValueBuilderInterface(value_factory),
154
+ type_(absl::in_place_type<Handle <ListType>>, std::move(type)),
96
155
storage_(Allocator<Handle <Value>>{value_factory.memory_manager ()}) {}
97
156
98
157
std::string DebugString () const override {
99
- size_t count = size ();
100
- std::string out;
101
- out.push_back (' [' );
102
- if (count != 0 ) {
103
- out.append (storage_[0 ]->DebugString ());
104
- for (size_t index = 1 ; index < count; index ++) {
105
- out.append (" , " );
106
- out.append (storage_[index ]->DebugString ());
107
- }
108
- }
109
- out.push_back (' ]' );
110
- return out;
158
+ return ComposeListValueDebugString (
159
+ storage_,
160
+ [](const Handle <Value>& value) { return value->DebugString (); });
111
161
}
112
162
113
163
absl::Status Add (Handle <Value> value) override {
@@ -127,14 +177,14 @@ class ListValueBuilderImpl<T, void> : public ListValueBuilderInterface {
127
177
128
178
absl::StatusOr<Handle <ListValue>> Build () && override {
129
179
CEL_ASSIGN_OR_RETURN (auto type,
130
- value_factory (). type_factory (). CreateListType ( type_));
180
+ ComposeListType ( value_factory (), std::move ( type_) ));
131
181
return value_factory ()
132
182
.template CreateListValue <base_internal::DynamicListValue>(
133
183
std::move (type), std::move (storage_));
134
184
}
135
185
136
186
private:
137
- Handle <typename ValueTraits<T>::type_type> type_;
187
+ ComposableListType <typename ValueTraits<T>::type_type> type_;
138
188
std::vector<Handle <Value>, Allocator<Handle <Value>>> storage_;
139
189
};
140
190
@@ -147,22 +197,21 @@ class ListValueBuilderImpl<Value, void> : public ListValueBuilderInterface {
147
197
ABSL_ATTRIBUTE_LIFETIME_BOUND ValueFactory& value_factory,
148
198
Handle <Type> type)
149
199
: ListValueBuilderInterface(value_factory),
150
- type_ (std::move(type)),
200
+ type_ (absl::in_place_type<Handle <Type>>, std::move(type)),
201
+ storage_(Allocator<Handle <Value>>{value_factory.memory_manager ()}) {}
202
+
203
+ ListValueBuilderImpl (
204
+ ComposedListType,
205
+ ABSL_ATTRIBUTE_LIFETIME_BOUND ValueFactory& value_factory,
206
+ Handle <ListType> type)
207
+ : ListValueBuilderInterface(value_factory),
208
+ type_(absl::in_place_type<Handle <ListType>>, std::move(type)),
151
209
storage_(Allocator<Handle <Value>>{value_factory.memory_manager ()}) {}
152
210
153
211
std::string DebugString () const override {
154
- size_t count = size ();
155
- std::string out;
156
- out.push_back (' [' );
157
- if (count != 0 ) {
158
- out.append (storage_[0 ]->DebugString ());
159
- for (size_t index = 1 ; index < count; index ++) {
160
- out.append (" , " );
161
- out.append (storage_[index ]->DebugString ());
162
- }
163
- }
164
- out.push_back (' ]' );
165
- return out;
212
+ return ComposeListValueDebugString (
213
+ storage_,
214
+ [](const Handle <Value>& value) { return value->DebugString (); });
166
215
}
167
216
168
217
absl::Status Add (Handle <Value> value) override {
@@ -178,14 +227,14 @@ class ListValueBuilderImpl<Value, void> : public ListValueBuilderInterface {
178
227
179
228
absl::StatusOr<Handle <ListValue>> Build () && override {
180
229
CEL_ASSIGN_OR_RETURN (auto type,
181
- value_factory (). type_factory (). CreateListType ( type_));
230
+ ComposeListType ( value_factory (), std::move ( type_) ));
182
231
return value_factory ()
183
232
.template CreateListValue <base_internal::DynamicListValue>(
184
233
std::move (type), std::move (storage_));
185
234
}
186
235
187
236
private:
188
- Handle <Type> type_;
237
+ ComposableListType <Type> type_;
189
238
std::vector<Handle <Value>, Allocator<Handle <Value>>> storage_;
190
239
};
191
240
@@ -198,23 +247,22 @@ class ListValueBuilderImpl : public ListValueBuilderInterface {
198
247
ABSL_ATTRIBUTE_LIFETIME_BOUND ValueFactory& value_factory,
199
248
Handle <typename ValueTraits<T>::type_type> type)
200
249
: ListValueBuilderInterface(value_factory),
201
- type_ (std::move(type)),
250
+ type_ (absl::in_place_type<Handle <typename ValueTraits<T>::type_type>>,
251
+ std::move (type)),
252
+ storage_(Allocator<U>{value_factory.memory_manager ()}) {}
253
+
254
+ ListValueBuilderImpl (
255
+ ComposedListType,
256
+ ABSL_ATTRIBUTE_LIFETIME_BOUND ValueFactory& value_factory,
257
+ Handle <ListType> type)
258
+ : ListValueBuilderInterface(value_factory),
259
+ type_(absl::in_place_type<Handle <ListType>>, std::move(type)),
202
260
storage_(Allocator<U>{value_factory.memory_manager ()}) {}
203
261
204
262
std::string DebugString () const override {
205
- using value_traits = ValueTraits<T>;
206
- size_t count = size ();
207
- std::string out;
208
- out.push_back (' [' );
209
- if (count != 0 ) {
210
- out.append (value_traits::DebugString (storage_[0 ]));
211
- for (size_t index = 1 ; index < count; index ++) {
212
- out.append (" , " );
213
- out.append (value_traits::DebugString (storage_[index ]));
214
- }
215
- }
216
- out.push_back (' ]' );
217
- return out;
263
+ return ComposeListValueDebugString (storage_, [](const U& value) {
264
+ return ValueTraits<T>::DebugString (value);
265
+ });
218
266
}
219
267
220
268
absl::Status Add (Handle <Value> value) override {
@@ -236,14 +284,14 @@ class ListValueBuilderImpl : public ListValueBuilderInterface {
236
284
237
285
absl::StatusOr<Handle <ListValue>> Build () && override {
238
286
CEL_ASSIGN_OR_RETURN (auto type,
239
- value_factory (). type_factory (). CreateListType ( type_));
287
+ ComposeListType ( value_factory (), std::move ( type_) ));
240
288
return value_factory ()
241
289
.template CreateListValue <base_internal::StaticListValue<T>>(
242
290
std::move (type), std::move (storage_));
243
291
}
244
292
245
293
private:
246
- Handle <typename ValueTraits<T>::type_type> type_;
294
+ ComposableListType <typename ValueTraits<T>::type_type> type_;
247
295
std::vector<U, Allocator<U>> storage_;
248
296
};
249
297
@@ -257,6 +305,8 @@ class ListValueBuilder final
257
305
using Impl = base_internal::ListValueBuilderImpl<
258
306
T, typename base_internal::ValueTraits<T>::underlying_type>;
259
307
308
+ static_assert (!std::is_same_v<T, ListValue>);
309
+
260
310
public:
261
311
using Impl::Impl;
262
312
};
0 commit comments