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