ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
guard_seq.h
Go to the documentation of this file.
1#ifndef IREP2_GUARD_SEQ_H_
2#define IREP2_GUARD_SEQ_H_
3
4#include <cstddef>
5#include <immer/vector.hpp>
6#include <immer/memory_policy.hpp>
7#include <irep2/irep2_expr.h>
8
44class guard_seq
45{
46 using memory_policy = immer::memory_policy<
47 immer::default_heap_policy,
48 immer::unsafe_refcount_policy,
49 immer::no_lock_policy>;
50 using vector_t = immer::vector<expr2tc, memory_policy>;
51
52 vector_t v_;
53
54 explicit guard_seq(vector_t v) : v_(std::move(v))
55 {
56 }
57
58public:
59 guard_seq() = default;
60
61 std::size_t size() const
62 {
63 return v_.size();
64 }
65 bool empty() const
66 {
67 return v_.empty();
68 }
69
70 // Reference-returning into immer storage. The reference is valid only
71 // until the next push_back()/clear() replaces the root — callers must not
72 // stash an element reference across a guard mutation. (Value-returning was
73 // measured at ~2x symex: an expr2tc copy is an atomic refcount bump, and
74 // the -=/|=/build_guard_expr/== loops access elements O(N) times per merge,
75 // so the per-access copy dominates.) All internal call sites read the
76 // reference before any mutation; this is the documented precondition.
77 const expr2tc &operator[](std::size_t i) const
78 {
79 return v_[i];
80 }
81 const expr2tc &front() const
82 {
83 return v_.front();
84 }
85 const expr2tc &back() const
86 {
87 return v_.back();
88 }
89
90 void push_back(const expr2tc &e)
91 {
92 v_ = std::move(v_).push_back(e);
93 }
94
96 guard_seq prefix(std::size_t n) const
97 {
98 return guard_seq(v_.take(n));
99 }
100
106 guard_seq suffix(std::size_t n) const
107 {
108 vector_t r;
109 for (std::size_t i = n; i < v_.size(); ++i)
110 r = std::move(r).push_back(v_[i]);
111 return guard_seq(std::move(r));
112 }
113
114 void clear()
115 {
116 v_ = vector_t{};
117 }
118
119 using const_iterator = vector_t::const_iterator;
121 {
122 return v_.begin();
123 }
125 {
126 return v_.end();
127 }
128
129 bool operator==(const guard_seq &o) const
130 {
131 return v_ == o.v_;
132 }
133 bool operator!=(const guard_seq &o) const
134 {
135 return v_ != o.v_;
136 }
137};
138
139#endif /* IREP2_GUARD_SEQ_H_ */
const expr2tc & front() const
Definition guard_seq.h:81
guard_seq()=default
const_iterator begin() const
Definition guard_seq.h:120
vector_t::const_iterator const_iterator
Definition guard_seq.h:119
bool empty() const
Definition guard_seq.h:65
bool operator==(const guard_seq &o) const
Definition guard_seq.h:129
guard_seq prefix(std::size_t n) const
Logical prefix [0, n) — shares subtrees, no element copies.
Definition guard_seq.h:96
void clear()
Definition guard_seq.h:114
std::size_t size() const
Definition guard_seq.h:61
const_iterator end() const
Definition guard_seq.h:124
const expr2tc & operator[](std::size_t i) const
Definition guard_seq.h:77
const expr2tc & back() const
Definition guard_seq.h:85
void push_back(const expr2tc &e)
Definition guard_seq.h:90
bool operator!=(const guard_seq &o) const
Definition guard_seq.h:133
guard_seq suffix(std::size_t n) const
Logical suffix [n, size).
Definition guard_seq.h:106
irep_container< expr2t > expr2tc
Definition irep2.h:431