/proc/self/cwd/eval/eval/evaluator_stack.h
Line | Count | Source |
1 | | #ifndef THIRD_PARTY_CEL_CPP_EVAL_EVAL_EVALUATOR_STACK_H_ |
2 | | #define THIRD_PARTY_CEL_CPP_EVAL_EVAL_EVALUATOR_STACK_H_ |
3 | | |
4 | | #include <algorithm> |
5 | | #include <cstddef> |
6 | | #include <memory> |
7 | | #include <type_traits> |
8 | | #include <utility> |
9 | | |
10 | | #include "absl/base/attributes.h" |
11 | | #include "absl/base/dynamic_annotations.h" |
12 | | #include "absl/base/nullability.h" |
13 | | #include "absl/base/optimization.h" |
14 | | #include "absl/log/absl_check.h" |
15 | | #include "absl/meta/type_traits.h" |
16 | | #include "absl/types/optional.h" |
17 | | #include "absl/types/span.h" |
18 | | #include "common/value.h" |
19 | | #include "eval/eval/attribute_trail.h" |
20 | | #include "internal/align.h" |
21 | | #include "internal/new.h" |
22 | | |
23 | | namespace google::api::expr::runtime { |
24 | | |
25 | | // CelValue stack. |
26 | | // Implementation is based on vector to allow passing parameters from |
27 | | // stack as Span<>. |
28 | | class EvaluatorStack { |
29 | | public: |
30 | 16.9k | explicit EvaluatorStack(size_t max_size) { Reserve(max_size); } |
31 | | |
32 | | EvaluatorStack(const EvaluatorStack&) = delete; |
33 | | EvaluatorStack(EvaluatorStack&&) = delete; |
34 | | |
35 | 16.9k | ~EvaluatorStack() { |
36 | 16.9k | if (max_size() > 0) { |
37 | 16.9k | const size_t n = size(); |
38 | 16.9k | std::destroy_n(values_begin_, n); |
39 | 16.9k | std::destroy_n(attributes_begin_, n); |
40 | 16.9k | cel::internal::SizedDelete(data_, SizeBytes(max_size_)); |
41 | 16.9k | } |
42 | 16.9k | } |
43 | | |
44 | | EvaluatorStack& operator=(const EvaluatorStack&) = delete; |
45 | | EvaluatorStack& operator=(EvaluatorStack&&) = delete; |
46 | | |
47 | | // Return the current stack size. |
48 | 17.1M | size_t size() const { |
49 | 17.1M | ABSL_DCHECK_GE(values_, values_begin_); |
50 | 17.1M | ABSL_DCHECK_LE(values_, values_begin_ + max_size_); |
51 | 17.1M | ABSL_DCHECK_GE(attributes_, attributes_begin_); |
52 | 17.1M | ABSL_DCHECK_LE(attributes_, attributes_begin_ + max_size_); |
53 | 17.1M | ABSL_DCHECK_EQ(values_ - values_begin_, attributes_ - attributes_begin_); |
54 | | |
55 | 17.1M | return values_ - values_begin_; |
56 | 17.1M | } |
57 | | |
58 | | // Return the maximum size of the stack. |
59 | 50.8k | size_t max_size() const { |
60 | 50.8k | ABSL_DCHECK_GE(values_, values_begin_); |
61 | 50.8k | ABSL_DCHECK_LE(values_, values_begin_ + max_size_); |
62 | 50.8k | ABSL_DCHECK_GE(attributes_, attributes_begin_); |
63 | 50.8k | ABSL_DCHECK_LE(attributes_, attributes_begin_ + max_size_); |
64 | 50.8k | ABSL_DCHECK_EQ(values_ - values_begin_, attributes_ - attributes_begin_); |
65 | | |
66 | 50.8k | return max_size_; |
67 | 50.8k | } |
68 | | |
69 | | // Returns true if stack is empty. |
70 | 0 | bool empty() const { |
71 | 0 | ABSL_DCHECK_GE(values_, values_begin_); |
72 | 0 | ABSL_DCHECK_LE(values_, values_begin_ + max_size_); |
73 | 0 | ABSL_DCHECK_GE(attributes_, attributes_begin_); |
74 | 0 | ABSL_DCHECK_LE(attributes_, attributes_begin_ + max_size_); |
75 | 0 | ABSL_DCHECK_EQ(values_ - values_begin_, attributes_ - attributes_begin_); |
76 | |
|
77 | 0 | return values_ == values_begin_; |
78 | 0 | } |
79 | | |
80 | 18.5M | bool full() const { |
81 | 18.5M | ABSL_DCHECK_GE(values_, values_begin_); |
82 | 18.5M | ABSL_DCHECK_LE(values_, values_begin_ + max_size_); |
83 | 18.5M | ABSL_DCHECK_GE(attributes_, attributes_begin_); |
84 | 18.5M | ABSL_DCHECK_LE(attributes_, attributes_begin_ + max_size_); |
85 | 18.5M | ABSL_DCHECK_EQ(values_ - values_begin_, attributes_ - attributes_begin_); |
86 | | |
87 | 18.5M | return values_ == values_end_; |
88 | 18.5M | } |
89 | | |
90 | | // Attributes stack size. |
91 | | ABSL_DEPRECATED("Use size()") |
92 | 0 | size_t attribute_size() const { return size(); } |
93 | | |
94 | | // Check that stack has enough elements. |
95 | 15.8M | bool HasEnough(size_t size) const { return this->size() >= size; } |
96 | | |
97 | | // Dumps the entire stack state as is. |
98 | 33.9k | void Clear() { |
99 | 33.9k | if (max_size() > 0) { |
100 | 33.9k | const size_t n = size(); |
101 | 33.9k | std::destroy_n(values_begin_, n); |
102 | 33.9k | std::destroy_n(attributes_begin_, n); |
103 | | |
104 | 33.9k | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER( |
105 | 33.9k | values_begin_, values_begin_ + max_size_, values_, values_begin_); |
106 | 33.9k | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(attributes_begin_, |
107 | 33.9k | attributes_begin_ + max_size_, |
108 | 33.9k | attributes_, attributes_begin_); |
109 | | |
110 | 33.9k | values_ = values_begin_; |
111 | 33.9k | attributes_ = attributes_begin_; |
112 | 33.9k | } |
113 | 33.9k | } |
114 | | |
115 | | // Gets the last size elements of the stack. |
116 | | // Checking that stack has enough elements is caller's responsibility. |
117 | | // Please note that calls to Push may invalidate returned Span object. |
118 | 12.6M | absl::Span<const cel::Value> GetSpan(size_t size) const { |
119 | 12.6M | ABSL_DCHECK(HasEnough(size)); |
120 | | |
121 | 12.6M | return absl::Span<const cel::Value>(values_ - size, size); |
122 | 12.6M | } |
123 | | |
124 | | // Gets the last size attribute trails of the stack. |
125 | | // Checking that stack has enough elements is caller's responsibility. |
126 | | // Please note that calls to Push may invalidate returned Span object. |
127 | 1.27M | absl::Span<const AttributeTrail> GetAttributeSpan(size_t size) const { |
128 | 1.27M | ABSL_DCHECK(HasEnough(size)); |
129 | | |
130 | 1.27M | return absl::Span<const AttributeTrail>(attributes_ - size, size); |
131 | 1.27M | } |
132 | | |
133 | | // Peeks the last element of the stack. |
134 | | // Checking that stack is not empty is caller's responsibility. |
135 | 4.28M | cel::Value& Peek() { |
136 | 4.28M | ABSL_DCHECK(HasEnough(1)); |
137 | | |
138 | 4.28M | return *(values_ - 1); |
139 | 4.28M | } |
140 | | |
141 | | // Peeks the last element of the stack. |
142 | | // Checking that stack is not empty is caller's responsibility. |
143 | 0 | const cel::Value& Peek() const { |
144 | 0 | ABSL_DCHECK(HasEnough(1)); |
145 | 0 |
|
146 | 0 | return *(values_ - 1); |
147 | 0 | } |
148 | | |
149 | | // Peeks the last element of the attribute stack. |
150 | | // Checking that stack is not empty is caller's responsibility. |
151 | 0 | const AttributeTrail& PeekAttribute() const { |
152 | 0 | ABSL_DCHECK(HasEnough(1)); |
153 | 0 |
|
154 | 0 | return *(attributes_ - 1); |
155 | 0 | } |
156 | | |
157 | | // Peeks the last element of the attribute stack. |
158 | | // Checking that stack is not empty is caller's responsibility. |
159 | 2.45M | AttributeTrail& PeekAttribute() { |
160 | 2.45M | ABSL_DCHECK(HasEnough(1)); |
161 | | |
162 | 2.45M | return *(attributes_ - 1); |
163 | 2.45M | } |
164 | | |
165 | 18.5M | void Pop() { |
166 | 18.5M | ABSL_DCHECK(!empty()); |
167 | | |
168 | 18.5M | --values_; |
169 | 18.5M | values_->~Value(); |
170 | 18.5M | --attributes_; |
171 | 18.5M | attributes_->~AttributeTrail(); |
172 | | |
173 | 18.5M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(values_begin_, values_begin_ + max_size_, |
174 | 18.5M | values_ + 1, values_); |
175 | 18.5M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(attributes_begin_, |
176 | 18.5M | attributes_begin_ + max_size_, |
177 | 18.5M | attributes_ + 1, attributes_); |
178 | 18.5M | } |
179 | | |
180 | | // Clears the last size elements of the stack. |
181 | | // Checking that stack has enough elements is caller's responsibility. |
182 | 13.9M | void Pop(size_t size) { |
183 | 13.9M | ABSL_DCHECK(HasEnough(size)); |
184 | | |
185 | 32.5M | for (; size > 0; --size) { |
186 | 18.5M | Pop(); |
187 | 18.5M | } |
188 | 13.9M | } |
189 | | |
190 | | template <typename V, typename A, |
191 | | typename = std::enable_if_t< |
192 | | std::conjunction_v<std::is_convertible<V, cel::Value>, |
193 | | std::is_convertible<A, AttributeTrail>>>> |
194 | 18.5M | void Push(V&& value, A&& attribute) { |
195 | 18.5M | ABSL_DCHECK(!full()); |
196 | | |
197 | 18.5M | if (ABSL_PREDICT_FALSE(full())) { |
198 | 0 | Grow(); |
199 | 0 | } |
200 | | |
201 | 18.5M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(values_begin_, values_begin_ + max_size_, |
202 | 18.5M | values_, values_ + 1); |
203 | 18.5M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(attributes_begin_, |
204 | 18.5M | attributes_begin_ + max_size_, |
205 | 18.5M | attributes_, attributes_ + 1); |
206 | | |
207 | 18.5M | ::new (static_cast<void*>(values_++)) cel::Value(std::forward<V>(value)); |
208 | 18.5M | ::new (static_cast<void*>(attributes_++)) |
209 | 18.5M | AttributeTrail(std::forward<A>(attribute)); |
210 | 18.5M | } Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::Push<cel::BoolValue, std::__1::nullopt_t const&, void>(cel::BoolValue&&, std::__1::nullopt_t const&) void google::api::expr::runtime::EvaluatorStack::Push<cel::Value, google::api::expr::runtime::AttributeTrail, void>(cel::Value&&, google::api::expr::runtime::AttributeTrail&&) Line | Count | Source | 194 | 2.74M | void Push(V&& value, A&& attribute) { | 195 | 2.74M | ABSL_DCHECK(!full()); | 196 | | | 197 | 2.74M | if (ABSL_PREDICT_FALSE(full())) { | 198 | 0 | Grow(); | 199 | 0 | } | 200 | | | 201 | 2.74M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(values_begin_, values_begin_ + max_size_, | 202 | 2.74M | values_, values_ + 1); | 203 | 2.74M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(attributes_begin_, | 204 | 2.74M | attributes_begin_ + max_size_, | 205 | 2.74M | attributes_, attributes_ + 1); | 206 | | | 207 | 2.74M | ::new (static_cast<void*>(values_++)) cel::Value(std::forward<V>(value)); | 208 | 2.74M | ::new (static_cast<void*>(attributes_++)) | 209 | 2.74M | AttributeTrail(std::forward<A>(attribute)); | 210 | 2.74M | } |
Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::Push<cel::ErrorValue, std::__1::nullopt_t const&, void>(cel::ErrorValue&&, std::__1::nullopt_t const&) void google::api::expr::runtime::EvaluatorStack::Push<cel::Value const&, std::__1::nullopt_t const&, void>(cel::Value const&, std::__1::nullopt_t const&) Line | Count | Source | 194 | 12.1M | void Push(V&& value, A&& attribute) { | 195 | 12.1M | ABSL_DCHECK(!full()); | 196 | | | 197 | 12.1M | if (ABSL_PREDICT_FALSE(full())) { | 198 | 0 | Grow(); | 199 | 0 | } | 200 | | | 201 | 12.1M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(values_begin_, values_begin_ + max_size_, | 202 | 12.1M | values_, values_ + 1); | 203 | 12.1M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(attributes_begin_, | 204 | 12.1M | attributes_begin_ + max_size_, | 205 | 12.1M | attributes_, attributes_ + 1); | 206 | | | 207 | 12.1M | ::new (static_cast<void*>(values_++)) cel::Value(std::forward<V>(value)); | 208 | 12.1M | ::new (static_cast<void*>(attributes_++)) | 209 | 12.1M | AttributeTrail(std::forward<A>(attribute)); | 210 | 12.1M | } |
void google::api::expr::runtime::EvaluatorStack::Push<cel::Value, std::__1::nullopt_t const&, void>(cel::Value&&, std::__1::nullopt_t const&) Line | Count | Source | 194 | 1.36M | void Push(V&& value, A&& attribute) { | 195 | 1.36M | ABSL_DCHECK(!full()); | 196 | | | 197 | 1.36M | if (ABSL_PREDICT_FALSE(full())) { | 198 | 0 | Grow(); | 199 | 0 | } | 200 | | | 201 | 1.36M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(values_begin_, values_begin_ + max_size_, | 202 | 1.36M | values_, values_ + 1); | 203 | 1.36M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(attributes_begin_, | 204 | 1.36M | attributes_begin_ + max_size_, | 205 | 1.36M | attributes_, attributes_ + 1); | 206 | | | 207 | 1.36M | ::new (static_cast<void*>(values_++)) cel::Value(std::forward<V>(value)); | 208 | 1.36M | ::new (static_cast<void*>(attributes_++)) | 209 | 1.36M | AttributeTrail(std::forward<A>(attribute)); | 210 | 1.36M | } |
Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::Push<cel::CustomListValue, std::__1::nullopt_t const&, void>(cel::CustomListValue&&, std::__1::nullopt_t const&) Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::Push<cel::CustomMapValue, std::__1::nullopt_t const&, void>(cel::CustomMapValue&&, std::__1::nullopt_t const&) void google::api::expr::runtime::EvaluatorStack::Push<cel::Value const&, google::api::expr::runtime::AttributeTrail const&, void>(cel::Value const&, google::api::expr::runtime::AttributeTrail const&) Line | Count | Source | 194 | 2.37M | void Push(V&& value, A&& attribute) { | 195 | 2.37M | ABSL_DCHECK(!full()); | 196 | | | 197 | 2.37M | if (ABSL_PREDICT_FALSE(full())) { | 198 | 0 | Grow(); | 199 | 0 | } | 200 | | | 201 | 2.37M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(values_begin_, values_begin_ + max_size_, | 202 | 2.37M | values_, values_ + 1); | 203 | 2.37M | ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(attributes_begin_, | 204 | 2.37M | attributes_begin_ + max_size_, | 205 | 2.37M | attributes_, attributes_ + 1); | 206 | | | 207 | 2.37M | ::new (static_cast<void*>(values_++)) cel::Value(std::forward<V>(value)); | 208 | 2.37M | ::new (static_cast<void*>(attributes_++)) | 209 | 2.37M | AttributeTrail(std::forward<A>(attribute)); | 210 | 2.37M | } |
|
211 | | |
212 | | template <typename V, |
213 | | typename = std::enable_if_t<std::is_convertible_v<V, cel::Value>>> |
214 | 12.1M | void Push(V&& value) { |
215 | 12.1M | ABSL_DCHECK(!full()); |
216 | | |
217 | 12.1M | Push(std::forward<V>(value), absl::nullopt); |
218 | 12.1M | } Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::Push<cel::BoolValue, void>(cel::BoolValue&&) void google::api::expr::runtime::EvaluatorStack::Push<cel::Value const&, void>(cel::Value const&) Line | Count | Source | 214 | 12.1M | void Push(V&& value) { | 215 | 12.1M | ABSL_DCHECK(!full()); | 216 | | | 217 | 12.1M | Push(std::forward<V>(value), absl::nullopt); | 218 | 12.1M | } |
Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::Push<cel::CustomListValue, void>(cel::CustomListValue&&) Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::Push<cel::CustomMapValue, void>(cel::CustomMapValue&&) Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::Push<cel::Value, void>(cel::Value&&) |
219 | | |
220 | | // Equivalent to `PopAndPush(1, ...)`. |
221 | | template <typename V, typename A, |
222 | | typename = std::enable_if_t< |
223 | | std::conjunction_v<std::is_convertible<V, cel::Value>, |
224 | | std::is_convertible<A, AttributeTrail>>>> |
225 | 358k | void PopAndPush(V&& value, A&& attribute) { |
226 | 358k | ABSL_DCHECK(!empty()); |
227 | | |
228 | 358k | *(values_ - 1) = std::forward<V>(value); |
229 | 358k | *(attributes_ - 1) = std::forward<A>(attribute); |
230 | 358k | } Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::UnknownValue, std::__1::nullopt_t const&, void>(cel::UnknownValue&&, std::__1::nullopt_t const&) void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::ErrorValue, std::__1::nullopt_t const&, void>(cel::ErrorValue&&, std::__1::nullopt_t const&) Line | Count | Source | 225 | 40.3k | void PopAndPush(V&& value, A&& attribute) { | 226 | 40.3k | ABSL_DCHECK(!empty()); | 227 | | | 228 | 40.3k | *(values_ - 1) = std::forward<V>(value); | 229 | 40.3k | *(attributes_ - 1) = std::forward<A>(attribute); | 230 | 40.3k | } |
void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::BoolValue, std::__1::nullopt_t const&, void>(cel::BoolValue&&, std::__1::nullopt_t const&) Line | Count | Source | 225 | 241 | void PopAndPush(V&& value, A&& attribute) { | 226 | 241 | ABSL_DCHECK(!empty()); | 227 | | | 228 | 241 | *(values_ - 1) = std::forward<V>(value); | 229 | 241 | *(attributes_ - 1) = std::forward<A>(attribute); | 230 | 241 | } |
void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::Value, std::__1::nullopt_t const&, void>(cel::Value&&, std::__1::nullopt_t const&) Line | Count | Source | 225 | 19.0k | void PopAndPush(V&& value, A&& attribute) { | 226 | 19.0k | ABSL_DCHECK(!empty()); | 227 | | | 228 | 19.0k | *(values_ - 1) = std::forward<V>(value); | 229 | 19.0k | *(attributes_ - 1) = std::forward<A>(attribute); | 230 | 19.0k | } |
void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::ErrorValue, google::api::expr::runtime::AttributeTrail, void>(cel::ErrorValue&&, google::api::expr::runtime::AttributeTrail&&) Line | Count | Source | 225 | 97.3k | void PopAndPush(V&& value, A&& attribute) { | 226 | 97.3k | ABSL_DCHECK(!empty()); | 227 | | | 228 | 97.3k | *(values_ - 1) = std::forward<V>(value); | 229 | 97.3k | *(attributes_ - 1) = std::forward<A>(attribute); | 230 | 97.3k | } |
void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::Value, google::api::expr::runtime::AttributeTrail, void>(cel::Value&&, google::api::expr::runtime::AttributeTrail&&) Line | Count | Source | 225 | 201k | void PopAndPush(V&& value, A&& attribute) { | 226 | 201k | ABSL_DCHECK(!empty()); | 227 | | | 228 | 201k | *(values_ - 1) = std::forward<V>(value); | 229 | 201k | *(attributes_ - 1) = std::forward<A>(attribute); | 230 | 201k | } |
Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::BoolValue, google::api::expr::runtime::AttributeTrail, void>(cel::BoolValue&&, google::api::expr::runtime::AttributeTrail&&) Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::OptionalValue, google::api::expr::runtime::AttributeTrail, void>(cel::OptionalValue&&, google::api::expr::runtime::AttributeTrail&&) |
231 | | |
232 | | // Equivalent to `PopAndPush(1, ...)`. |
233 | | template <typename V, |
234 | | typename = std::enable_if_t<std::is_convertible_v<V, cel::Value>>> |
235 | 59.6k | void PopAndPush(V&& value) { |
236 | 59.6k | ABSL_DCHECK(!empty()); |
237 | | |
238 | 59.6k | PopAndPush(std::forward<V>(value), absl::nullopt); |
239 | 59.6k | } Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::UnknownValue, void>(cel::UnknownValue&&) void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::ErrorValue, void>(cel::ErrorValue&&) Line | Count | Source | 235 | 40.3k | void PopAndPush(V&& value) { | 236 | 40.3k | ABSL_DCHECK(!empty()); | 237 | | | 238 | 40.3k | PopAndPush(std::forward<V>(value), absl::nullopt); | 239 | 40.3k | } |
void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::BoolValue, void>(cel::BoolValue&&) Line | Count | Source | 235 | 241 | void PopAndPush(V&& value) { | 236 | 241 | ABSL_DCHECK(!empty()); | 237 | | | 238 | 241 | PopAndPush(std::forward<V>(value), absl::nullopt); | 239 | 241 | } |
void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::Value, void>(cel::Value&&) Line | Count | Source | 235 | 19.0k | void PopAndPush(V&& value) { | 236 | 19.0k | ABSL_DCHECK(!empty()); | 237 | | | 238 | 19.0k | PopAndPush(std::forward<V>(value), absl::nullopt); | 239 | 19.0k | } |
|
240 | | |
241 | | // Equivalent to `Pop(n)` followed by `Push(...)`. Both `V` and `A` MUST NOT |
242 | | // be located on the stack. If this is the case, use SwapAndPop instead. |
243 | | template <typename V, typename A, |
244 | | typename = std::enable_if_t< |
245 | | std::conjunction_v<std::is_convertible<V, cel::Value>, |
246 | | std::is_convertible<A, AttributeTrail>>>> |
247 | 12.6M | void PopAndPush(size_t n, V&& value, A&& attribute) { |
248 | 12.6M | if (n > 0) { |
249 | 11.3M | if constexpr (std::is_same_v<cel::Value, absl::remove_cvref_t<V>>) { |
250 | 22.6M | ABSL_DCHECK(&value < values_begin_ || |
251 | 22.6M | &value >= values_begin_ + max_size_) |
252 | 22.6M | << "Attmpting to push a value about to be popped, use PopAndSwap " |
253 | 22.6M | "instead."; |
254 | 11.3M | } |
255 | 11.3M | if constexpr (std::is_same_v<AttributeTrail, absl::remove_cvref_t<A>>) { |
256 | 1.17M | ABSL_DCHECK(&attribute < attributes_begin_ || |
257 | 1.17M | &attribute >= attributes_begin_ + max_size_) |
258 | 1.17M | << "Attmpting to push an attribute about to be popped, use " |
259 | 1.17M | "PopAndSwap instead."; |
260 | 588k | } |
261 | | |
262 | 11.3M | Pop(n - 1); |
263 | | |
264 | 11.3M | ABSL_DCHECK(!empty()); |
265 | | |
266 | 11.3M | *(values_ - 1) = std::forward<V>(value); |
267 | 11.3M | *(attributes_ - 1) = std::forward<A>(attribute); |
268 | 11.3M | } else { |
269 | 1.36M | Push(std::forward<V>(value), std::forward<A>(attribute)); |
270 | 1.36M | } |
271 | 12.6M | } Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::ErrorValue, std::__1::nullopt_t const&, void>(unsigned long, cel::ErrorValue&&, std::__1::nullopt_t const&) void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::Value, google::api::expr::runtime::AttributeTrail, void>(unsigned long, cel::Value&&, google::api::expr::runtime::AttributeTrail&&) Line | Count | Source | 247 | 588k | void PopAndPush(size_t n, V&& value, A&& attribute) { | 248 | 588k | if (n > 0) { | 249 | 588k | if constexpr (std::is_same_v<cel::Value, absl::remove_cvref_t<V>>) { | 250 | 1.17M | ABSL_DCHECK(&value < values_begin_ || | 251 | 1.17M | &value >= values_begin_ + max_size_) | 252 | 1.17M | << "Attmpting to push a value about to be popped, use PopAndSwap " | 253 | 1.17M | "instead."; | 254 | 588k | } | 255 | 588k | if constexpr (std::is_same_v<AttributeTrail, absl::remove_cvref_t<A>>) { | 256 | 1.17M | ABSL_DCHECK(&attribute < attributes_begin_ || | 257 | 1.17M | &attribute >= attributes_begin_ + max_size_) | 258 | 1.17M | << "Attmpting to push an attribute about to be popped, use " | 259 | 1.17M | "PopAndSwap instead."; | 260 | 588k | } | 261 | | | 262 | 588k | Pop(n - 1); | 263 | | | 264 | 588k | ABSL_DCHECK(!empty()); | 265 | | | 266 | 588k | *(values_ - 1) = std::forward<V>(value); | 267 | 588k | *(attributes_ - 1) = std::forward<A>(attribute); | 268 | 588k | } else { | 269 | 0 | Push(std::forward<V>(value), std::forward<A>(attribute)); | 270 | 0 | } | 271 | 588k | } |
void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::Value, std::__1::nullopt_t const&, void>(unsigned long, cel::Value&&, std::__1::nullopt_t const&) Line | Count | Source | 247 | 12.0M | void PopAndPush(size_t n, V&& value, A&& attribute) { | 248 | 12.0M | if (n > 0) { | 249 | 10.7M | if constexpr (std::is_same_v<cel::Value, absl::remove_cvref_t<V>>) { | 250 | 21.4M | ABSL_DCHECK(&value < values_begin_ || | 251 | 21.4M | &value >= values_begin_ + max_size_) | 252 | 21.4M | << "Attmpting to push a value about to be popped, use PopAndSwap " | 253 | 21.4M | "instead."; | 254 | 10.7M | } | 255 | | if constexpr (std::is_same_v<AttributeTrail, absl::remove_cvref_t<A>>) { | 256 | | ABSL_DCHECK(&attribute < attributes_begin_ || | 257 | | &attribute >= attributes_begin_ + max_size_) | 258 | | << "Attmpting to push an attribute about to be popped, use " | 259 | | "PopAndSwap instead."; | 260 | | } | 261 | | | 262 | 10.7M | Pop(n - 1); | 263 | | | 264 | 10.7M | ABSL_DCHECK(!empty()); | 265 | | | 266 | 10.7M | *(values_ - 1) = std::forward<V>(value); | 267 | 10.7M | *(attributes_ - 1) = std::forward<A>(attribute); | 268 | 10.7M | } else { | 269 | 1.36M | Push(std::forward<V>(value), std::forward<A>(attribute)); | 270 | 1.36M | } | 271 | 12.0M | } |
|
272 | | |
273 | | // Equivalent to `Pop(n)` followed by `Push(...)`. `V` MUST NOT be located on |
274 | | // the stack. If this is the case, use SwapAndPop instead. |
275 | | template <typename V, |
276 | | typename = std::enable_if_t<std::is_convertible_v<V, cel::Value>>> |
277 | 12.0M | void PopAndPush(size_t n, V&& value) { |
278 | 12.0M | PopAndPush(n, std::forward<V>(value), absl::nullopt); |
279 | 12.0M | } Unexecuted instantiation: void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::ErrorValue, void>(unsigned long, cel::ErrorValue&&) void google::api::expr::runtime::EvaluatorStack::PopAndPush<cel::Value, void>(unsigned long, cel::Value&&) Line | Count | Source | 277 | 12.0M | void PopAndPush(size_t n, V&& value) { | 278 | 12.0M | PopAndPush(n, std::forward<V>(value), absl::nullopt); | 279 | 12.0M | } |
|
280 | | |
281 | | // Swaps the `n - i` element (from the top of the stack) with the `n` element, |
282 | | // and pops `n - 1` elements. This results in the `n - i` element being at the |
283 | | // top of the stack. |
284 | 168k | void SwapAndPop(size_t n, size_t i) { |
285 | 168k | ABSL_DCHECK_GT(n, 0); |
286 | 168k | ABSL_DCHECK_LT(i, n); |
287 | 168k | ABSL_DCHECK(HasEnough(n - 1)); |
288 | | |
289 | 168k | using std::swap; |
290 | | |
291 | 168k | if (i > 0) { |
292 | 166k | swap(*(values_ - n), *(values_ - n + i)); |
293 | 166k | swap(*(attributes_ - n), *(attributes_ - n + i)); |
294 | 166k | } |
295 | 168k | Pop(n - 1); |
296 | 168k | } |
297 | | |
298 | | // Update the max size of the stack and update capacity if needed. |
299 | 0 | void SetMaxSize(size_t size) { Reserve(size); } |
300 | | |
301 | | private: |
302 | 50.8k | static size_t AttributesBytesOffset(size_t size) { |
303 | 50.8k | return cel::internal::AlignUp(sizeof(cel::Value) * size, |
304 | 50.8k | __STDCPP_DEFAULT_NEW_ALIGNMENT__); |
305 | 50.8k | } |
306 | | |
307 | 33.9k | static size_t SizeBytes(size_t size) { |
308 | 33.9k | return AttributesBytesOffset(size) + (sizeof(AttributeTrail) * size); |
309 | 33.9k | } |
310 | | |
311 | | void Grow(); |
312 | | |
313 | | // Preallocate stack. |
314 | | void Reserve(size_t size); |
315 | | |
316 | | cel::Value* absl_nullability_unknown values_ = nullptr; |
317 | | cel::Value* absl_nullability_unknown values_begin_ = nullptr; |
318 | | AttributeTrail* absl_nullability_unknown attributes_ = nullptr; |
319 | | AttributeTrail* absl_nullability_unknown attributes_begin_ = nullptr; |
320 | | cel::Value* absl_nullability_unknown values_end_ = nullptr; |
321 | | void* absl_nullability_unknown data_ = nullptr; |
322 | | size_t max_size_ = 0; |
323 | | }; |
324 | | |
325 | | } // namespace google::api::expr::runtime |
326 | | |
327 | | #endif // THIRD_PARTY_CEL_CPP_EVAL_EVAL_EVALUATOR_STACK_H_ |