• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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