1717
1818#include < cstddef>
1919#include < utility>
20- #include < vector>
2120
21+ #include " absl/base/attributes.h"
2222#include " absl/base/no_destructor.h"
2323#include " absl/base/nullability.h"
24+ #include " absl/container/fixed_array.h"
2425#include " absl/log/absl_check.h"
2526#include " absl/types/optional.h"
2627#include " common/value.h"
2728#include " eval/eval/attribute_trail.h"
2829
2930namespace google ::api::expr::runtime {
3031
32+ class ComprehensionSlot final {
33+ public:
34+ ComprehensionSlot () = default ;
35+ ComprehensionSlot (const ComprehensionSlot&) = delete ;
36+ ComprehensionSlot (ComprehensionSlot&&) = delete ;
37+ ComprehensionSlot& operator =(const ComprehensionSlot&) = delete ;
38+ ComprehensionSlot& operator =(ComprehensionSlot&&) = delete ;
39+
40+ const cel::Value& value () const ABSL_ATTRIBUTE_LIFETIME_BOUND {
41+ ABSL_DCHECK (Has ());
42+
43+ return value_;
44+ }
45+
46+ absl::Nonnull<cel::Value*> mutable_value () ABSL_ATTRIBUTE_LIFETIME_BOUND {
47+ ABSL_DCHECK (Has ());
48+
49+ return &value_;
50+ }
51+
52+ const AttributeTrail& attribute () const ABSL_ATTRIBUTE_LIFETIME_BOUND {
53+ ABSL_DCHECK (Has ());
54+
55+ return attribute_;
56+ }
57+
58+ absl::Nonnull<AttributeTrail*> mutable_attribute ()
59+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
60+ ABSL_DCHECK (Has ());
61+
62+ return &attribute_;
63+ }
64+
65+ bool Has () const { return has_; }
66+
67+ void Set () { Set (cel::NullValue (), absl::nullopt ); }
68+
69+ template <typename V>
70+ void Set (V&& value) {
71+ Set (std::forward<V>(value), absl::nullopt );
72+ }
73+
74+ template <typename V, typename A>
75+ void Set (V&& value, A&& attribute) {
76+ value_ = std::forward<V>(value);
77+ attribute_ = std::forward<A>(attribute);
78+ has_ = true ;
79+ }
80+
81+ void Clear () {
82+ if (has_) {
83+ value_ = cel::NullValue ();
84+ attribute_ = absl::nullopt ;
85+ has_ = false ;
86+ }
87+ }
88+
89+ private:
90+ cel::Value value_;
91+ AttributeTrail attribute_;
92+ bool has_ = false ;
93+ };
94+
3195// Simple manager for comprehension variables.
3296//
3397// At plan time, each comprehension variable is assigned a slot by index.
3498// This is used instead of looking up the variable identifier by name in a
3599// runtime stack.
36100//
37101// Callers must handle range checking.
38- class ComprehensionSlots {
102+ class ComprehensionSlots final {
39103 public:
40- struct Slot {
41- cel::Value value;
42- AttributeTrail attribute;
43- };
104+ using Slot = ComprehensionSlot;
44105
45106 // Trivial instance if no slots are needed.
46107 // Trivially thread safe since no effective state.
@@ -49,52 +110,42 @@ class ComprehensionSlots {
49110 return *instance;
50111 }
51112
52- explicit ComprehensionSlots (size_t size) : size_(size), slots_(size) {}
113+ explicit ComprehensionSlots (size_t size) : slots_(size) {}
53114
54- // Move only
55115 ComprehensionSlots (const ComprehensionSlots&) = delete ;
56116 ComprehensionSlots& operator =(const ComprehensionSlots&) = delete ;
57- ComprehensionSlots (ComprehensionSlots&&) = default ;
58- ComprehensionSlots& operator =(ComprehensionSlots&&) = default ;
59-
60- // Return ptr to slot at index.
61- // If not set, returns nullptr.
62- absl::Nullable<Slot*> Get (size_t index) {
63- ABSL_DCHECK_LT (index, slots_.size ());
64- auto & slot = slots_[index];
65- if (!slot.has_value ()) return nullptr ;
66- return &slot.value ();
67- }
68117
69- void Reset () {
70- slots_.clear ();
71- slots_.resize (size_);
72- }
118+ ComprehensionSlots (ComprehensionSlots&&) = delete ;
119+ ComprehensionSlots& operator =(ComprehensionSlots&&) = delete ;
73120
74- void ClearSlot (size_t index) {
75- ABSL_DCHECK_LT (index, slots_.size ());
76- slots_[index] = absl::nullopt ;
121+ absl::Nonnull<Slot*> Get (size_t index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
122+ ABSL_DCHECK_LT (index, size ());
123+
124+ return &slots_[index];
77125 }
78126
79- absl::Nonnull<Slot*> Set (size_t index) {
80- ABSL_DCHECK_LT (index, slots_.size ());
81- return &slots_[index].emplace ();
127+ void Reset () {
128+ for (Slot& slot : slots_) {
129+ slot.Clear ();
130+ }
82131 }
83132
84- void Set (size_t index, cel::Value value) {
85- Set (index, std::move (value), AttributeTrail ());
133+ void ClearSlot (size_t index) { Get (index)->Clear (); }
134+
135+ template <typename V>
136+ void Set (size_t index, V&& value) {
137+ Set (index, std::forward<V>(value), absl::nullopt );
86138 }
87139
88- void Set ( size_t index, cel::Value value, AttributeTrail attribute) {
89- ABSL_DCHECK_LT ( index, slots_. size ());
90- slots_[ index] = Slot{ std::move (value), std::move (attribute)} ;
140+ template < typename V, typename A>
141+ void Set ( size_t index, V&& value, A&& attribute) {
142+ Get ( index)-> Set ( std::forward<V> (value), std::forward<A> (attribute)) ;
91143 }
92144
93145 size_t size () const { return slots_.size (); }
94146
95147 private:
96- size_t size_;
97- std::vector<absl::optional<Slot>> slots_;
148+ absl::FixedArray<ComprehensionSlot, 0 > slots_;
98149};
99150
100151} // namespace google::api::expr::runtime
0 commit comments