Tatooine
property.h
Go to the documentation of this file.
1#ifndef TATOOINE_PROPERTY_H
2#define TATOOINE_PROPERTY_H
3//==============================================================================
4#include <cassert>
5#include <deque>
6#include <memory>
7#include <set>
8#include <vector>
9//==============================================================================
10namespace tatooine {
11//==============================================================================
12template <typename Handle, typename ValueType>
13struct typed_vector_property;
14//==============================================================================
15template <typename Handle>
18 //============================================================================
19 vector_property() = default;
20 vector_property(const vector_property& other) = default;
21 vector_property(vector_property&& other) noexcept = default;
22 auto operator=(const vector_property&) -> vector_property& = default;
23 auto operator=(vector_property&&) noexcept -> vector_property& = default;
24 //============================================================================
26 virtual ~vector_property() = default;
27 //----------------------------------------------------------------------------
29 virtual void reserve(std::size_t n) = 0;
30 //----------------------------------------------------------------------------
32 virtual void resize(std::size_t n) = 0;
33 //----------------------------------------------------------------------------
35 virtual void push_back() = 0;
36 //----------------------------------------------------------------------------
38 virtual void erase(std::size_t) = 0;
39 //----------------------------------------------------------------------------
41 virtual void clear() = 0;
42 //----------------------------------------------------------------------------
44 [[nodiscard]] virtual auto type() const -> const std::type_info& = 0;
45 //----------------------------------------------------------------------------
46 template <typename ValueType>
47 auto holds_type() const {
48 return type() == typeid(ValueType);
49 }
50 //----------------------------------------------------------------------------
51 virtual auto clone() const -> std::unique_ptr<this_type> = 0;
52 //----------------------------------------------------------------------------
53 template <typename ValueType>
54 auto cast_to_typed() -> decltype(auto) {
55 return *static_cast<typed_vector_property<Handle, ValueType>*>(this);
56 }
57 //----------------------------------------------------------------------------
58 template <typename ValueType>
59 auto cast_to_typed() const -> decltype(auto) {
60 return *static_cast<typed_vector_property<Handle, ValueType> const*>(this);
61 }
62 virtual auto clean(std::set<Handle> const&) -> void = 0;
63};
64//==============================================================================
65template <typename Handle, typename ValueType>
69 using container_type = std::vector<ValueType>;
70 using value_type = typename container_type::value_type;
71 using allocator_type = typename container_type::allocator_type;
72 using size_type = typename container_type::size_type;
73 using difference_type = typename container_type::difference_type;
74 using reference = typename container_type::reference;
75 using const_reference = typename container_type::const_reference;
76 using pointer = typename container_type::pointer;
77 using const_pointer = typename container_type::const_pointer;
78 using iterator = typename container_type::iterator;
79 using const_iterator = typename container_type::const_iterator;
80 using reverse_iterator = typename container_type::reverse_iterator;
82 typename container_type::const_reverse_iterator;
83 //============================================================================
84 private:
86 ValueType m_value;
87 //============================================================================
88 public:
89 explicit typed_vector_property(const ValueType& value = ValueType{})
90 : m_value{value} {}
91 //----------------------------------------------------------------------------
93 : parent_type{other}, m_data{other.m_data}, m_value{other.m_value} {}
94 //----------------------------------------------------------------------------
96 : parent_type{std::move(other)},
97 m_data{std::move(other.m_data)},
98 m_value{std::move(other.m_value)} {}
99 //----------------------------------------------------------------------------
100 auto operator=(const typed_vector_property& other) -> auto& {
102 m_data = other.m_data;
103 m_value = other.m_value;
104 return *this;
105 }
106 //----------------------------------------------------------------------------
107 auto operator=(typed_vector_property&& other) noexcept -> auto& {
108 parent_type::operator=(std::move(other));
109 m_data = std::move(other.m_data);
110 m_value = std::move(other.m_value);
111 return *this;
112 }
113 //============================================================================
114 auto size() { return m_data.size(); }
115 //----------------------------------------------------------------------------
116 void reserve(std::size_t n) override { m_data.reserve(n); }
117 //----------------------------------------------------------------------------
118 void resize(std::size_t n) override { m_data.resize(n, m_value); }
119 //----------------------------------------------------------------------------
120 void push_back() override { m_data.push_back(m_value); }
121 void push_back(const ValueType& value) { m_data.push_back(value); }
122 //----------------------------------------------------------------------------
123 auto front() -> auto& { return m_data.front(); }
124 auto front() const -> const auto& { return m_data.front(); }
125 //----------------------------------------------------------------------------
126 auto back() -> auto& { return m_data.back(); }
127 auto back() const -> const auto& { return m_data.back(); }
128 //----------------------------------------------------------------------------
129 auto erase(iterator pos) { return m_data.erase(pos); }
130 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
131 auto erase(const_iterator pos) { return m_data.erase(pos); }
132 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
133 auto erase(iterator first, iterator last) {
134 return m_data.erase(first, last);
135 }
136 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
138 return m_data.erase(first, last);
139 }
140 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
141 auto erase(std::size_t i) -> void override {
142 erase(begin() + static_cast<difference_type>(i));
143 }
144 //----------------------------------------------------------------------------
145 auto begin() { return m_data.begin(); }
146 auto begin() const { return m_data.begin(); }
147 //----------------------------------------------------------------------------
148 auto end() { return m_data.end(); }
149 auto end() const { return m_data.end(); }
150 //----------------------------------------------------------------------------
151 template <typename... Ts>
152 void emplace_back(Ts&&... ts) {
153 m_data.emplace_back(std::forward<Ts>(ts)...);
154 }
155 //----------------------------------------------------------------------------
156 void clear() override {
157 m_data.clear();
158 m_data.shrink_to_fit();
159 }
160 //----------------------------------------------------------------------------
161 auto data() const { return m_data.data(); }
162 //----------------------------------------------------------------------------
163 auto internal_container() const -> auto const& { return m_data; }
164 //----------------------------------------------------------------------------
165 auto size() const { return m_data.size(); }
166 //----------------------------------------------------------------------------
168 auto at(std::size_t const i) -> auto& {
169 assert(i < m_data.size());
170 return m_data.at(i);
171 }
172 //----------------------------------------------------------------------------
174 auto at(std::size_t const i) const -> const auto& {
175 assert(i < m_data.size());
176 return m_data.at(i);
177 }
178 //----------------------------------------------------------------------------
180 auto at(Handle handle) -> auto& {
181 assert(handle.index() < m_data.size());
182 return m_data.at(handle.index());
183 }
184 //----------------------------------------------------------------------------
186 auto at(Handle handle) const -> const auto& {
187 assert(handle.index() < m_data.size());
188 return m_data.at(handle.index());
189 }
190 //----------------------------------------------------------------------------
192 auto operator[](Handle handle) -> auto& {
193 assert(handle.index() < m_data.size());
194 return m_data[handle.index()];
195 }
196 //----------------------------------------------------------------------------
198 auto operator[](Handle handle) const -> const auto& {
199 assert(handle.index() < m_data.size());
200 return m_data[handle.index()];
201 }
202 //----------------------------------------------------------------------------
204 auto operator[](std::size_t const i) -> auto& {
205 assert(i < m_data.size());
206 return m_data[i];
207 }
208 //----------------------------------------------------------------------------
210 auto operator[](std::size_t const i) const -> const auto& {
211 assert(i < m_data.size());
212 return m_data[i];
213 }
214 //----------------------------------------------------------------------------
215 [[nodiscard]] auto type() const -> const std::type_info& override {
216 return typeid(ValueType);
217 }
218 //----------------------------------------------------------------------------
219 auto clone() const -> std::unique_ptr<parent_type> override {
220 return std::unique_ptr<this_type>{new this_type{*this}};
221 }
222 //----------------------------------------------------------------------------
223 auto clean(std::set<Handle> const& invalid_handles) -> void override {
224 auto cleaned_data = container_type{};
225 cleaned_data.reserve(m_data.size() - invalid_handles.size());
226 auto invalid_it = invalid_handles.begin();
227 auto i = std::size_t{};
228 for (auto const& date : m_data) {
229 if (invalid_it != invalid_handles.end() && *invalid_it == Handle{i}) {
230 ++invalid_it;
231 } else {
232 cleaned_data.push_back(date);
233 }
234 ++i;
235 }
236 m_data = std::move(cleaned_data);
237 }
238};
239//==============================================================================
240template <typename Handle, typename ValueType>
241struct typed_deque_property;
242//==============================================================================
243template <typename Handle>
246 //============================================================================
247 deque_property() = default;
248 deque_property(const deque_property& other) = default;
249 deque_property(deque_property&& other) noexcept = default;
250 auto operator=(const deque_property&) -> deque_property& = default;
252 //============================================================================
254 virtual ~deque_property() = default;
255 //----------------------------------------------------------------------------
257 virtual void resize(std::size_t n) = 0;
258 //----------------------------------------------------------------------------
260 virtual void push_back() = 0;
261 //----------------------------------------------------------------------------
263 virtual void push_front() = 0;
264 //----------------------------------------------------------------------------
266 virtual void erase(std::size_t) = 0;
267 //----------------------------------------------------------------------------
269 virtual void clear() = 0;
270 //----------------------------------------------------------------------------
272 [[nodiscard]] virtual auto type() const -> const std::type_info& = 0;
273 //----------------------------------------------------------------------------
274 template <typename ValueType>
275 auto holds_type() const {
276 return type() == typeid(ValueType);
277 }
278 //----------------------------------------------------------------------------
279 template <typename ValueType>
280 auto cast_to_typed() -> decltype(auto) {
281 return *static_cast<typed_deque_property<Handle, ValueType>*>(this);
282 }
283 //----------------------------------------------------------------------------
284 template <typename ValueType>
285 auto cast_to_typed() const -> decltype(auto) {
286 return *static_cast<typed_deque_property<Handle, ValueType> const*>(this);
287 }
288 //----------------------------------------------------------------------------
289 virtual auto clone() const -> std::unique_ptr<this_type> = 0;
290};
291//==============================================================================
292template <typename Handle, typename ValueType>
296 using container_type = std::deque<ValueType>;
297 using value_type = typename container_type::value_type;
298 using allocator_type = typename container_type::allocator_type;
299 using size_type = typename container_type::size_type;
300 using difference_type = typename container_type::difference_type;
301 using reference = typename container_type::reference;
302 using const_reference = typename container_type::const_reference;
303 using pointer = typename container_type::pointer;
304 using const_pointer = typename container_type::const_pointer;
305 using iterator = typename container_type::iterator;
306 using const_iterator = typename container_type::const_iterator;
307 using reverse_iterator = typename container_type::reverse_iterator;
309 typename container_type::const_reverse_iterator;
310 //============================================================================
311 private:
313 ValueType m_value;
314 //============================================================================
315 public:
316 explicit typed_deque_property(const ValueType& value = ValueType{})
317 : m_value{value} {}
318 //----------------------------------------------------------------------------
320 : parent_type{other}, m_data{other.m_data}, m_value{other.m_value} {}
321 //----------------------------------------------------------------------------
323 : parent_type{std::move(other)},
324 m_data{std::move(other.m_data)},
325 m_value{std::move(other.m_value)} {}
326 //----------------------------------------------------------------------------
327 auto operator=(const typed_deque_property& other) -> auto& {
328 parent_type::operator=(other);
329 m_data = other.m_data;
330 m_value = other.m_value;
331 return *this;
332 }
333 //----------------------------------------------------------------------------
334 auto operator=(typed_deque_property&& other) noexcept -> auto& {
335 parent_type::operator=(std::move(other));
336 m_data = std::move(other.m_data);
337 m_value = std::move(other.m_value);
338 return *this;
339 }
340 //============================================================================
341 auto size() { return m_data.size(); }
342 //----------------------------------------------------------------------------
344 void resize(std::size_t n) override { m_data.resize(n); }
345 //----------------------------------------------------------------------------
346 void push_back() override { m_data.push_back(m_value); }
347 void push_back(const ValueType& value) { m_data.push_back(value); }
348 //----------------------------------------------------------------------------
349 void push_front() override { m_data.push_front(m_value); }
350 void push_front(const ValueType& value) { m_data.push_front(value); }
351 //----------------------------------------------------------------------------
352 auto front() -> auto& { return m_data.front(); }
353 auto front() const -> const auto& { return m_data.front(); }
354 //----------------------------------------------------------------------------
355 auto back() -> auto& { return m_data.back(); }
356 auto back() const -> const auto& { return m_data.back(); }
357 //----------------------------------------------------------------------------
358 auto erase(iterator pos) { return m_data.erase(pos); }
359 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
360 auto erase(const_iterator pos) { return m_data.erase(pos); }
361 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
362 auto erase(iterator first, iterator last) {
363 return m_data.erase(first, last);
364 }
365 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
367 return m_data.erase(first, last);
368 }
369 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
370 void erase(std::size_t i) override { erase(next(begin(), i)); }
371 //----------------------------------------------------------------------------
372 auto begin() { return m_data.begin(); }
373 auto begin() const { return m_data.begin(); }
374 //----------------------------------------------------------------------------
375 auto end() { return m_data.end(); }
376 auto end() const { return m_data.end(); }
377 //----------------------------------------------------------------------------
378 template <typename... Ts>
379 auto emplace_back(Ts&&... ts) -> void {
380 m_data.emplace_back(std::forward<Ts>(ts)...);
381 }
382 //----------------------------------------------------------------------------
383 auto clear() -> void override {
384 m_data.clear();
385 m_data.shrink_to_fit();
386 }
387 //----------------------------------------------------------------------------
388 auto internal_container() const -> const auto& { return m_data; }
389 //----------------------------------------------------------------------------
390 auto data() const { return m_data.data(); }
391 //----------------------------------------------------------------------------
392 auto size() const { return m_data.size(); }
393 //----------------------------------------------------------------------------
395 auto at(Handle handle) -> auto& {
396 assert(handle.index() < m_data.size());
397 return m_data.at(handle.index());
398 }
399 //----------------------------------------------------------------------------
401 auto at(Handle handle) const -> const auto& {
402 assert(handle.index() < m_data.size());
403 return m_data.at(handle.index());
404 }
405 //----------------------------------------------------------------------------
407 auto operator[](Handle handle) -> auto& {
408 assert(handle.index() < m_data.size());
409 return m_data[handle.index()];
410 }
411 //----------------------------------------------------------------------------
413 auto operator[](Handle handle) const -> const auto& {
414 assert(handle.index() < m_data.size());
415 return m_data[handle.index()];
416 }
417 //----------------------------------------------------------------------------
419 auto operator[](std::size_t const i) -> auto& {
420 assert(i < m_data.size());
421 return m_data[i];
422 }
423 //----------------------------------------------------------------------------
425 auto operator[](std::size_t const i) const -> const auto& {
426 assert(i < m_data.size());
427 return m_data[i];
428 }
429 //----------------------------------------------------------------------------
430 [[nodiscard]] auto type() const -> const std::type_info& override {
431 return typeid(ValueType);
432 }
433 //----------------------------------------------------------------------------
434 auto clone() const -> std::unique_ptr<parent_type> override {
435 return std::unique_ptr<this_type>{new this_type{*this}};
436 }
437};
438
439//==============================================================================
440} // namespace tatooine
441//==============================================================================
442#endif
Definition: algorithm.h:6
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto next(Iter iter)
Definition: iterator_facade.h:325
Definition: property.h:244
virtual void erase(std::size_t)=0
Resize storage to hold n elements.
virtual void resize(std::size_t n)=0
Resize storage to hold n elements.
deque_property(const deque_property &other)=default
virtual auto clone() const -> std::unique_ptr< this_type >=0
virtual void push_back()=0
pushes element at back
virtual auto type() const -> const std::type_info &=0
for identifying type.
auto cast_to_typed() const -> decltype(auto)
Definition: property.h:285
auto cast_to_typed() -> decltype(auto)
Definition: property.h:280
deque_property(deque_property &&other) noexcept=default
virtual void clear()=0
Free unused memory.
auto operator=(const deque_property &) -> deque_property &=default
virtual void push_front()=0
pushes element at front
auto holds_type() const
Definition: property.h:275
auto operator=(deque_property &&) noexcept -> deque_property &
Definition: handle.h:14
auto index() const
Definition: handle.h:64
Definition: property.h:293
auto emplace_back(Ts &&... ts) -> void
Definition: property.h:379
auto operator=(const typed_deque_property &other) -> auto &
Definition: property.h:327
auto clone() const -> std::unique_ptr< parent_type > override
Definition: property.h:434
typename container_type::const_iterator const_iterator
Definition: property.h:306
typename container_type::const_pointer const_pointer
Definition: property.h:304
auto erase(iterator first, iterator last)
Definition: property.h:362
auto end()
Definition: property.h:375
auto back() const -> const auto &
Definition: property.h:356
auto size()
Definition: property.h:341
auto back() -> auto &
Definition: property.h:355
auto internal_container() const -> const auto &
Definition: property.h:388
typename container_type::reverse_iterator reverse_iterator
Definition: property.h:307
typename container_type::pointer pointer
Definition: property.h:303
void push_back() override
pushes element at back
Definition: property.h:346
auto clear() -> void override
Free unused memory.
Definition: property.h:383
std::deque< ValueType > container_type
Definition: property.h:296
typename container_type::allocator_type allocator_type
Definition: property.h:298
typename container_type::difference_type difference_type
Definition: property.h:300
auto erase(iterator pos)
Definition: property.h:358
auto operator=(typed_deque_property &&other) noexcept -> auto &
Definition: property.h:334
typed_deque_property(typed_deque_property &&other) noexcept
Definition: property.h:322
typename container_type::reference reference
Definition: property.h:301
ValueType m_value
Definition: property.h:313
auto operator[](std::size_t const i) const -> const auto &
Const access to the i'th element.
Definition: property.h:425
auto operator[](Handle handle) -> auto &
Access the i'th element.
Definition: property.h:407
auto operator[](Handle handle) const -> const auto &
Const access to the i'th element.
Definition: property.h:413
void erase(std::size_t i) override
Resize storage to hold n elements.
Definition: property.h:370
auto type() const -> const std::type_info &override
for identifying type.
Definition: property.h:430
void resize(std::size_t n) override
Resize storage to hold n elements.
Definition: property.h:344
void push_front() override
pushes element at front
Definition: property.h:349
auto size() const
Definition: property.h:392
typename container_type::iterator iterator
Definition: property.h:305
auto begin() const
Definition: property.h:373
typed_deque_property(const ValueType &value=ValueType{})
Definition: property.h:316
void push_front(const ValueType &value)
Definition: property.h:350
auto erase(const_iterator first, const_iterator last)
Definition: property.h:366
auto front() const -> const auto &
Definition: property.h:353
typename container_type::const_reverse_iterator const_reverse_iterator
Definition: property.h:309
typename container_type::const_reference const_reference
Definition: property.h:302
auto at(Handle handle) const -> const auto &
Const access to the i'th element.
Definition: property.h:401
auto erase(const_iterator pos)
Definition: property.h:360
auto data() const
Definition: property.h:390
void push_back(const ValueType &value)
Definition: property.h:347
auto end() const
Definition: property.h:376
container_type m_data
Definition: property.h:312
auto front() -> auto &
Definition: property.h:352
typename container_type::value_type value_type
Definition: property.h:297
typename container_type::size_type size_type
Definition: property.h:299
auto operator[](std::size_t const i) -> auto &
Access the i'th element.
Definition: property.h:419
typed_deque_property(const typed_deque_property &other)
Definition: property.h:319
auto at(Handle handle) -> auto &
Access the i'th element.
Definition: property.h:395
auto begin()
Definition: property.h:372
Definition: property.h:66
std::vector< ValueType > container_type
Definition: property.h:69
auto size()
Definition: property.h:114
typename container_type::size_type size_type
Definition: property.h:72
typed_vector_property(typed_vector_property &&other) noexcept
Definition: property.h:95
auto data() const
Definition: property.h:161
auto end() const
Definition: property.h:149
auto erase(const_iterator pos)
Definition: property.h:131
typename container_type::const_reference const_reference
Definition: property.h:75
auto back() const -> const auto &
Definition: property.h:127
void push_back() override
pushes element at back
Definition: property.h:120
auto operator[](Handle handle) const -> const auto &
Const access to the i'th element.
Definition: property.h:198
auto operator=(const typed_vector_property &other) -> auto &
Definition: property.h:100
auto back() -> auto &
Definition: property.h:126
typename container_type::difference_type difference_type
Definition: property.h:73
void reserve(std::size_t n) override
Reserve memory for n elements.
Definition: property.h:116
typename container_type::allocator_type allocator_type
Definition: property.h:71
typename container_type::const_iterator const_iterator
Definition: property.h:79
auto operator=(typed_vector_property &&other) noexcept -> auto &
Definition: property.h:107
container_type m_data
Definition: property.h:85
typename container_type::const_reverse_iterator const_reverse_iterator
Definition: property.h:82
void push_back(const ValueType &value)
Definition: property.h:121
typename container_type::reference reference
Definition: property.h:74
auto front() const -> const auto &
Definition: property.h:124
auto at(Handle handle) -> auto &
Access the i'th element.
Definition: property.h:180
void clear() override
Free unused memory.
Definition: property.h:156
auto at(Handle handle) const -> const auto &
Const access to the i'th element.
Definition: property.h:186
typename container_type::pointer pointer
Definition: property.h:76
auto begin()
Definition: property.h:145
auto at(std::size_t const i) -> auto &
Access the i'th element.
Definition: property.h:168
auto front() -> auto &
Definition: property.h:123
void resize(std::size_t n) override
Resize storage to hold n elements.
Definition: property.h:118
typed_vector_property(const ValueType &value=ValueType{})
Definition: property.h:89
auto erase(iterator first, iterator last)
Definition: property.h:133
auto size() const
Definition: property.h:165
auto operator[](Handle handle) -> auto &
Access the i'th element.
Definition: property.h:192
typename container_type::const_pointer const_pointer
Definition: property.h:77
ValueType m_value
Definition: property.h:86
auto clone() const -> std::unique_ptr< parent_type > override
Definition: property.h:219
auto type() const -> const std::type_info &override
for identifying type.
Definition: property.h:215
auto erase(iterator pos)
Definition: property.h:129
auto begin() const
Definition: property.h:146
auto internal_container() const -> auto const &
Definition: property.h:163
auto at(std::size_t const i) const -> const auto &
Const access to the i'th element.
Definition: property.h:174
void emplace_back(Ts &&... ts)
Definition: property.h:152
typename container_type::reverse_iterator reverse_iterator
Definition: property.h:80
auto end()
Definition: property.h:148
auto erase(const_iterator first, const_iterator last)
Definition: property.h:137
auto erase(std::size_t i) -> void override
Resize storage to hold n elements.
Definition: property.h:141
typed_vector_property(const typed_vector_property &other)
Definition: property.h:92
typename container_type::value_type value_type
Definition: property.h:70
typename container_type::iterator iterator
Definition: property.h:78
auto operator[](std::size_t const i) -> auto &
Access the i'th element.
Definition: property.h:204
auto operator[](std::size_t const i) const -> const auto &
Const access to the i'th element.
Definition: property.h:210
auto clean(std::set< Handle > const &invalid_handles) -> void override
Definition: property.h:223
Definition: property.h:16
virtual auto clean(std::set< Handle > const &) -> void=0
virtual auto clone() const -> std::unique_ptr< this_type >=0
auto operator=(const vector_property &) -> vector_property &=default
virtual void clear()=0
Free unused memory.
auto cast_to_typed() -> decltype(auto)
Definition: property.h:54
auto operator=(vector_property &&) noexcept -> vector_property &=default
auto holds_type() const
Definition: property.h:47
virtual auto type() const -> const std::type_info &=0
for identifying type.
virtual void push_back()=0
pushes element at back
virtual void erase(std::size_t)=0
Resize storage to hold n elements.
virtual void reserve(std::size_t n)=0
Reserve memory for n elements.
vector_property(vector_property &&other) noexcept=default
auto cast_to_typed() const -> decltype(auto)
Definition: property.h:59
vector_property(const vector_property &other)=default
virtual void resize(std::size_t n)=0
Resize storage to hold n elements.