Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
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 
11 namespace Ra {
12 namespace Core {
13 namespace Utils {
14 
22 template <typename T>
23 class IndexMap
24 {
25  public:
26  // ===============================================================================
27  // TYPEDEF
28  // ===============================================================================
29  using Container = typename std::deque<T>;
30  using IndexContainer = typename std::deque<Index>;
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 // ===============================================================================
153 template <typename T>
154 IndexMap<T>::IndexMap() : m_data(), m_index(), m_free( 1, Index( 0 ) ) {}
155 
156 template <typename T>
157 IndexMap<T>::IndexMap( const IndexMap& id_map ) :
158  m_data( id_map.m_data ), m_index( id_map.m_index ), m_free( id_map.m_free ) {}
159 
160 // ===============================================================================
161 // DESTRUCTOR
162 // ===============================================================================
163 template <typename T>
165 
166 // ===============================================================================
167 // INSERT
168 // ===============================================================================
169 template <typename T>
170 inline 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 
182 template <typename T>
183 template <typename... Args>
184 Index 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 // ===============================================================================
199 template <typename T>
200 inline 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 // ===============================================================================
212 template <typename T>
213 inline 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 
220 template <typename T>
221 inline 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 // ===============================================================================
230 template <typename T>
231 inline size_t IndexMap<T>::size() const {
232  return m_data.size();
233 }
234 
235 template <typename T>
236 inline 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 // ===============================================================================
246 template <typename T>
247 inline bool IndexMap<T>::empty() const {
248  return m_data.empty();
249 }
250 
251 template <typename T>
252 inline bool IndexMap<T>::full() const {
253  return m_free.empty();
254 }
255 
256 template <typename T>
257 inline 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 
263 template <typename T>
264 inline 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 // ===============================================================================
272 template <typename T>
273 inline T& IndexMap<T>::operator[]( const Index& idx ) {
274  return access( idx );
275 }
276 
277 template <typename T>
278 inline const T& IndexMap<T>::operator[]( const Index& idx ) const {
279  return at( idx );
280 }
281 
282 // ===============================================================================
283 // INDEX ITERATOR
284 // ===============================================================================
285 template <typename T>
287  return m_index.cbegin();
288 }
289 
290 template <typename T>
292  return m_index.cend();
293 }
294 
295 // ===============================================================================
296 // DATA ITERATOR
297 // ===============================================================================
298 template <typename T>
300  return m_data.begin();
301 }
302 
303 template <typename T>
305  return m_data.end();
306 }
307 
308 template <typename T>
310  return m_data.begin();
311 }
312 
313 template <typename T>
315  return m_data.end();
316 }
317 
318 template <typename T>
320  return m_data.cbegin();
321 }
322 
323 template <typename T>
325  return m_data.cend();
326 }
327 
328 // ===============================================================================
329 // FREE LIST
330 // ===============================================================================
331 template <typename T>
332 inline 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 
341 template <typename T>
342 inline 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 
362 template <typename T>
364 IndexMap<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 
370 template <typename T>
371 typename IndexMap<T>::Iterator
372 IndexMap<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 
378 template <typename T>
379 size_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
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
typename IndexContainer::const_iterator ConstIndexIterator
Where the indices are stored.
Definition: IndexMap.hpp:33
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
typename Container::iterator Iterator
Definition: IndexMap.hpp:36
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
Definition: Cage.cpp:3