1 #ifndef _DEPOOLARRAY_HPP
2 #define _DEPOOLARRAY_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements C++ Base Library
5 * -----------------------------
6 *
7 * Copyright 2014 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Array template backed by memory pool.
24 *//*--------------------------------------------------------------------*/
25
26 #include "deDefs.hpp"
27 #include "deMemPool.hpp"
28 #include "deInt32.h"
29
30 #include <iterator>
31
32 namespace de
33 {
34
35 //! Self-test for PoolArray
36 void PoolArray_selfTest(void);
37
38 template <typename T, uint32_t Alignment>
39 class PoolArrayConstIterator;
40
41 template <typename T, uint32_t Alignment>
42 class PoolArrayIterator;
43
44 /*--------------------------------------------------------------------*//*!
45 * \brief Array template backed by memory pool
46 *
47 * \note Memory in PoolArray is not contiguous so pointer arithmetic
48 * to access next element(s) doesn't work.
49 * \todo [2013-02-11 pyry] Make elements per page template argument.
50 *//*--------------------------------------------------------------------*/
51 template <typename T,
52 uint32_t Alignment = (sizeof(T) > sizeof(void *) ? (uint32_t)sizeof(void *) : (uint32_t)sizeof(T))>
53 class PoolArray
54 {
55 public:
56 typedef PoolArrayIterator<T, Alignment> Iterator;
57 typedef PoolArrayConstIterator<T, Alignment> ConstIterator;
58
59 typedef Iterator iterator;
60 typedef ConstIterator const_iterator;
61
62 explicit PoolArray(MemPool *pool);
63 PoolArray(MemPool *pool, const PoolArray<T, Alignment> &other);
64 ~PoolArray(void);
65
66 void clear(void);
67
68 void reserve(uintptr_t capacity);
69 void resize(uintptr_t size);
70 void resize(uintptr_t size, const T &value);
71
size(void) const72 uintptr_t size(void) const
73 {
74 return m_numElements;
75 }
empty(void) const76 bool empty(void) const
77 {
78 return m_numElements == 0;
79 }
80
81 void pushBack(const T &value);
82 T popBack(void);
83
at(intptr_t ndx) const84 const T &at(intptr_t ndx) const
85 {
86 return *getPtr(ndx);
87 }
at(intptr_t ndx)88 T &at(intptr_t ndx)
89 {
90 return *getPtr(ndx);
91 }
92
operator [](intptr_t ndx) const93 const T &operator[](intptr_t ndx) const
94 {
95 return at(ndx);
96 }
operator [](intptr_t ndx)97 T &operator[](intptr_t ndx)
98 {
99 return at(ndx);
100 }
101
begin(void)102 Iterator begin(void)
103 {
104 return Iterator(this, 0);
105 }
end(void)106 Iterator end(void)
107 {
108 return Iterator(this, (intptr_t)m_numElements);
109 }
110
begin(void) const111 ConstIterator begin(void) const
112 {
113 return ConstIterator(this, 0);
114 }
end(void) const115 ConstIterator end(void) const
116 {
117 return ConstIterator(this, (intptr_t)m_numElements);
118 }
119
front(void) const120 const T &front(void) const
121 {
122 return at(0);
123 }
front(void)124 T &front(void)
125 {
126 return at(0);
127 }
128
back(void) const129 const T &back(void) const
130 {
131 return at(m_numElements - 1);
132 }
back(void)133 T &back(void)
134 {
135 return at(m_numElements - 1);
136 }
137
138 private:
139 enum
140 {
141 ELEMENTS_PER_PAGE_LOG2 = 4 //!< 16 elements per page.
142 };
143
144 PoolArray(const PoolArray<T, Alignment>
145 &other); // \note Default copy ctor is not allowed, use PoolArray(pool, copy) instead.
146
147 T *getPtr(intptr_t ndx) const;
148
149 MemPool *m_pool;
150
151 uintptr_t m_numElements; //!< Number of elements in the array.
152 uintptr_t m_capacity; //!< Number of allocated elements in the array.
153
154 uintptr_t m_pageTableCapacity; //!< Size of the page table.
155 void **m_pageTable; //!< Pointer to the page table.
156 };
157
158 template <typename T, uint32_t Alignment>
159 class PoolArrayIteratorBase
160 {
161 public:
PoolArrayIteratorBase(uintptr_t ndx)162 PoolArrayIteratorBase(uintptr_t ndx) : m_ndx(ndx)
163 {
164 }
~PoolArrayIteratorBase(void)165 ~PoolArrayIteratorBase(void)
166 {
167 }
168
getNdx(void) const169 intptr_t getNdx(void) const throw()
170 {
171 return m_ndx;
172 }
173
174 protected:
175 intptr_t m_ndx;
176 };
177
178 template <typename T, uint32_t Alignment>
179 class PoolArrayConstIterator : public PoolArrayIteratorBase<T, Alignment>
180 {
181 public:
182 PoolArrayConstIterator(void);
183 PoolArrayConstIterator(const PoolArray<T, Alignment> *array, intptr_t ndx);
184 PoolArrayConstIterator(const PoolArrayIterator<T, Alignment> &iterator);
185 ~PoolArrayConstIterator(void);
186
187 // \note Default assignment and copy-constructor are auto-generated.
188
getArray(void) const189 const PoolArray<T, Alignment> *getArray(void) const throw()
190 {
191 return m_array;
192 }
193
194 // De-reference operators.
operator ->(void) const195 const T *operator->(void) const throw()
196 {
197 return &(*m_array)[this->m_ndx];
198 }
operator *(void) const199 const T &operator*(void) const throw()
200 {
201 return (*m_array)[this->m_ndx];
202 }
operator [](uintptr_t offs) const203 const T &operator[](uintptr_t offs) const throw()
204 {
205 return (*m_array)[this->m_ndx + offs];
206 }
207
208 // Pre-increment and decrement.
operator ++(void)209 PoolArrayConstIterator<T, Alignment> &operator++(void)
210 {
211 this->m_ndx += 1;
212 return *this;
213 }
operator --(void)214 PoolArrayConstIterator<T, Alignment> &operator--(void)
215 {
216 this->m_ndx -= 1;
217 return *this;
218 }
219
220 // Post-increment and decrement.
operator ++(int)221 PoolArrayConstIterator<T, Alignment> operator++(int)
222 {
223 PoolArrayConstIterator<T, Alignment> copy(*this);
224 this->m_ndx += 1;
225 return copy;
226 }
operator --(int)227 PoolArrayConstIterator<T, Alignment> operator--(int)
228 {
229 PoolArrayConstIterator<T, Alignment> copy(*this);
230 this->m_ndx -= 1;
231 return copy;
232 }
233
234 // Compound assignment.
operator +=(intptr_t offs)235 PoolArrayConstIterator<T, Alignment> &operator+=(intptr_t offs)
236 {
237 this->m_ndx += offs;
238 return *this;
239 }
operator -=(intptr_t offs)240 PoolArrayConstIterator<T, Alignment> &operator-=(intptr_t offs)
241 {
242 this->m_ndx -= offs;
243 return *this;
244 }
245
246 // Assignment from non-const.
247 PoolArrayConstIterator<T, Alignment> &operator=(const PoolArrayIterator<T, Alignment> &iter);
248
249 private:
250 const PoolArray<T, Alignment> *m_array;
251 };
252
253 template <typename T, uint32_t Alignment>
254 class PoolArrayIterator : public PoolArrayIteratorBase<T, Alignment>
255 {
256 public:
257 PoolArrayIterator(void);
258 PoolArrayIterator(PoolArray<T, Alignment> *array, intptr_t ndx);
259 ~PoolArrayIterator(void);
260
261 // \note Default assignment and copy-constructor are auto-generated.
262
getArray(void) const263 PoolArray<T, Alignment> *getArray(void) const throw()
264 {
265 return m_array;
266 }
267
268 // De-reference operators.
operator ->(void) const269 T *operator->(void) const throw()
270 {
271 return &(*m_array)[this->m_ndx];
272 }
operator *(void) const273 T &operator*(void) const throw()
274 {
275 return (*m_array)[this->m_ndx];
276 }
operator [](uintptr_t offs) const277 T &operator[](uintptr_t offs) const throw()
278 {
279 return (*m_array)[this->m_ndx + offs];
280 }
281
282 // Pre-increment and decrement.
operator ++(void)283 PoolArrayIterator<T, Alignment> &operator++(void)
284 {
285 this->m_ndx += 1;
286 return *this;
287 }
operator --(void)288 PoolArrayIterator<T, Alignment> &operator--(void)
289 {
290 this->m_ndx -= 1;
291 return *this;
292 }
293
294 // Post-increment and decrement.
operator ++(int)295 PoolArrayIterator<T, Alignment> operator++(int)
296 {
297 PoolArrayIterator<T, Alignment> copy(*this);
298 this->m_ndx += 1;
299 return copy;
300 }
operator --(int)301 PoolArrayIterator<T, Alignment> operator--(int)
302 {
303 PoolArrayIterator<T, Alignment> copy(*this);
304 this->m_ndx -= 1;
305 return copy;
306 }
307
308 // Compound assignment.
operator +=(intptr_t offs)309 PoolArrayIterator<T, Alignment> &operator+=(intptr_t offs)
310 {
311 this->m_ndx += offs;
312 return *this;
313 }
operator -=(intptr_t offs)314 PoolArrayIterator<T, Alignment> &operator-=(intptr_t offs)
315 {
316 this->m_ndx -= offs;
317 return *this;
318 }
319
320 private:
321 PoolArray<T, Alignment> *m_array;
322 };
323
324 // Initializer helper for array.
325 template <typename T>
326 struct PoolArrayElement
327 {
constructDefaultde::PoolArrayElement328 static void constructDefault(void *ptr)
329 {
330 new (ptr) T();
331 } //!< Called for non-initialized memory.
constructCopyde::PoolArrayElement332 static void constructCopy(void *ptr, const T &val)
333 {
334 new (ptr) T(val);
335 } //!< Called for non-initialized memory when initial value is provided.
destructde::PoolArrayElement336 static void destruct(T *ptr)
337 {
338 ptr->~T();
339 } //!< Called when element is destructed.
340 };
341
342 // Specialization for basic types.
343 #define DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(TYPE) \
344 template <> \
345 struct PoolArrayElement<TYPE> \
346 { \
347 static void constructDefault(void *) \
348 { \
349 } \
350 static void constructCopy(void *ptr, TYPE val) \
351 { \
352 *(TYPE *)ptr = val; \
353 } \
354 static void destruct(TYPE *) \
355 { \
356 } \
357 }
358
359 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(uint8_t);
360 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(uint16_t);
361 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(uint32_t);
362 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(uint64_t);
363 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(int8_t);
364 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(int16_t);
365 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(int32_t);
366 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(int64_t);
367
368 // PoolArray<T> implementation.
369
370 template <typename T, uint32_t Alignment>
PoolArray(MemPool * pool)371 PoolArray<T, Alignment>::PoolArray(MemPool *pool)
372 : m_pool(pool)
373 , m_numElements(0)
374 , m_capacity(0)
375 , m_pageTableCapacity(0)
376 , m_pageTable(0)
377 {
378 DE_ASSERT(deIsPowerOfTwo32(Alignment));
379 }
380
381 template <typename T, uint32_t Alignment>
~PoolArray(void)382 PoolArray<T, Alignment>::~PoolArray(void)
383 {
384 // Clear resets values to T()
385 clear();
386 }
387
388 template <typename T, uint32_t Alignment>
clear(void)389 inline void PoolArray<T, Alignment>::clear(void)
390 {
391 resize(0);
392 }
393
394 template <typename T, uint32_t Alignment>
resize(uintptr_t newSize)395 inline void PoolArray<T, Alignment>::resize(uintptr_t newSize)
396 {
397 if (newSize < m_numElements)
398 {
399 // Destruct elements that are no longer active.
400 for (uintptr_t ndx = newSize; ndx < m_numElements; ndx++)
401 PoolArrayElement<T>::destruct(getPtr(ndx));
402
403 m_numElements = newSize;
404 }
405 else if (newSize > m_numElements)
406 {
407 uintptr_t prevSize = m_numElements;
408
409 reserve(newSize);
410 m_numElements = newSize;
411
412 // Fill new elements with default values
413 for (uintptr_t ndx = prevSize; ndx < m_numElements; ndx++)
414 PoolArrayElement<T>::constructDefault(getPtr(ndx));
415 }
416 }
417
418 template <typename T, uint32_t Alignment>
resize(uintptr_t newSize,const T & value)419 inline void PoolArray<T, Alignment>::resize(uintptr_t newSize, const T &value)
420 {
421 if (newSize < m_numElements)
422 resize(newSize); // value is not used
423 else if (newSize > m_numElements)
424 {
425 uintptr_t prevSize = m_numElements;
426
427 reserve(newSize);
428 m_numElements = newSize;
429
430 // Fill new elements with copies of value
431 for (uintptr_t ndx = prevSize; ndx < m_numElements; ndx++)
432 PoolArrayElement<T>::constructCopy(getPtr(ndx), value);
433 }
434 }
435
436 template <typename T, uint32_t Alignment>
reserve(uintptr_t capacity)437 inline void PoolArray<T, Alignment>::reserve(uintptr_t capacity)
438 {
439 if (capacity >= m_capacity)
440 {
441 void *oldPageTable = DE_NULL;
442 uintptr_t oldPageTableSize = 0;
443
444 uintptr_t newCapacity = (uintptr_t)deAlignPtr((void *)capacity, 1 << ELEMENTS_PER_PAGE_LOG2);
445 uintptr_t reqPageTableCapacity = newCapacity >> ELEMENTS_PER_PAGE_LOG2;
446
447 if (m_pageTableCapacity < reqPageTableCapacity)
448 {
449 uintptr_t newPageTableCapacity = max(2 * m_pageTableCapacity, reqPageTableCapacity);
450 void **newPageTable = (void **)m_pool->alloc(newPageTableCapacity * sizeof(void *));
451 uintptr_t i;
452
453 for (i = 0; i < m_pageTableCapacity; i++)
454 newPageTable[i] = m_pageTable[i];
455
456 for (; i < newPageTableCapacity; i++)
457 newPageTable[i] = DE_NULL;
458
459 // Grab information about old page table for recycling purposes.
460 oldPageTable = m_pageTable;
461 oldPageTableSize = m_pageTableCapacity * sizeof(T *);
462
463 m_pageTable = newPageTable;
464 m_pageTableCapacity = newPageTableCapacity;
465 }
466
467 // Allocate new pages.
468 {
469 uintptr_t elementSize = (uintptr_t)deAlignPtr((void *)(uintptr_t)sizeof(T), Alignment);
470 uintptr_t pageAllocSize = elementSize << ELEMENTS_PER_PAGE_LOG2;
471 uintptr_t pageTableNdx = m_capacity >> ELEMENTS_PER_PAGE_LOG2;
472
473 // Allocate new pages from recycled old page table.
474 for (;;)
475 {
476 void *newPage = deAlignPtr(oldPageTable, Alignment);
477 uintptr_t alignPadding = (uintptr_t)newPage - (uintptr_t)oldPageTable;
478
479 if (oldPageTableSize < pageAllocSize + alignPadding)
480 break; // No free space for alloc + alignment.
481
482 DE_ASSERT(m_pageTableCapacity > pageTableNdx);
483 DE_ASSERT(!m_pageTable[pageTableNdx]);
484 m_pageTable[pageTableNdx++] = newPage;
485
486 oldPageTable = (void *)((uint8_t *)newPage + pageAllocSize);
487 oldPageTableSize -= pageAllocSize + alignPadding;
488 }
489
490 // Allocate the rest of the needed pages from the pool.
491 for (; pageTableNdx < reqPageTableCapacity; pageTableNdx++)
492 {
493 DE_ASSERT(!m_pageTable[pageTableNdx]);
494 m_pageTable[pageTableNdx] = m_pool->alignedAlloc(pageAllocSize, Alignment);
495 }
496
497 m_capacity = pageTableNdx << ELEMENTS_PER_PAGE_LOG2;
498 DE_ASSERT(m_capacity >= newCapacity);
499 }
500 }
501 }
502
503 template <typename T, uint32_t Alignment>
pushBack(const T & value)504 inline void PoolArray<T, Alignment>::pushBack(const T &value)
505 {
506 resize(size() + 1);
507 at(size() - 1) = value;
508 }
509
510 template <typename T, uint32_t Alignment>
popBack(void)511 inline T PoolArray<T, Alignment>::popBack(void)
512 {
513 T val = at(size() - 1);
514 resize(size() - 1);
515 return val;
516 }
517
518 template <typename T, uint32_t Alignment>
getPtr(intptr_t ndx) const519 inline T *PoolArray<T, Alignment>::getPtr(intptr_t ndx) const
520 {
521 DE_ASSERT(inBounds<intptr_t>(ndx, 0, (intptr_t)m_numElements));
522 uintptr_t pageNdx = ((uintptr_t)ndx >> ELEMENTS_PER_PAGE_LOG2);
523 uintptr_t subNdx = (uintptr_t)ndx & ((1 << ELEMENTS_PER_PAGE_LOG2) - 1);
524 uintptr_t elemSize = (uintptr_t)deAlignPtr((void *)(uintptr_t)sizeof(T), Alignment);
525 T *ptr = (T *)((uint8_t *)m_pageTable[pageNdx] + (subNdx * elemSize));
526 DE_ASSERT(deIsAlignedPtr(ptr, Alignment));
527 return ptr;
528 }
529
530 // PoolArrayIteratorBase implementation
531
532 template <typename T, uint32_t Alignment>
operator ==(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)533 inline bool operator==(const PoolArrayIteratorBase<T, Alignment> &a, const PoolArrayIteratorBase<T, Alignment> &b)
534 {
535 // \todo [2013-02-08 pyry] Compare array ptr.
536 return a.getNdx() == b.getNdx();
537 }
538
539 template <typename T, uint32_t Alignment>
operator !=(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)540 inline bool operator!=(const PoolArrayIteratorBase<T, Alignment> &a, const PoolArrayIteratorBase<T, Alignment> &b)
541 {
542 // \todo [2013-02-08 pyry] Compare array ptr.
543 return a.getNdx() != b.getNdx();
544 }
545
546 template <typename T, uint32_t Alignment>
operator <(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)547 inline bool operator<(const PoolArrayIteratorBase<T, Alignment> &a, const PoolArrayIteratorBase<T, Alignment> &b)
548 {
549 return a.getNdx() < b.getNdx();
550 }
551
552 template <typename T, uint32_t Alignment>
operator >(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)553 inline bool operator>(const PoolArrayIteratorBase<T, Alignment> &a, const PoolArrayIteratorBase<T, Alignment> &b)
554 {
555 return a.getNdx() > b.getNdx();
556 }
557
558 template <typename T, uint32_t Alignment>
operator <=(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)559 inline bool operator<=(const PoolArrayIteratorBase<T, Alignment> &a, const PoolArrayIteratorBase<T, Alignment> &b)
560 {
561 return a.getNdx() <= b.getNdx();
562 }
563
564 template <typename T, uint32_t Alignment>
operator >=(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)565 inline bool operator>=(const PoolArrayIteratorBase<T, Alignment> &a, const PoolArrayIteratorBase<T, Alignment> &b)
566 {
567 return a.getNdx() >= b.getNdx();
568 }
569
570 // PoolArrayConstIterator<T> implementation
571
572 template <typename T, uint32_t Alignment>
PoolArrayConstIterator(void)573 inline PoolArrayConstIterator<T, Alignment>::PoolArrayConstIterator(void)
574 : PoolArrayIteratorBase<T, Alignment>(0)
575 , m_array(DE_NULL)
576 {
577 }
578
579 template <typename T, uint32_t Alignment>
PoolArrayConstIterator(const PoolArray<T,Alignment> * array,intptr_t ndx)580 inline PoolArrayConstIterator<T, Alignment>::PoolArrayConstIterator(const PoolArray<T, Alignment> *array, intptr_t ndx)
581 : PoolArrayIteratorBase<T, Alignment>(ndx)
582 , m_array(array)
583 {
584 }
585
586 template <typename T, uint32_t Alignment>
PoolArrayConstIterator(const PoolArrayIterator<T,Alignment> & iter)587 inline PoolArrayConstIterator<T, Alignment>::PoolArrayConstIterator(const PoolArrayIterator<T, Alignment> &iter)
588 : PoolArrayIteratorBase<T, Alignment>(iter)
589 , m_array(iter.getArray())
590 {
591 }
592
593 template <typename T, uint32_t Alignment>
~PoolArrayConstIterator(void)594 inline PoolArrayConstIterator<T, Alignment>::~PoolArrayConstIterator(void)
595 {
596 }
597
598 // Arithmetic operators.
599
600 template <typename T, uint32_t Alignment>
operator +(const PoolArrayConstIterator<T,Alignment> & iter,intptr_t offs)601 inline PoolArrayConstIterator<T, Alignment> operator+(const PoolArrayConstIterator<T, Alignment> &iter, intptr_t offs)
602 {
603 return PoolArrayConstIterator<T, Alignment>(iter->getArray(), iter->getNdx() + offs);
604 }
605
606 template <typename T, uint32_t Alignment>
operator +(uintptr_t offs,const PoolArrayConstIterator<T,Alignment> & iter)607 inline PoolArrayConstIterator<T, Alignment> operator+(uintptr_t offs, const PoolArrayConstIterator<T, Alignment> &iter)
608 {
609 return PoolArrayConstIterator<T, Alignment>(iter->getArray(), iter->getNdx() + offs);
610 }
611
612 template <typename T, uint32_t Alignment>
operator -(const PoolArrayConstIterator<T,Alignment> & iter,intptr_t offs)613 PoolArrayConstIterator<T, Alignment> operator-(const PoolArrayConstIterator<T, Alignment> &iter, intptr_t offs)
614 {
615 return PoolArrayConstIterator<T, Alignment>(iter.getArray(), iter.getNdx() - offs);
616 }
617
618 template <typename T, uint32_t Alignment>
operator -(const PoolArrayConstIterator<T,Alignment> & iter,const PoolArrayConstIterator<T,Alignment> & other)619 intptr_t operator-(const PoolArrayConstIterator<T, Alignment> &iter, const PoolArrayConstIterator<T, Alignment> &other)
620 {
621 return iter.getNdx() - other.getNdx();
622 }
623
624 // PoolArrayIterator<T> implementation.
625
626 template <typename T, uint32_t Alignment>
PoolArrayIterator(void)627 inline PoolArrayIterator<T, Alignment>::PoolArrayIterator(void)
628 : PoolArrayIteratorBase<T, Alignment>(0)
629 , m_array(DE_NULL)
630 {
631 }
632
633 template <typename T, uint32_t Alignment>
PoolArrayIterator(PoolArray<T,Alignment> * array,intptr_t ndx)634 inline PoolArrayIterator<T, Alignment>::PoolArrayIterator(PoolArray<T, Alignment> *array, intptr_t ndx)
635 : PoolArrayIteratorBase<T, Alignment>(ndx)
636 , m_array(array)
637 {
638 }
639
640 template <typename T, uint32_t Alignment>
~PoolArrayIterator(void)641 inline PoolArrayIterator<T, Alignment>::~PoolArrayIterator(void)
642 {
643 }
644
645 // Arithmetic operators.
646
647 template <typename T, uint32_t Alignment>
operator +(const PoolArrayIterator<T,Alignment> & iter,intptr_t offs)648 inline PoolArrayIterator<T, Alignment> operator+(const PoolArrayIterator<T, Alignment> &iter, intptr_t offs)
649 {
650 return PoolArrayIterator<T, Alignment>(iter.getArray(), iter.getNdx() + offs);
651 }
652
653 template <typename T, uint32_t Alignment>
operator +(uintptr_t offs,const PoolArrayIterator<T,Alignment> & iter)654 inline PoolArrayIterator<T, Alignment> operator+(uintptr_t offs, const PoolArrayIterator<T, Alignment> &iter)
655 {
656 return PoolArrayIterator<T, Alignment>(iter.getArray(), iter.getNdx() + offs);
657 }
658
659 template <typename T, uint32_t Alignment>
operator -(const PoolArrayIterator<T,Alignment> & iter,intptr_t offs)660 PoolArrayIterator<T, Alignment> operator-(const PoolArrayIterator<T, Alignment> &iter, intptr_t offs)
661 {
662 return PoolArrayIterator<T, Alignment>(iter.getArray(), iter.getNdx() - offs);
663 }
664
665 template <typename T, uint32_t Alignment>
operator -(const PoolArrayIterator<T,Alignment> & iter,const PoolArrayIterator<T,Alignment> & other)666 intptr_t operator-(const PoolArrayIterator<T, Alignment> &iter, const PoolArrayIterator<T, Alignment> &other)
667 {
668 return iter.getNdx() - other.getNdx();
669 }
670
671 } // namespace de
672
673 // std::iterator_traits specializations
674 namespace std
675 {
676
677 template <typename T, uint32_t Alignment>
678 struct iterator_traits<de::PoolArrayConstIterator<T, Alignment>>
679 {
680 typedef intptr_t difference_type;
681 typedef T value_type;
682 typedef const T *pointer;
683 typedef const T &reference;
684 typedef random_access_iterator_tag iterator_category;
685 };
686
687 template <typename T, uint32_t Alignment>
688 struct iterator_traits<de::PoolArrayIterator<T, Alignment>>
689 {
690 typedef intptr_t difference_type;
691 typedef T value_type;
692 typedef T *pointer;
693 typedef T &reference;
694 typedef random_access_iterator_tag iterator_category;
695 };
696
697 } // namespace std
698
699 #endif // _DEPOOLARRAY_HPP
700