tc3d_array.h

来自「自己写的一些基本的3d引擎的基础的代码」· C头文件 代码 · 共 654 行 · 第 1/2 页

H
654
字号
				 * @return	none
				 */
				virtual TC3D_Void Adjust(TC3D_U32 size)
				{
					T *pOld = pData;
					TC3D_U32 cpyCount;

					// Do not adjust if same size
					if(size == tAlloc)
						return;

					// Allocate an array of the new size
					pData = tAllocator.Allocate(size);

					// Only copy what fits the array
					cpyCount = size < tSize ? size : tSize;

					// Copy all elements
					for(TC3D_U32 i = 0; i < cpyCount; i++)
						tAllocator.Construct(pData + i, pOld[i]);
		
					// Destruct old elements
					for(TC3D_U32 i = 0; i < tSize; i++)
						tAllocator.Destruct(pOld + i);

					// Free the old components
					if(pOld)
						tAllocator.Deallocate(pOld);
					tAlloc = size;

					if(size < tSize)
						tSize = size;
				}

				/**
				 * Push an element to the back of the array, this is
				 * very efficient because adding an additional element
				 * to the end introduces no overhead besides allocating
				 * additional memory if the current size of the array
				 * is not enough. If the array is empty, initial size
				 * is allocated and can be changed either by modifying
				 * THMUD_ARRAY_INITIAL_SIZE definition or creating an
				 * array with an initial size.
				 *
				 * @param	item	item to push
				 * @return	none
				 */
				virtual TC3D_Void Push_Back(const T &item)
				{
					// Allocate additional memory if needed
					if(!tAlloc)
						Adjust(CC3D_ARRAY_INIT_SIZE);

					if(tSize >= tAlloc)
						Adjust(tAlloc * 2);

                    tAllocator.Construct(pData + (tSize++), item);
					tSorted = DC3D_FALSE;
				}

				/**
				 * Push an element to the front of the array, this
				 * function is in general slower than Push_Back and
				 * should be avoided if possible. It is here merely
				 * for completeness and may be used in some conditions.
				 * Besides being slower, the allocation properties
				 * are identical to Push_Back.
				 * 
				 * @param	item	item to push
				 * @return	none
				 */
				virtual TC3D_Void Push_Front(const T &item)
				{
					// Allocate additional memory if needed
					if(!tAlloc)
						Adjust(CC3D_ARRAY_INIT_SIZE);

					if(tSize >= tAlloc)
						Adjust(tAlloc * 2);

					for(TC3D_U32 i = tSize; i > 0; i--)
						tAllocator.Construct(pData + i, pData[i - 1]);

					tAllocator.Construct(pData, item);
					tSize++;
					tSorted = DC3D_FALSE;
				}
				
				/**
				 * Pops an item from the back of the array
				 *
				 * @param	none
				 * @return	none
				 */
				virtual T Pop_Back()
				{
					T item = *(End() - 1);
					Erase(End() - 1, End());
					return item;
				}

				/**
				 * Pops an item from the front of the array
				 *
				 * @param	none
				 * @return	none
				 */
				virtual TC3D_Void Pop_Front()
				{
					T item = *Begin();
					Erase(Begin(), Begin() + 1);
					return item;
				}

				/**
				 * Insert an element to a specific place specified by
				 * an array iterator. This function is also slow because
				 * it will shift the array to make room for the newly added
				 * element. It also allocates memory if the array is not
				 * big enough
				 * 
				 * @param	it		iterator specifying the position to add
				 * @param	item	item to insert
				 * @return	none
				 */
				virtual TC3D_Void Insert(const CC3D_Iterator &it, const T &item)
				{
					if(!tSize)
					{
						Push_Back(item);
						return;
					}

					MC3D_DEBUG_ASSERT(it.pData <= (pData + tSize));

					if(tSize >= tAlloc)
						Adjust(tAlloc * 2);

					for(T *i = pData + tSize; i > it.pData; i--)
						tAllocator.Construct(i, *(i - 1));

					tAllocator.Construct(it.pData, item);
					tSize++;
					tSorted = DC3D_TRUE;
				}

				/** 
				 * Erase a range of elements pointed by the begin
				 * and end iterators. Once the elements have been
				 * erased and shifted, the array is adjusted to the
				 * proper size according to the allocation standards.
				 *
				 * @param	begin	begin point of deletion
				 * @param	end		end point of deletion
				 * @return	none
				 */
				virtual TC3D_Void Erase(const CC3D_Iterator &begin, const CC3D_Iterator &end)
				{
					if(begin.pData == end.pData)
						return;

					MC3D_DEBUG_ASSERT((end.pData - begin.pData) >= 0);
					MC3D_DEBUG_ASSERT((end.pData - begin.pData) <= (TC3D_S32)tSize);

					TC3D_U32 size = (TC3D_U32)(end.pData - begin.pData);
					T *pEnd = pData + tSize;
					
					// Shift in as many elements as possible
					TC3D_U32 shifted = 0;
					for(T *i = end.pData; i < pEnd; i++)
					{
						tAllocator.Destruct(i - size);
						tAllocator.Construct(i - size, *i);
						shifted++;
					}

					// Destroy the tailing elements after shifting
					for(T *i = pEnd - 1; i >= (pEnd - shifted); i--)
						tAllocator.Destruct(i);

					// Destroy elements if less shifting than deletion
					for(T *i = begin.pData + shifted; i < end.pData; i++)
						tAllocator.Destruct(i);

					tSize -= size;
					
					// Shrink the array accordingly
					TC3D_U32 shrinkSize = tAlloc;

					TC3D_U32 shrink = (TC3D_U32)(shrinkSize * 0.5f);
					while(tSize < shrink && shrinkSize > CC3D_ARRAY_INIT_SIZE)
					{
						shrinkSize = shrink;
						shrink = (TC3D_U32)(shrink * 0.5f);
					}
					if(shrinkSize < tAlloc)
						Adjust(shrinkSize > CC3D_ARRAY_INIT_SIZE ? shrinkSize : CC3D_ARRAY_INIT_SIZE);
				}

				/**
				 * Erases a single element with a given index
				 *
				 * @param	index	index value
				 * @return	none
				 */
				virtual TC3D_Void Erase(TC3D_U32 index) 
				{ 
					Erase(Begin() + index); 
				}

				/** 
				 * Erases a single element at the position pointed
				 * by the begin iterator. The elements after the
				 * point of deletion will be shifted properly.
				 *
				 * @param	begin	begin point of deletion
				 * @return	none
				 */
				virtual TC3D_Void Erase(const CC3D_Iterator &begin) 
				{ 
					Erase(begin, begin + 1); 
				}

				/** Get the size used of the array */
				inline virtual TC3D_U32 Size() const 
				{ 
					return tSize; 
				}

				/** Get the allocation size of the array */
				inline virtual TC3D_U32 Alloc() const 
				{ 
					return tAlloc; 
				}

				/** Get the constant pointer to the data elements */
				inline virtual const T *Pointer_Const() const 
				{ 
					return pData; 
				}

				/** Gets the pointer to the data elements */
				inline virtual T *Pointer() const
				{
					return pData;
				}

				/** Returns an iterator pointed at the beginning of the array */
				inline CC3D_Iterator Begin()
				{
					return CC3D_Iterator(pData, this);
				}
				
				/** Returns an iterator pointed at the end of the array */
				inline CC3D_Iterator End()
				{
					return CC3D_Iterator(pData + tSize, this);
				}

				/** Check if the array is empty */
				inline virtual TC3D_Bool Empty() const
				{
					return (tSize == 0);
				}

				/**
				 * Clear the array and deallocate all of its memory.
				 * This function can be used to clear out the entire
				 * array at once. Note that it does free all the memory
				 * so that adding components later will reallocate
				 * memory.
				 *
				 * @param	none
				 * @return	none
				 */
				virtual TC3D_Void Clear()
				{
					if(!tAlloc)
						return;

					// Destruct all contents
					for(TC3D_U32 i = 0; i < tSize; i++)
						tAllocator.Destruct(pData + i);

					// Deallocate array
					tAllocator.Deallocate(pData);

					// Reset size information
					pData = NULL;
					tSize = 0;
					tAlloc = 0;
					tSorted = DC3D_TRUE;
				}


				/** Array indexing */
				inline virtual T &operator [] (TC3D_U32 index) const
				{
					MC3D_DEBUG_ASSERT(index < tSize);

					return pData[index];
				}

				/** Array asignment */
				virtual TC3D_Array<T, TAlloc> &operator = (const TC3D_Array<T, TAlloc> &src)
				{
					if(this != &src)
					{
						// Clear, resize etc....
						Clear();
						Adjust(src.tAlloc);
						tSize = src.tSize;

						// Copyover all of the elements
						for(TC3D_U32 i = 0; i < src.tSize; i++)
                            tAllocator.Construct(pData + i, src.pData[i]);

						tSorted = src.tSorted;
					}
					return *this;
				}
		};
	};
};

#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?