xref: /aosp_15_r20/external/deqp/framework/delibs/decpp/dePoolArray.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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