vrshoot

diff libs/assimp/irrXML/irrArray.h @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/assimp/irrXML/irrArray.h	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,444 @@
     1.4 +// Copyright (C) 2002-2005 Nikolaus Gebhardt
     1.5 +// This file is part of the "Irrlicht Engine" and the "irrXML" project.
     1.6 +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
     1.7 +
     1.8 +#ifndef __IRR_ARRAY_H_INCLUDED__
     1.9 +#define __IRR_ARRAY_H_INCLUDED__
    1.10 +
    1.11 +#include "irrTypes.h"
    1.12 +#include "heapsort.h"
    1.13 +
    1.14 +namespace irr
    1.15 +{
    1.16 +namespace core
    1.17 +{
    1.18 +
    1.19 +//!	Self reallocating template array (like stl vector) with additional features.
    1.20 +/** Some features are: Heap sorting, binary search methods, easier debugging.
    1.21 +*/
    1.22 +template <class T>
    1.23 +class array
    1.24 +{
    1.25 +
    1.26 +public:
    1.27 +
    1.28 +	array()
    1.29 +		: data(0), allocated(0), used(0),
    1.30 +			free_when_destroyed(true), is_sorted(true)
    1.31 +	{
    1.32 +	}
    1.33 +
    1.34 +	//! Constructs a array and allocates an initial chunk of memory.
    1.35 +	//! \param start_count: Amount of elements to allocate.
    1.36 +	array(u32 start_count)
    1.37 +		: data(0), allocated(0), used(0),
    1.38 +			free_when_destroyed(true),	is_sorted(true)
    1.39 +	{
    1.40 +		reallocate(start_count);
    1.41 +	}
    1.42 +
    1.43 +
    1.44 +	//! Copy constructor
    1.45 +	array(const array<T>& other)
    1.46 +		: data(0)
    1.47 +	{
    1.48 +		*this = other;
    1.49 +	}
    1.50 +
    1.51 +
    1.52 +
    1.53 +	//! Destructor. Frees allocated memory, if set_free_when_destroyed
    1.54 +	//! was not set to false by the user before.
    1.55 +	~array()
    1.56 +	{
    1.57 +		if (free_when_destroyed)
    1.58 +			delete [] data;
    1.59 +	}
    1.60 +
    1.61 +
    1.62 +
    1.63 +	//! Reallocates the array, make it bigger or smaller.
    1.64 +	//! \param new_size: New size of array.
    1.65 +	void reallocate(u32 new_size)
    1.66 +	{
    1.67 +		T* old_data = data;
    1.68 +
    1.69 +		data = new T[new_size];
    1.70 +		allocated = new_size;
    1.71 +		
    1.72 +		s32 end = used < new_size ? used : new_size;
    1.73 +		for (s32 i=0; i<end; ++i)
    1.74 +			data[i] = old_data[i];
    1.75 +
    1.76 +		if (allocated < used)
    1.77 +			used = allocated;
    1.78 +		
    1.79 +		delete [] old_data;
    1.80 +	}
    1.81 +
    1.82 +	//! Adds an element at back of array. If the array is to small to 
    1.83 +	//! add this new element, the array is made bigger.
    1.84 +	//! \param element: Element to add at the back of the array.
    1.85 +	void push_back(const T& element)
    1.86 +	{
    1.87 +		if (used + 1 > allocated)
    1.88 +		{
    1.89 +			// reallocate(used * 2 +1);
    1.90 +			// this doesn't work if the element is in the same array. So
    1.91 +			// we'll copy the element first to be sure we'll get no data
    1.92 +			// corruption
    1.93 +
    1.94 +			T e;
    1.95 +			e = element;           // copy element
    1.96 +			reallocate(used * 2 +1); // increase data block
    1.97 +			data[used++] = e;        // push_back
    1.98 +			is_sorted = false; 
    1.99 +			return;
   1.100 +		}
   1.101 +
   1.102 +		data[used++] = element;
   1.103 +		is_sorted = false;
   1.104 +	}
   1.105 +
   1.106 +
   1.107 +	//! Adds an element at the front of the array. If the array is to small to 
   1.108 +	//! add this new element, the array is made bigger. Please note that this
   1.109 +	//! is slow, because the whole array needs to be copied for this.
   1.110 +	//! \param element: Element to add at the back of the array.
   1.111 +	void push_front(const T& element)
   1.112 +	{
   1.113 +		if (used + 1 > allocated)
   1.114 +			reallocate(used * 2 +1);
   1.115 +
   1.116 +		for (int i=(int)used; i>0; --i)
   1.117 +			data[i] = data[i-1];
   1.118 +
   1.119 +		data[0] = element;
   1.120 +		is_sorted = false;
   1.121 +		++used;
   1.122 +	}
   1.123 +
   1.124 +	
   1.125 +	//! Insert item into array at specified position. Please use this
   1.126 +	//! only if you know what you are doing (possible performance loss). 
   1.127 +	//! The preferred method of adding elements should be push_back().
   1.128 +	//! \param element: Element to be inserted
   1.129 +	//! \param index: Where position to insert the new element.
   1.130 +	void insert(const T& element, u32 index=0) 
   1.131 +	{
   1.132 +		_IRR_DEBUG_BREAK_IF(index>used) // access violation
   1.133 +
   1.134 +		if (used + 1 > allocated)
   1.135 +			reallocate(used * 2 +1);
   1.136 +
   1.137 +		for (u32 i=used++; i>index; i--) 
   1.138 +			data[i] = data[i-1];
   1.139 +
   1.140 +		data[index] = element;
   1.141 +		is_sorted = false;
   1.142 +	}
   1.143 +
   1.144 +
   1.145 +
   1.146 +
   1.147 +	//! Clears the array and deletes all allocated memory.
   1.148 +	void clear()
   1.149 +	{
   1.150 +		delete [] data;
   1.151 +		data = 0;
   1.152 +		used = 0;
   1.153 +		allocated = 0;
   1.154 +		is_sorted = true;
   1.155 +	}
   1.156 +
   1.157 +
   1.158 +
   1.159 +	//! Sets pointer to new array, using this as new workspace.
   1.160 +	//! \param newPointer: Pointer to new array of elements.
   1.161 +	//! \param size: Size of the new array.
   1.162 +	void set_pointer(T* newPointer, u32 size)
   1.163 +	{
   1.164 +		delete [] data;
   1.165 +		data = newPointer;
   1.166 +		allocated = size;
   1.167 +		used = size;
   1.168 +		is_sorted = false;
   1.169 +	}
   1.170 +
   1.171 +
   1.172 +
   1.173 +	//! Sets if the array should delete the memory it used.
   1.174 +	//! \param f: If true, the array frees the allocated memory in its
   1.175 +	//! destructor, otherwise not. The default is true.
   1.176 +	void set_free_when_destroyed(bool f)
   1.177 +	{
   1.178 +		free_when_destroyed = f;
   1.179 +	}
   1.180 +
   1.181 +
   1.182 +
   1.183 +	//! Sets the size of the array.
   1.184 +	//! \param usedNow: Amount of elements now used.
   1.185 +	void set_used(u32 usedNow)
   1.186 +	{
   1.187 +		if (allocated < usedNow)
   1.188 +			reallocate(usedNow);
   1.189 +
   1.190 +		used = usedNow;
   1.191 +	}
   1.192 +
   1.193 +
   1.194 +
   1.195 +	//! Assignement operator
   1.196 +	void operator=(const array<T>& other)
   1.197 +	{
   1.198 +		if (data)
   1.199 +			delete [] data;
   1.200 +
   1.201 +		//if (allocated < other.allocated)
   1.202 +		if (other.allocated == 0)
   1.203 +			data = 0;
   1.204 +		else
   1.205 +			data = new T[other.allocated];
   1.206 +
   1.207 +		used = other.used;
   1.208 +		free_when_destroyed = other.free_when_destroyed;
   1.209 +		is_sorted = other.is_sorted;
   1.210 +		allocated = other.allocated;
   1.211 +
   1.212 +		for (u32 i=0; i<other.used; ++i)
   1.213 +			data[i] = other.data[i];
   1.214 +	}
   1.215 +
   1.216 +
   1.217 +	//! Direct access operator
   1.218 +	T& operator [](u32 index)
   1.219 +	{
   1.220 +		_IRR_DEBUG_BREAK_IF(index>=used) // access violation
   1.221 +
   1.222 +		return data[index];
   1.223 +	}
   1.224 +
   1.225 +
   1.226 +
   1.227 +	//! Direct access operator
   1.228 +	const T& operator [](u32 index) const
   1.229 +	{
   1.230 +		_IRR_DEBUG_BREAK_IF(index>=used) // access violation
   1.231 +
   1.232 +		return data[index];
   1.233 +	}
   1.234 +
   1.235 +    //! Gets last frame
   1.236 +	const T& getLast() const
   1.237 +	{
   1.238 +		_IRR_DEBUG_BREAK_IF(!used) // access violation
   1.239 +
   1.240 +		return data[used-1];
   1.241 +	}
   1.242 +
   1.243 +    //! Gets last frame
   1.244 +	T& getLast()
   1.245 +	{
   1.246 +		_IRR_DEBUG_BREAK_IF(!used) // access violation
   1.247 +
   1.248 +		return data[used-1];
   1.249 +	}
   1.250 +    
   1.251 +
   1.252 +	//! Returns a pointer to the array.
   1.253 +	//! \return Pointer to the array.
   1.254 +	T* pointer()
   1.255 +	{
   1.256 +		return data;
   1.257 +	}
   1.258 +
   1.259 +
   1.260 +
   1.261 +	//! Returns a const pointer to the array.
   1.262 +	//! \return Pointer to the array.
   1.263 +	const T* const_pointer() const
   1.264 +	{
   1.265 +		return data;
   1.266 +	}
   1.267 +
   1.268 +
   1.269 +
   1.270 +	//! Returns size of used array.
   1.271 +	//! \return Size of elements in the array.
   1.272 +	u32 size() const
   1.273 +	{
   1.274 +		return used;
   1.275 +	}
   1.276 +
   1.277 +
   1.278 +
   1.279 +	//! Returns amount memory allocated.
   1.280 +	//! \return Returns amount of memory allocated. The amount of bytes
   1.281 +	//! allocated would  be allocated_size() * sizeof(ElementsUsed);
   1.282 +	u32 allocated_size() const
   1.283 +	{
   1.284 +		return allocated;
   1.285 +	}
   1.286 +
   1.287 +
   1.288 +
   1.289 +	//! Returns true if array is empty
   1.290 +	//! \return True if the array is empty, false if not.
   1.291 +	bool empty() const
   1.292 +	{
   1.293 +		return used == 0;
   1.294 +	}
   1.295 +
   1.296 +
   1.297 +
   1.298 +	//! Sorts the array using heapsort. There is no additional memory waste and
   1.299 +	//! the algorithm performs (O) n log n in worst case.
   1.300 +	void sort()
   1.301 +	{
   1.302 +		if (is_sorted || used<2)
   1.303 +			return;
   1.304 +
   1.305 +		heapsort(data, used);
   1.306 +		is_sorted = true;
   1.307 +	}
   1.308 +
   1.309 +
   1.310 +
   1.311 +	//! Performs a binary search for an element, returns -1 if not found.
   1.312 +	//! The array will be sorted before the binary search if it is not
   1.313 +	//! already sorted.
   1.314 +	//! \param element: Element to search for.
   1.315 +	//! \return Returns position of the searched element if it was found,
   1.316 +	//! otherwise -1 is returned.
   1.317 +	s32 binary_search(const T& element)
   1.318 +	{
   1.319 +		return binary_search(element, 0, used-1);
   1.320 +	}
   1.321 +
   1.322 +
   1.323 +
   1.324 +	//! Performs a binary search for an element, returns -1 if not found.
   1.325 +	//! The array will be sorted before the binary search if it is not
   1.326 +	//! already sorted.
   1.327 +	//! \param element: Element to search for.
   1.328 +	//! \param left: First left index
   1.329 +	//! \param right: Last right index.
   1.330 +	//! \return Returns position of the searched element if it was found,
   1.331 +	//! otherwise -1 is returned.
   1.332 +	s32 binary_search(const T& element, s32 left, s32 right)
   1.333 +	{
   1.334 +		if (!used)
   1.335 +			return -1;
   1.336 +
   1.337 +		sort();
   1.338 +
   1.339 +		s32 m;
   1.340 +
   1.341 +		do
   1.342 +		{
   1.343 +			m = (left+right)>>1;
   1.344 +
   1.345 +			if (element < data[m])
   1.346 +				right = m - 1;
   1.347 +			else
   1.348 +				left = m + 1;
   1.349 +
   1.350 +		} while((element < data[m] || data[m] < element) && left<=right);
   1.351 +
   1.352 +		// this last line equals to:
   1.353 +		// " while((element != array[m]) && left<=right);"
   1.354 +		// but we only want to use the '<' operator.
   1.355 +		// the same in next line, it is "(element == array[m])"
   1.356 +
   1.357 +		if (!(element < data[m]) && !(data[m] < element))
   1.358 +			return m;
   1.359 +
   1.360 +		return -1;
   1.361 +	}
   1.362 +
   1.363 +
   1.364 +	//! Finds an element in linear time, which is very slow. Use
   1.365 +	//! binary_search for faster finding. Only works if =operator is implemented.
   1.366 +	//! \param element: Element to search for.
   1.367 +	//! \return Returns position of the searched element if it was found,
   1.368 +	//! otherwise -1 is returned.
   1.369 +	s32 linear_search(T& element)
   1.370 +	{
   1.371 +		for (u32 i=0; i<used; ++i)
   1.372 +			if (!(element < data[i]) && !(data[i] < element))
   1.373 +				return (s32)i;
   1.374 +
   1.375 +		return -1;
   1.376 +	}
   1.377 +
   1.378 +
   1.379 +	//! Finds an element in linear time, which is very slow. Use
   1.380 +	//! binary_search for faster finding. Only works if =operator is implemented.
   1.381 +	//! \param element: Element to search for.
   1.382 +	//! \return Returns position of the searched element if it was found,
   1.383 +	//! otherwise -1 is returned.
   1.384 +	s32 linear_reverse_search(T& element)
   1.385 +	{
   1.386 +		for (s32 i=used-1; i>=0; --i)
   1.387 +			if (data[i] == element)
   1.388 +				return (s32)i;
   1.389 +
   1.390 +		return -1;
   1.391 +	}
   1.392 +
   1.393 +
   1.394 +
   1.395 +	//! Erases an element from the array. May be slow, because all elements 
   1.396 +	//! following after the erased element have to be copied.
   1.397 +	//! \param index: Index of element to be erased.
   1.398 +	void erase(u32 index)
   1.399 +	{
   1.400 +		_IRR_DEBUG_BREAK_IF(index>=used || index<0) // access violation
   1.401 +
   1.402 +		for (u32 i=index+1; i<used; ++i)
   1.403 +			data[i-1] = data[i];
   1.404 +
   1.405 +		--used;
   1.406 +	}
   1.407 +
   1.408 +
   1.409 +	//! Erases some elements from the array. may be slow, because all elements 
   1.410 +	//! following after the erased element have to be copied.
   1.411 +	//! \param index: Index of the first element to be erased.
   1.412 +	//! \param count: Amount of elements to be erased.
   1.413 +	void erase(u32 index, s32 count)
   1.414 +	{
   1.415 +		_IRR_DEBUG_BREAK_IF(index>=used || index<0 || count<1 || index+count>used) // access violation
   1.416 +
   1.417 +		for (u32 i=index+count; i<used; ++i)
   1.418 +			data[i-count] = data[i];
   1.419 +
   1.420 +		used-= count;
   1.421 +	}
   1.422 +
   1.423 +
   1.424 +	//! Sets if the array is sorted
   1.425 +	void set_sorted(bool _is_sorted)
   1.426 +	{
   1.427 +		is_sorted = _is_sorted;
   1.428 +	}
   1.429 +
   1.430 +			
   1.431 +	private:
   1.432 +
   1.433 +		T* data;
   1.434 +		u32 allocated;
   1.435 +		u32 used;
   1.436 +		bool free_when_destroyed;
   1.437 +		bool is_sorted;
   1.438 +};
   1.439 +
   1.440 +
   1.441 +} // end namespace core
   1.442 +} // end namespace irr
   1.443 +
   1.444 +
   1.445 +
   1.446 +#endif
   1.447 +