Radium Engine  1.5.20
Loading...
Searching...
No Matches
IndexMap.hpp
1#pragma once
2
3#include <Core/RaCore.hpp>
4
5#include <algorithm>
6#include <assert.h>
7#include <deque>
8
9#include <Core/Utils/Index.hpp>
10
11namespace Ra {
12namespace Core {
13namespace Utils {
14
22template <typename T>
24{
25 public:
26 // ===============================================================================
27 // TYPEDEF
28 // ===============================================================================
29 using Container = typename std::deque<T>;
31
33 typename IndexContainer::const_iterator;
35 using Iterator =
36 typename Container::iterator;
37 using ConstIterator = typename Container::const_iterator;
39
40 // ===============================================================================
41 // CONSTRUCTOR
42 // ===============================================================================
43 inline IndexMap();
44 inline IndexMap( const IndexMap& id_map );
45
46 // ===============================================================================
47 // DESTRUCTOR
48 // ===============================================================================
49 inline ~IndexMap();
50
51 // ===============================================================================
52 // INSERT
53 // ===============================================================================
55 inline Index insert( const T& obj );
56
59 template <typename... Args>
60 inline Index emplace( const Args&&... args );
61
62 // ===============================================================================
63 // REMOVE
64 // ===============================================================================
66 inline bool remove( const Index& idx );
67
68 // ===============================================================================
69 // ACCESS
70 // ===============================================================================
72 inline const T& at( const Index& idx ) const;
73
75 inline T& access( const Index& idx );
76
77 // ===============================================================================
78 // SIZE
79 // ===============================================================================
80 inline size_t size() const;
81 inline void clear();
82
83 // ===============================================================================
84 // QUERY
85 // ===============================================================================
86 inline bool empty() const;
87 inline bool full() const;
88 inline bool contains( const Index& idx )
89 const;
90 inline Index index( const uint i )
91 const;
92
93 // ===============================================================================
94 // OPERATOR
95 // ===============================================================================
96 inline T& operator[]( const Index& idx );
97 inline const T& operator[](
98 const Index& idx ) const;
99
100 // ===============================================================================
101 // INDEX ITERATOR
102 // ===============================================================================
103 inline ConstIndexIterator
104 cbegin_index() const;
105 inline ConstIndexIterator
106 cend_index() const;
107
108 // ===============================================================================
109 // DATA ITERATOR
110 // ===============================================================================
111 inline Iterator begin();
112 inline Iterator end();
113 inline ConstIterator begin() const;
114 inline ConstIterator
115 end() const;
116 inline ConstIterator
117 cbegin() const;
118 inline ConstIterator
119 cend() const;
120
121 protected:
122 // Member variables
123 Container m_data;
125
126 private:
127 // ===============================================================================
128 // FREE LIST MANAGEMENT
129 // ===============================================================================
130 inline void push_free_index( const Index& idx );
131 inline bool pop_free_index( Index& idx );
132
133 // ===============================================================================
134 // HELPER FUNCTIONS
135 // ===============================================================================
136 // These function return an iterator to an object from an interator in an index.
137 inline ConstIterator citfromIndex( const ConstIndexIterator& it )
138 const;
139 inline Iterator
140 itfromIndex( const ConstIndexIterator&
141 it );
142 inline size_t idxfromIndex( const ConstIndexIterator& it )
143 const;
144
145 private:
146 // Member variables
147 IndexContainer m_free;
148};
149
150// ===============================================================================
151// CONSTRUCTOR
152// ===============================================================================
153template <typename T>
154IndexMap<T>::IndexMap() : m_data(), m_index(), m_free( 1, Index( 0 ) ) {}
155
156template <typename T>
158 m_data( id_map.m_data ), m_index( id_map.m_index ), m_free( id_map.m_free ) {}
159
160// ===============================================================================
161// DESTRUCTOR
162// ===============================================================================
163template <typename T>
165
166// ===============================================================================
167// INSERT
168// ===============================================================================
169template <typename T>
170inline Index IndexMap<T>::insert( const T& obj ) {
171 Index idx;
172 if ( pop_free_index( idx ) ) {
173 typename std::deque<Index>::iterator it =
174 std::lower_bound( m_index.begin(), m_index.end(), idx );
175 if ( it == m_index.end() ) { m_data.insert( m_data.end(), obj ); }
176 else { m_data.insert( citfromIndex( it ), obj ); }
177 m_index.insert( it, idx );
178 }
179 return idx;
180}
181
182template <typename T>
183template <typename... Args>
184Index IndexMap<T>::emplace( const Args&&... args ) {
185 Index idx;
186 if ( pop_free_index( idx ) ) {
187 typename std::deque<Index>::iterator it =
188 std::lower_bound( m_index.begin(), m_index.end(), idx );
189 if ( it == m_index.end() ) { m_data.emplace( m_data.end(), args... ); }
190 else { m_data.emplace( citfromIndex( it ), args... ); }
191 m_index.insert( it, idx );
192 }
193 return idx;
194}
195
196// ===============================================================================
197// REMOVE
198// ===============================================================================
199template <typename T>
200inline bool IndexMap<T>::remove( const Index& idx ) {
201 typename std::deque<Index>::iterator it = std::find( m_index.begin(), m_index.end(), idx );
202 if ( it == m_index.end() ) { return false; }
203 m_data.erase( itfromIndex( it ) );
204 m_index.erase( it );
205 push_free_index( idx );
206 return true;
207}
208
209// ===============================================================================
210// ACCESS
211// ===============================================================================
212template <typename T>
213inline const T& IndexMap<T>::at( const Index& idx ) const {
214 typename std::deque<Index>::const_iterator it =
215 std::find( m_index.begin(), m_index.end(), idx );
216 CORE_ASSERT( it != m_index.end(), "Index not found" );
217 return m_data.at( idxfromIndex( it ) );
218}
219
220template <typename T>
221inline T& IndexMap<T>::access( const Index& idx ) {
222 typename std::deque<Index>::iterator it = std::find( m_index.begin(), m_index.end(), idx );
223 CORE_ASSERT( ( it != m_index.end() ), "Index not found" );
224 return *itfromIndex( it );
225}
226
227// ===============================================================================
228// SIZE
229// ===============================================================================
230template <typename T>
231inline size_t IndexMap<T>::size() const {
232 return m_data.size();
233}
234
235template <typename T>
236inline void IndexMap<T>::clear() {
237 m_index.clear();
238 m_data.clear();
239 m_free.clear();
240 m_free.push_back( Index( 0 ) );
241}
242
243// ===============================================================================
244// QUERY
245// ===============================================================================
246template <typename T>
247inline bool IndexMap<T>::empty() const {
248 return m_data.empty();
249}
250
251template <typename T>
252inline bool IndexMap<T>::full() const {
253 return m_free.empty();
254}
255
256template <typename T>
257inline bool IndexMap<T>::contains( const Index& idx ) const {
258 typename std::deque<Index>::const_iterator it =
259 std::find( m_index.begin(), m_index.end(), idx );
260 return !( it == m_index.end() );
261}
262
263template <typename T>
264inline Index IndexMap<T>::index( const uint i ) const {
265 if ( i >= m_index.size() ) { return Index::Invalid(); }
266 return m_index.at( i );
267}
268
269// ===============================================================================
270// OPERATOR
271// ===============================================================================
272template <typename T>
273inline T& IndexMap<T>::operator[]( const Index& idx ) {
274 return access( idx );
275}
276
277template <typename T>
278inline const T& IndexMap<T>::operator[]( const Index& idx ) const {
279 return at( idx );
280}
281
282// ===============================================================================
283// INDEX ITERATOR
284// ===============================================================================
285template <typename T>
287 return m_index.cbegin();
288}
289
290template <typename T>
292 return m_index.cend();
293}
294
295// ===============================================================================
296// DATA ITERATOR
297// ===============================================================================
298template <typename T>
300 return m_data.begin();
301}
302
303template <typename T>
305 return m_data.end();
306}
307
308template <typename T>
310 return m_data.begin();
311}
312
313template <typename T>
315 return m_data.end();
316}
317
318template <typename T>
320 return m_data.cbegin();
321}
322
323template <typename T>
325 return m_data.cend();
326}
327
328// ===============================================================================
329// FREE LIST
330// ===============================================================================
331template <typename T>
332inline void IndexMap<T>::push_free_index( const Index& idx ) {
333 std::deque<Index>::iterator free_it = std::lower_bound( m_free.begin(), m_free.end(), idx );
334 m_free.insert( free_it, idx );
335 if ( m_data.empty() ) {
336 m_free.clear();
337 m_free.push_back( Index( 0 ) );
338 }
339}
340
341template <typename T>
342inline bool IndexMap<T>::pop_free_index( Index& idx ) {
343 if ( m_free.empty() ) {
344 idx = Index::Invalid();
345 return false;
346 }
347 idx = m_free.front();
348 m_free.pop_front();
349 if ( m_free.empty() ) {
350 Index next = idx + 1;
351 if ( next.isValid() ) {
352 if ( uint( next.getValue() ) > m_data.size() ) { m_free.push_back( next ); }
353 }
354 }
355 return true;
356}
357
358// ===============================================================================
359// HELPER FUNCTIONS
360// ===============================================================================
361
362template <typename T>
364IndexMap<T>::citfromIndex( const typename IndexMap<T>::ConstIndexIterator& it ) const {
365 auto dataIt = m_data.begin();
366 std::advance( dataIt, std::distance( m_index.cbegin(), it ) );
367 return dataIt;
368}
369
370template <typename T>
372IndexMap<T>::itfromIndex( const typename IndexMap<T>::ConstIndexIterator& it ) {
373 auto dataIt = m_data.begin();
374 std::advance( dataIt, std::distance( m_index.cbegin(), it ) );
375 return dataIt;
376}
377
378template <typename T>
379size_t IndexMap<T>::idxfromIndex( const typename IndexMap<T>::ConstIndexIterator& it ) const {
380 return std::distance( m_index.cbegin(), it );
381}
382
383} // namespace Utils
384} // namespace Core
385} // namespace Ra
T advance(T... args)
typename IndexContainer::const_iterator ConstIndexIterator
Where the indices are stored.
Definition IndexMap.hpp:32
Index index(const uint i) const
Return true if the IndexMap contains a object with the given index.
Definition IndexMap.hpp:264
const T & at(const Index &idx) const
Return a read-only ref to object with the given index. Crashes if index does not exist.
Definition IndexMap.hpp:213
typename std::deque< Index > IndexContainer
Where the objects are stored.
Definition IndexMap.hpp:30
IndexMap(const IndexMap &id_map)
Default constructor.
Definition IndexMap.hpp:157
~IndexMap()
Copy constructor.
Definition IndexMap.hpp:164
ConstIterator end() const
Return a iterator to the first object in the IndexMap.
Definition IndexMap.hpp:314
IndexContainer m_index
Objects in the IndexMap.
Definition IndexMap.hpp:124
bool remove(const Index &idx)
Remove the object with the given index. Return false if the operation failed.
Definition IndexMap.hpp:200
void clear()
Return the size of the IndexMap ( number of object contained ).
Definition IndexMap.hpp:236
Index emplace(const Args &&... args)
Definition IndexMap.hpp:184
T & access(const Index &idx)
Return a reference to the object with the given index. Crash if index does not exist.
Definition IndexMap.hpp:221
Index insert(const T &obj)
Destructor.
Definition IndexMap.hpp:170
Iterator end()
Return a iterator to the first object in the IndexMap.
Definition IndexMap.hpp:304
bool empty() const
Clear the IndexMap.
Definition IndexMap.hpp:247
Iterator begin()
Return a const iterator to the end of the indices of the IndexMap.
Definition IndexMap.hpp:299
ConstIndexIterator cbegin_index() const
Return a const reference to the object with given index.
Definition IndexMap.hpp:286
ConstIterator cbegin() const
Return a iterator to the end of the object list in the IndexMap.
Definition IndexMap.hpp:319
ConstIterator begin() const
Return a iterator to the end of the object list in the IndexMap.
Definition IndexMap.hpp:309
bool contains(const Index &idx) const
Return true if the IndexMap cannot contain more objects.
Definition IndexMap.hpp:257
Container m_data
Return a const iterator to the end of the object list in the IndexMap.
Definition IndexMap.hpp:123
const T & operator[](const Index &idx) const
Return a reference to the object with given index.
Definition IndexMap.hpp:278
bool full() const
Return true if the IndexMap is empty.
Definition IndexMap.hpp:252
typename Container::const_iterator ConstIterator
Iterator to the list of objects of the IndexMap.
Definition IndexMap.hpp:37
ConstIndexIterator cend_index() const
Return a const iterator to the first index in the IndexMap.
Definition IndexMap.hpp:291
T & operator[](const Index &idx)
Return the i-th index. Return an invalid index if i is out of bound.
Definition IndexMap.hpp:273
ConstIterator cend() const
Return a const iterator to the first object in the IndexMap.
Definition IndexMap.hpp:324
typename Container::iterator Iterator
Definition IndexMap.hpp:35
T distance(T... args)
T find(T... args)
T lower_bound(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3