y3c-stl 0.3.3
Friendly C++ STL wrapper with automatic stacktrace
Loading...
Searching...
No Matches
life.h
Go to the documentation of this file.
1#pragma once
2#include "y3c/terminate.h"
3#include <memory>
4#include <vector>
5
6namespace y3c {
7namespace internal {
8template <typename element_type>
9class contiguous_iterator;
10
12 const void *ptr_;
13 bool valid_;
14
15 explicit life_validator(const void *ptr, bool valid = true)
16 : ptr_(ptr), valid_(valid) {}
17};
19 bool alive_;
20 const void *begin_, *end_;
21 std::vector<std::shared_ptr<life_validator>> validators_;
22
23 public:
24 life_state(const void *begin, const void *end)
25 : alive_(true), begin_(begin), end_(end) {}
26 life_state(const life_state &) = delete;
27 life_state &operator=(const life_state &) = delete;
28 life_state(life_state &&) = delete;
30 ~life_state() = default;
31
32 void destroy() {
33 alive_ = false;
34 for (const auto &validator : validators_) {
35 validator->valid_ = false;
36 }
37 validators_.clear();
38 }
39 const void *begin() const { return begin_; }
40 const void *end() const { return end_; }
41 void push_validator(const std::shared_ptr<life_validator> &v) {
42 validators_.push_back(v);
43 }
44 void update_range(const void *new_begin, const void *new_end,
45 const void *invalidate_from = nullptr) {
46 bool end_changed = end_ != new_end;
47 for (auto it = validators_.begin(); it != validators_.end();) {
48 auto validator = *it;
49 if (validator->ptr_ < begin_ || validator->ptr_ > end_ ||
50 validator->ptr_ < new_begin || validator->ptr_ > new_end ||
51 (end_changed && validator->ptr_ == end_) ||
52 (end_changed && validator->ptr_ == new_end) ||
53 (invalidate_from != nullptr &&
54 validator->ptr_ >= invalidate_from)) {
55 validator->valid_ = false;
56 it = validators_.erase(it);
57 } else {
58 ++it;
59 }
60 }
61 begin_ = new_begin;
62 end_ = new_end;
63 }
64 bool alive() const { return alive_; }
65 bool in_range(const void *ptr) const { return begin_ <= ptr && ptr < end_; }
66 bool in_range_including_end(const void *ptr) const {
67 return begin_ <= ptr && ptr <= end_;
68 }
69 bool in_range(const void *begin, const void *end) const {
70 return this->begin_ <= begin && begin <= end && end <= this->end_;
71 }
72 template <typename T>
73 std::size_t size() const {
74 return static_cast<const T *>(end_) - static_cast<const T *>(begin_);
75 }
76 template <typename T>
77 std::ptrdiff_t index_of(T *ptr) const {
78 return ptr - static_cast<const T *>(begin_);
79 }
80};
81
90 std::shared_ptr<life_state> state_;
91
92 explicit life_observer(const std::shared_ptr<life_state> &state)
93 : state_(state) {}
94
95 public:
100 explicit life_observer(std::nullptr_t) : state_(nullptr) {}
101 life_observer(const life_observer &) = default;
103 ~life_observer() = default;
104
105 const std::shared_ptr<life_validator> &
106 push_validator(const std::shared_ptr<life_validator> &v) const {
107 state_->push_validator(v);
108 return v;
109 }
110 const void *begin() const { return state_->begin(); }
111 const void *end() const { return state_->end(); }
112 template <typename element_type>
113 element_type *assert_ptr(element_type *ptr, const std::string &func,
114 internal::skip_trace_tag = {}) const {
115 // array<T, 0> の参照の場合 ptr_ = nullptr, alive = arrayの寿命
116 // になる場合があるが、 その場合はnullptrアクセスエラーとしない
117 if (!state_) {
119 }
120 if (!state_->alive()) {
122 }
123 if (!state_->in_range(ptr)) {
125 func, state_->size<element_type>(), state_->index_of(ptr));
126 }
127 return ptr;
128 }
129 template <typename element_type>
131 const std::string &func,
132 internal::skip_trace_tag = {}) const {
133 if (!state_) {
135 }
136 if (!state_->alive()) {
138 }
139 y3c_assert_internal(iter.validator_);
140 if (!iter.validator_->valid_) {
142 }
143 if (!state_->in_range(iter.ptr_)) {
145 func, state_->size<element_type>(),
146 state_->index_of(iter.ptr_));
147 }
148 return iter.ptr_;
149 }
150 template <typename element_type>
151 element_type *
153 const std::string &func,
154 internal::skip_trace_tag = {}) const {
155 if (!state_) {
157 }
158 if (!state_->alive()) {
160 }
161 y3c_assert_internal(iter.validator_);
162 if (!iter.validator_->valid_) {
164 }
165 if (!state_->in_range_including_end(iter.ptr_)) {
167 func, state_->size<element_type>(),
168 state_->index_of(iter.ptr_));
169 }
170 return iter.ptr_;
171 }
172 template <typename element_type>
175 const std::string &func,
176 internal::skip_trace_tag = {}) const {
177 if (!state_) {
179 }
180 if (!state_->alive()) {
182 }
183 y3c_assert_internal(begin.validator_);
184 if (!begin.validator_->valid_) {
186 }
187 y3c_assert_internal(end.validator_);
188 if (!end.validator_->valid_) {
190 }
191 if (!state_->in_range(begin.ptr_, end.ptr_)) {
193 func, state_->size<element_type>(),
194 state_->index_of(begin.ptr_), state_->index_of(end.ptr_));
195 }
196 }
197
198 friend class life;
199};
200
207class life {
208 const void *begin, *end;
209 mutable std::shared_ptr<life_state> state_;
210
211 std::shared_ptr<life_state> init_state() const {
212 if (!state_) {
213 state_ = std::shared_ptr<life_state>(new life_state(begin, end));
214 }
215 return state_;
216 }
217
218 public:
219 explicit life(const void *begin, const void *end)
220 : begin(begin), end(end), state_(nullptr) {}
221 template <typename T>
222 explicit life(T *begin) : life(begin, begin + 1) {}
223 life(const life &) = delete;
224 life &operator=(const life &) = delete;
225 life(life &&) = delete;
226 life &operator=(life &&) = delete;
228 if (state_) {
229 state_->destroy();
230 }
231 }
232
233 life_observer observer() const { return life_observer(init_state()); }
240 void update(const void *begin, const void *end,
241 const void *invalidate_from = nullptr) {
242 init_state();
243 if ((begin < state_->begin() && end <= state_->begin()) ||
244 (begin >= state_->end() && end > state_->end())) {
245 state_->destroy();
246 state_ = std::shared_ptr<life_state>(new life_state(begin, end));
247 } else {
248 state_->update_range(begin, end, invalidate_from);
249 }
250 }
251
252 bool operator==(const life_observer &obs) const {
253 return this->state_ == obs.state_;
254 }
255 bool operator!=(const life_observer &obs) const {
256 return this->state_ != obs.state_;
257 }
258};
259} // namespace internal
260} // namespace y3c
array, vector など各種コンテナのイテレータ
Definition iterator.h:26
ライフタイムの状態を観測するクラス
Definition life.h:89
void assert_range_iter(const contiguous_iterator< element_type > &begin, const contiguous_iterator< element_type > &end, const std::string &func, internal::skip_trace_tag={}) const
Definition life.h:173
element_type * assert_ptr(element_type *ptr, const std::string &func, internal::skip_trace_tag={}) const
Definition life.h:113
element_type * assert_iter_including_end(const contiguous_iterator< element_type > &iter, const std::string &func, internal::skip_trace_tag={}) const
Definition life.h:152
const void * end() const
Definition life.h:111
element_type * assert_iter(const contiguous_iterator< element_type > &iter, const std::string &func, internal::skip_trace_tag={}) const
Definition life.h:130
const void * begin() const
Definition life.h:110
life_observer & operator=(const life_observer &)=default
life_observer(std::nullptr_t)
Definition life.h:100
life_observer(const life_observer &)=default
const std::shared_ptr< life_validator > & push_validator(const std::shared_ptr< life_validator > &v) const
Definition life.h:106
Definition life.h:18
std::ptrdiff_t index_of(T *ptr) const
Definition life.h:77
void destroy()
Definition life.h:32
life_state(const life_state &)=delete
const void * end() const
Definition life.h:40
void push_validator(const std::shared_ptr< life_validator > &v)
Definition life.h:41
const void * begin() const
Definition life.h:39
life_state(const void *begin, const void *end)
Definition life.h:24
bool in_range(const void *begin, const void *end) const
Definition life.h:69
void update_range(const void *new_begin, const void *new_end, const void *invalidate_from=nullptr)
Definition life.h:44
life_state & operator=(const life_state &)=delete
life_state & operator=(life_state &&)=delete
bool in_range_including_end(const void *ptr) const
Definition life.h:66
std::size_t size() const
Definition life.h:73
life_state(life_state &&)=delete
bool in_range(const void *ptr) const
Definition life.h:65
bool alive() const
Definition life.h:64
オブジェクトのライフタイムを管理するクラス
Definition life.h:207
life(life &&)=delete
life & operator=(life &&)=delete
~life()
Definition life.h:227
void update(const void *begin, const void *end, const void *invalidate_from=nullptr)
Definition life.h:240
life(T *begin)
Definition life.h:222
life(const void *begin, const void *end)
Definition life.h:219
life(const life &)=delete
life_observer observer() const
Definition life.h:233
bool operator==(const life_observer &obs) const
Definition life.h:252
bool operator!=(const life_observer &obs) const
Definition life.h:255
life & operator=(const life &)=delete
ポインタ型wrap: element_type型のデータへのポインタと、 このポインタ自体の生存状態を管理するクラス
Definition wrap.h:318
void terminate_ub_access_nullptr(std::string func, Args &&...args)
Definition terminate.h:133
void terminate_ub_out_of_range(std::string func, Args &&...args)
Definition terminate.h:132
void terminate_ub_access_deleted(std::string func, Args &&...args)
Definition terminate.h:134
void terminate_ub_invalid_iter(std::string func, Args &&...args)
Definition terminate.h:136
Definition array.h:8
wrap< element_type * > ptr
Definition wrap.h:487
Definition life.h:11
bool valid_
Definition life.h:13
life_validator(const void *ptr, bool valid=true)
Definition life.h:15
const void * ptr_
Definition life.h:12
Definition terminate.h:27
#define y3c_assert_internal(cond)
Definition terminate.h:148