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, deUint32 Alignment>
39 class PoolArrayConstIterator;
40
41 template<typename T, deUint32 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, deUint32 Alignment = (sizeof(T) > sizeof(void*) ? (deUint32)sizeof(void*) : (deUint32)sizeof(T))>
52 class PoolArray
53 {
54 public:
55 typedef PoolArrayIterator<T, Alignment> Iterator;
56 typedef PoolArrayConstIterator<T, Alignment> ConstIterator;
57
58 typedef Iterator iterator;
59 typedef ConstIterator const_iterator;
60
61 explicit PoolArray (MemPool* pool);
62 PoolArray (MemPool* pool, const PoolArray<T, Alignment>& other);
63 ~PoolArray (void);
64
65 void clear (void);
66
67 void reserve (deUintptr capacity);
68 void resize (deUintptr size);
69 void resize (deUintptr size, const T& value);
70
size(void) const71 deUintptr size (void) const { return m_numElements; }
empty(void) const72 bool empty (void) const { return m_numElements == 0;}
73
74 void pushBack (const T& value);
75 T popBack (void);
76
at(deIntptr ndx) const77 const T& at (deIntptr ndx) const { return *getPtr(ndx); }
at(deIntptr ndx)78 T& at (deIntptr ndx) { return *getPtr(ndx); }
79
operator [](deIntptr ndx) const80 const T& operator[] (deIntptr ndx) const { return at(ndx); }
operator [](deIntptr ndx)81 T& operator[] (deIntptr ndx) { return at(ndx); }
82
begin(void)83 Iterator begin (void) { return Iterator(this, 0); }
end(void)84 Iterator end (void) { return Iterator(this, (deIntptr)m_numElements); }
85
begin(void) const86 ConstIterator begin (void) const { return ConstIterator(this, 0); }
end(void) const87 ConstIterator end (void) const { return ConstIterator(this, (deIntptr)m_numElements); }
88
front(void) const89 const T& front (void) const { return at(0); }
front(void)90 T& front (void) { return at(0); }
91
back(void) const92 const T& back (void) const { return at(m_numElements-1); }
back(void)93 T& back (void) { return at(m_numElements-1); }
94
95 private:
96 enum
97 {
98 ELEMENTS_PER_PAGE_LOG2 = 4 //!< 16 elements per page.
99 };
100
101 PoolArray (const PoolArray<T, Alignment>& other); // \note Default copy ctor is not allowed, use PoolArray(pool, copy) instead.
102
103 T* getPtr (deIntptr ndx) const;
104
105 MemPool* m_pool;
106
107 deUintptr m_numElements; //!< Number of elements in the array.
108 deUintptr m_capacity; //!< Number of allocated elements in the array.
109
110 deUintptr m_pageTableCapacity; //!< Size of the page table.
111 void** m_pageTable; //!< Pointer to the page table.
112 };
113
114 template<typename T, deUint32 Alignment>
115 class PoolArrayIteratorBase
116 {
117 public:
PoolArrayIteratorBase(deUintptr ndx)118 PoolArrayIteratorBase (deUintptr ndx) : m_ndx(ndx) {}
~PoolArrayIteratorBase(void)119 ~PoolArrayIteratorBase (void) {}
120
getNdx(void) const121 deIntptr getNdx (void) const throw() { return m_ndx; }
122
123 protected:
124 deIntptr m_ndx;
125 };
126
127 template<typename T, deUint32 Alignment>
128 class PoolArrayConstIterator : public PoolArrayIteratorBase<T, Alignment>
129 {
130 public:
131 PoolArrayConstIterator (void);
132 PoolArrayConstIterator (const PoolArray<T, Alignment>* array, deIntptr ndx);
133 PoolArrayConstIterator (const PoolArrayIterator<T, Alignment>& iterator);
134 ~PoolArrayConstIterator (void);
135
136 // \note Default assignment and copy-constructor are auto-generated.
137
getArray(void) const138 const PoolArray<T, Alignment>* getArray (void) const throw() { return m_array; }
139
140 // De-reference operators.
operator ->(void) const141 const T* operator-> (void) const throw() { return &(*m_array)[this->m_ndx]; }
operator *(void) const142 const T& operator* (void) const throw() { return (*m_array)[this->m_ndx]; }
operator [](deUintptr offs) const143 const T& operator[] (deUintptr offs) const throw() { return (*m_array)[this->m_ndx+offs]; }
144
145 // Pre-increment and decrement.
operator ++(void)146 PoolArrayConstIterator<T, Alignment>& operator++ (void) { this->m_ndx += 1; return *this; }
operator --(void)147 PoolArrayConstIterator<T, Alignment>& operator-- (void) { this->m_ndx -= 1; return *this; }
148
149 // Post-increment and decrement.
operator ++(int)150 PoolArrayConstIterator<T, Alignment> operator++ (int) { PoolArrayConstIterator<T, Alignment> copy(*this); this->m_ndx +=1; return copy; }
operator --(int)151 PoolArrayConstIterator<T, Alignment> operator-- (int) { PoolArrayConstIterator<T, Alignment> copy(*this); this->m_ndx -=1; return copy; }
152
153 // Compound assignment.
operator +=(deIntptr offs)154 PoolArrayConstIterator<T, Alignment>& operator+= (deIntptr offs) { this->m_ndx += offs; return *this; }
operator -=(deIntptr offs)155 PoolArrayConstIterator<T, Alignment>& operator-= (deIntptr offs) { this->m_ndx -= offs; return *this; }
156
157 // Assignment from non-const.
158 PoolArrayConstIterator<T, Alignment>& operator= (const PoolArrayIterator<T, Alignment>& iter);
159
160 private:
161 const PoolArray<T, Alignment>* m_array;
162 };
163
164 template<typename T, deUint32 Alignment>
165 class PoolArrayIterator : public PoolArrayIteratorBase<T, Alignment>
166 {
167 public:
168 PoolArrayIterator (void);
169 PoolArrayIterator (PoolArray<T, Alignment>* array, deIntptr ndx);
170 ~PoolArrayIterator (void);
171
172 // \note Default assignment and copy-constructor are auto-generated.
173
getArray(void) const174 PoolArray<T, Alignment>* getArray (void) const throw() { return m_array; }
175
176 // De-reference operators.
operator ->(void) const177 T* operator-> (void) const throw() { return &(*m_array)[this->m_ndx]; }
operator *(void) const178 T& operator* (void) const throw() { return (*m_array)[this->m_ndx]; }
operator [](deUintptr offs) const179 T& operator[] (deUintptr offs) const throw() { return (*m_array)[this->m_ndx+offs]; }
180
181 // Pre-increment and decrement.
operator ++(void)182 PoolArrayIterator<T, Alignment>& operator++ (void) { this->m_ndx += 1; return *this; }
operator --(void)183 PoolArrayIterator<T, Alignment>& operator-- (void) { this->m_ndx -= 1; return *this; }
184
185 // Post-increment and decrement.
operator ++(int)186 PoolArrayIterator<T, Alignment> operator++ (int) { PoolArrayIterator<T, Alignment> copy(*this); this->m_ndx +=1; return copy; }
operator --(int)187 PoolArrayIterator<T, Alignment> operator-- (int) { PoolArrayIterator<T, Alignment> copy(*this); this->m_ndx -=1; return copy; }
188
189 // Compound assignment.
operator +=(deIntptr offs)190 PoolArrayIterator<T, Alignment>& operator+= (deIntptr offs) { this->m_ndx += offs; return *this; }
operator -=(deIntptr offs)191 PoolArrayIterator<T, Alignment>& operator-= (deIntptr offs) { this->m_ndx -= offs; return *this; }
192
193 private:
194 PoolArray<T, Alignment>* m_array;
195 };
196
197 // Initializer helper for array.
198 template<typename T>
199 struct PoolArrayElement
200 {
constructDefaultde::PoolArrayElement201 static void constructDefault (void* ptr) { new (ptr) T(); } //!< Called for non-initialized memory.
constructCopyde::PoolArrayElement202 static void constructCopy (void* ptr, const T& val) { new (ptr) T(val); } //!< Called for non-initialized memory when initial value is provided.
destructde::PoolArrayElement203 static void destruct (T* ptr) { ptr->~T(); } //!< Called when element is destructed.
204 };
205
206 // Specialization for basic types.
207 #define DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(TYPE) \
208 template<> struct PoolArrayElement<TYPE> { \
209 static void constructDefault (void*) {} \
210 static void constructCopy (void* ptr, TYPE val) { *(TYPE*)ptr = val; } \
211 static void destruct (TYPE*) {} \
212 }
213
214 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(deUint8);
215 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(deUint16);
216 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(deUint32);
217 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(deUint64);
218 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(deInt8);
219 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(deInt16);
220 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(deInt32);
221 DE_SPECIALIZE_POOL_ARRAY_ELEMENT_BASIC_TYPE(deInt64);
222
223 // PoolArray<T> implementation.
224
225 template<typename T, deUint32 Alignment>
PoolArray(MemPool * pool)226 PoolArray<T, Alignment>::PoolArray (MemPool* pool)
227 : m_pool (pool)
228 , m_numElements (0)
229 , m_capacity (0)
230 , m_pageTableCapacity (0)
231 , m_pageTable (0)
232 {
233 DE_ASSERT(deIsPowerOfTwo32(Alignment));
234 }
235
236 template<typename T, deUint32 Alignment>
~PoolArray(void)237 PoolArray<T, Alignment>::~PoolArray (void)
238 {
239 // Clear resets values to T()
240 clear();
241 }
242
243 template<typename T, deUint32 Alignment>
clear(void)244 inline void PoolArray<T, Alignment>::clear (void)
245 {
246 resize(0);
247 }
248
249 template<typename T, deUint32 Alignment>
resize(deUintptr newSize)250 inline void PoolArray<T, Alignment>::resize (deUintptr newSize)
251 {
252 if (newSize < m_numElements)
253 {
254 // Destruct elements that are no longer active.
255 for (deUintptr ndx = newSize; ndx < m_numElements; ndx++)
256 PoolArrayElement<T>::destruct(getPtr(ndx));
257
258 m_numElements = newSize;
259 }
260 else if (newSize > m_numElements)
261 {
262 deUintptr prevSize = m_numElements;
263
264 reserve(newSize);
265 m_numElements = newSize;
266
267 // Fill new elements with default values
268 for (deUintptr ndx = prevSize; ndx < m_numElements; ndx++)
269 PoolArrayElement<T>::constructDefault(getPtr(ndx));
270 }
271 }
272
273 template<typename T, deUint32 Alignment>
resize(deUintptr newSize,const T & value)274 inline void PoolArray<T, Alignment>::resize (deUintptr newSize, const T& value)
275 {
276 if (newSize < m_numElements)
277 resize(newSize); // value is not used
278 else if (newSize > m_numElements)
279 {
280 deUintptr prevSize = m_numElements;
281
282 reserve(newSize);
283 m_numElements = newSize;
284
285 // Fill new elements with copies of value
286 for (deUintptr ndx = prevSize; ndx < m_numElements; ndx++)
287 PoolArrayElement<T>::constructCopy(getPtr(ndx), value);
288 }
289 }
290
291 template<typename T, deUint32 Alignment>
reserve(deUintptr capacity)292 inline void PoolArray<T, Alignment>::reserve (deUintptr capacity)
293 {
294 if (capacity >= m_capacity)
295 {
296 void* oldPageTable = DE_NULL;
297 deUintptr oldPageTableSize = 0;
298
299 deUintptr newCapacity = (deUintptr)deAlignPtr((void*)capacity, 1 << ELEMENTS_PER_PAGE_LOG2);
300 deUintptr reqPageTableCapacity = newCapacity >> ELEMENTS_PER_PAGE_LOG2;
301
302 if (m_pageTableCapacity < reqPageTableCapacity)
303 {
304 deUintptr newPageTableCapacity = max(2*m_pageTableCapacity, reqPageTableCapacity);
305 void** newPageTable = (void**)m_pool->alloc(newPageTableCapacity * sizeof(void*));
306 deUintptr i;
307
308 for (i = 0; i < m_pageTableCapacity; i++)
309 newPageTable[i] = m_pageTable[i];
310
311 for (; i < newPageTableCapacity; i++)
312 newPageTable[i] = DE_NULL;
313
314 // Grab information about old page table for recycling purposes.
315 oldPageTable = m_pageTable;
316 oldPageTableSize = m_pageTableCapacity * sizeof(T*);
317
318 m_pageTable = newPageTable;
319 m_pageTableCapacity = newPageTableCapacity;
320 }
321
322 // Allocate new pages.
323 {
324 deUintptr elementSize = (deUintptr)deAlignPtr((void*)(deUintptr)sizeof(T), Alignment);
325 deUintptr pageAllocSize = elementSize << ELEMENTS_PER_PAGE_LOG2;
326 deUintptr pageTableNdx = m_capacity >> ELEMENTS_PER_PAGE_LOG2;
327
328 // Allocate new pages from recycled old page table.
329 for (;;)
330 {
331 void* newPage = deAlignPtr(oldPageTable, Alignment);
332 deUintptr alignPadding = (deUintptr)newPage - (deUintptr)oldPageTable;
333
334 if (oldPageTableSize < pageAllocSize+alignPadding)
335 break; // No free space for alloc + alignment.
336
337 DE_ASSERT(m_pageTableCapacity > pageTableNdx);
338 DE_ASSERT(!m_pageTable[pageTableNdx]);
339 m_pageTable[pageTableNdx++] = newPage;
340
341 oldPageTable = (void*)((deUint8*)newPage + pageAllocSize);
342 oldPageTableSize -= pageAllocSize+alignPadding;
343 }
344
345 // Allocate the rest of the needed pages from the pool.
346 for (; pageTableNdx < reqPageTableCapacity; pageTableNdx++)
347 {
348 DE_ASSERT(!m_pageTable[pageTableNdx]);
349 m_pageTable[pageTableNdx] = m_pool->alignedAlloc(pageAllocSize, Alignment);
350 }
351
352 m_capacity = pageTableNdx << ELEMENTS_PER_PAGE_LOG2;
353 DE_ASSERT(m_capacity >= newCapacity);
354 }
355 }
356 }
357
358 template<typename T, deUint32 Alignment>
pushBack(const T & value)359 inline void PoolArray<T, Alignment>::pushBack (const T& value)
360 {
361 resize(size()+1);
362 at(size()-1) = value;
363 }
364
365 template<typename T, deUint32 Alignment>
popBack(void)366 inline T PoolArray<T, Alignment>::popBack (void)
367 {
368 T val = at(size()-1);
369 resize(size()-1);
370 return val;
371 }
372
373 template<typename T, deUint32 Alignment>
getPtr(deIntptr ndx) const374 inline T* PoolArray<T, Alignment>::getPtr (deIntptr ndx) const
375 {
376 DE_ASSERT(inBounds<deIntptr>(ndx, 0, (deIntptr)m_numElements));
377 deUintptr pageNdx = ((deUintptr)ndx >> ELEMENTS_PER_PAGE_LOG2);
378 deUintptr subNdx = (deUintptr)ndx & ((1 << ELEMENTS_PER_PAGE_LOG2) - 1);
379 deUintptr elemSize = (deUintptr)deAlignPtr((void*)(deUintptr)sizeof(T), Alignment);
380 T* ptr = (T*)((deUint8*)m_pageTable[pageNdx] + (subNdx*elemSize));
381 DE_ASSERT(deIsAlignedPtr(ptr, Alignment));
382 return ptr;
383 }
384
385 // PoolArrayIteratorBase implementation
386
387 template<typename T, deUint32 Alignment>
operator ==(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)388 inline bool operator== (const PoolArrayIteratorBase<T, Alignment>& a, const PoolArrayIteratorBase<T, Alignment>& b)
389 {
390 // \todo [2013-02-08 pyry] Compare array ptr.
391 return a.getNdx() == b.getNdx();
392 }
393
394 template<typename T, deUint32 Alignment>
operator !=(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)395 inline bool operator!= (const PoolArrayIteratorBase<T, Alignment>& a, const PoolArrayIteratorBase<T, Alignment>& b)
396 {
397 // \todo [2013-02-08 pyry] Compare array ptr.
398 return a.getNdx() != b.getNdx();
399 }
400
401 template<typename T, deUint32 Alignment>
operator <(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)402 inline bool operator< (const PoolArrayIteratorBase<T, Alignment>& a, const PoolArrayIteratorBase<T, Alignment>& b)
403 {
404 return a.getNdx() < b.getNdx();
405 }
406
407 template<typename T, deUint32 Alignment>
operator >(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)408 inline bool operator> (const PoolArrayIteratorBase<T, Alignment>& a, const PoolArrayIteratorBase<T, Alignment>& b)
409 {
410 return a.getNdx() > b.getNdx();
411 }
412
413 template<typename T, deUint32 Alignment>
operator <=(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)414 inline bool operator<= (const PoolArrayIteratorBase<T, Alignment>& a, const PoolArrayIteratorBase<T, Alignment>& b)
415 {
416 return a.getNdx() <= b.getNdx();
417 }
418
419 template<typename T, deUint32 Alignment>
operator >=(const PoolArrayIteratorBase<T,Alignment> & a,const PoolArrayIteratorBase<T,Alignment> & b)420 inline bool operator>= (const PoolArrayIteratorBase<T, Alignment>& a, const PoolArrayIteratorBase<T, Alignment>& b)
421 {
422 return a.getNdx() >= b.getNdx();
423 }
424
425 // PoolArrayConstIterator<T> implementation
426
427 template<typename T, deUint32 Alignment>
PoolArrayConstIterator(void)428 inline PoolArrayConstIterator<T, Alignment>::PoolArrayConstIterator (void)
429 : PoolArrayIteratorBase<T, Alignment> (0)
430 , m_array (DE_NULL)
431 {
432 }
433
434 template<typename T, deUint32 Alignment>
PoolArrayConstIterator(const PoolArray<T,Alignment> * array,deIntptr ndx)435 inline PoolArrayConstIterator<T, Alignment>::PoolArrayConstIterator (const PoolArray<T, Alignment>* array, deIntptr ndx)
436 : PoolArrayIteratorBase<T, Alignment> (ndx)
437 , m_array (array)
438 {
439 }
440
441 template<typename T, deUint32 Alignment>
PoolArrayConstIterator(const PoolArrayIterator<T,Alignment> & iter)442 inline PoolArrayConstIterator<T, Alignment>::PoolArrayConstIterator (const PoolArrayIterator<T, Alignment>& iter)
443 : PoolArrayIteratorBase<T, Alignment> (iter)
444 , m_array (iter.getArray())
445 {
446 }
447
448 template<typename T, deUint32 Alignment>
~PoolArrayConstIterator(void)449 inline PoolArrayConstIterator<T, Alignment>::~PoolArrayConstIterator (void)
450 {
451 }
452
453 // Arithmetic operators.
454
455 template<typename T, deUint32 Alignment>
operator +(const PoolArrayConstIterator<T,Alignment> & iter,deIntptr offs)456 inline PoolArrayConstIterator<T, Alignment> operator+ (const PoolArrayConstIterator<T, Alignment>& iter, deIntptr offs)
457 {
458 return PoolArrayConstIterator<T, Alignment>(iter->getArray(), iter->getNdx()+offs);
459 }
460
461 template<typename T, deUint32 Alignment>
operator +(deUintptr offs,const PoolArrayConstIterator<T,Alignment> & iter)462 inline PoolArrayConstIterator<T, Alignment> operator+ (deUintptr offs, const PoolArrayConstIterator<T, Alignment>& iter)
463 {
464 return PoolArrayConstIterator<T, Alignment>(iter->getArray(), iter->getNdx()+offs);
465 }
466
467 template<typename T, deUint32 Alignment>
operator -(const PoolArrayConstIterator<T,Alignment> & iter,deIntptr offs)468 PoolArrayConstIterator<T, Alignment> operator- (const PoolArrayConstIterator<T, Alignment>& iter, deIntptr offs)
469 {
470 return PoolArrayConstIterator<T, Alignment>(iter.getArray(), iter.getNdx()-offs);
471 }
472
473 template<typename T, deUint32 Alignment>
operator -(const PoolArrayConstIterator<T,Alignment> & iter,const PoolArrayConstIterator<T,Alignment> & other)474 deIntptr operator- (const PoolArrayConstIterator<T, Alignment>& iter, const PoolArrayConstIterator<T, Alignment>& other)
475 {
476 return iter.getNdx()-other.getNdx();
477 }
478
479 // PoolArrayIterator<T> implementation.
480
481 template<typename T, deUint32 Alignment>
PoolArrayIterator(void)482 inline PoolArrayIterator<T, Alignment>::PoolArrayIterator (void)
483 : PoolArrayIteratorBase<T, Alignment> (0)
484 , m_array (DE_NULL)
485 {
486 }
487
488 template<typename T, deUint32 Alignment>
PoolArrayIterator(PoolArray<T,Alignment> * array,deIntptr ndx)489 inline PoolArrayIterator<T, Alignment>::PoolArrayIterator (PoolArray<T, Alignment>* array, deIntptr ndx)
490 : PoolArrayIteratorBase<T, Alignment> (ndx)
491 , m_array (array)
492 {
493 }
494
495 template<typename T, deUint32 Alignment>
~PoolArrayIterator(void)496 inline PoolArrayIterator<T, Alignment>::~PoolArrayIterator (void)
497 {
498 }
499
500 // Arithmetic operators.
501
502 template<typename T, deUint32 Alignment>
operator +(const PoolArrayIterator<T,Alignment> & iter,deIntptr offs)503 inline PoolArrayIterator<T, Alignment> operator+ (const PoolArrayIterator<T, Alignment>& iter, deIntptr offs)
504 {
505 return PoolArrayIterator<T, Alignment>(iter.getArray(), iter.getNdx()+offs);
506 }
507
508 template<typename T, deUint32 Alignment>
operator +(deUintptr offs,const PoolArrayIterator<T,Alignment> & iter)509 inline PoolArrayIterator<T, Alignment> operator+ (deUintptr offs, const PoolArrayIterator<T, Alignment>& iter)
510 {
511 return PoolArrayIterator<T, Alignment>(iter.getArray(), iter.getNdx()+offs);
512 }
513
514 template<typename T, deUint32 Alignment>
operator -(const PoolArrayIterator<T,Alignment> & iter,deIntptr offs)515 PoolArrayIterator<T, Alignment> operator- (const PoolArrayIterator<T, Alignment>& iter, deIntptr offs)
516 {
517 return PoolArrayIterator<T, Alignment>(iter.getArray(), iter.getNdx()-offs);
518 }
519
520 template<typename T, deUint32 Alignment>
operator -(const PoolArrayIterator<T,Alignment> & iter,const PoolArrayIterator<T,Alignment> & other)521 deIntptr operator- (const PoolArrayIterator<T, Alignment>& iter, const PoolArrayIterator<T, Alignment>& other)
522 {
523 return iter.getNdx()-other.getNdx();
524 }
525
526 } // de
527
528 // std::iterator_traits specializations
529 namespace std
530 {
531
532 template<typename T, deUint32 Alignment>
533 struct iterator_traits<de::PoolArrayConstIterator<T, Alignment> >
534 {
535 typedef deIntptr difference_type;
536 typedef T value_type;
537 typedef const T* pointer;
538 typedef const T& reference;
539 typedef random_access_iterator_tag iterator_category;
540 };
541
542 template<typename T, deUint32 Alignment>
543 struct iterator_traits<de::PoolArrayIterator<T, Alignment> >
544 {
545 typedef deIntptr difference_type;
546 typedef T value_type;
547 typedef T* pointer;
548 typedef T& reference;
549 typedef random_access_iterator_tag iterator_category;
550 };
551
552 } // std
553
554 #endif // _DEPOOLARRAY_HPP
555