A port of the irrlicht XML parser library.
irrArray.h@0:41a49a73580c, 2010-11-17 (annotated)
- Committer:
- hlipka
- Date:
- Wed Nov 17 20:19:41 2010 +0000
- Revision:
- 0:41a49a73580c
initial version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hlipka | 0:41a49a73580c | 1 | // Copyright (C) 2002-2005 Nikolaus Gebhardt |
hlipka | 0:41a49a73580c | 2 | // This file is part of the "Irrlicht Engine" and the "irrXML" project. |
hlipka | 0:41a49a73580c | 3 | // For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h |
hlipka | 0:41a49a73580c | 4 | |
hlipka | 0:41a49a73580c | 5 | #ifndef __IRR_ARRAY_H_INCLUDED__ |
hlipka | 0:41a49a73580c | 6 | #define __IRR_ARRAY_H_INCLUDED__ |
hlipka | 0:41a49a73580c | 7 | |
hlipka | 0:41a49a73580c | 8 | #include "irrTypes.h" |
hlipka | 0:41a49a73580c | 9 | #include "heapsort.h" |
hlipka | 0:41a49a73580c | 10 | |
hlipka | 0:41a49a73580c | 11 | namespace irr |
hlipka | 0:41a49a73580c | 12 | { |
hlipka | 0:41a49a73580c | 13 | namespace core |
hlipka | 0:41a49a73580c | 14 | { |
hlipka | 0:41a49a73580c | 15 | |
hlipka | 0:41a49a73580c | 16 | //! Self reallocating template array (like stl vector) with additional features. |
hlipka | 0:41a49a73580c | 17 | /** Some features are: Heap sorting, binary search methods, easier debugging. |
hlipka | 0:41a49a73580c | 18 | */ |
hlipka | 0:41a49a73580c | 19 | template <class T> |
hlipka | 0:41a49a73580c | 20 | class array |
hlipka | 0:41a49a73580c | 21 | { |
hlipka | 0:41a49a73580c | 22 | |
hlipka | 0:41a49a73580c | 23 | public: |
hlipka | 0:41a49a73580c | 24 | |
hlipka | 0:41a49a73580c | 25 | array() |
hlipka | 0:41a49a73580c | 26 | : data(0), used(0), allocated(0), |
hlipka | 0:41a49a73580c | 27 | free_when_destroyed(true), is_sorted(true) |
hlipka | 0:41a49a73580c | 28 | { |
hlipka | 0:41a49a73580c | 29 | } |
hlipka | 0:41a49a73580c | 30 | |
hlipka | 0:41a49a73580c | 31 | //! Constructs a array and allocates an initial chunk of memory. |
hlipka | 0:41a49a73580c | 32 | //! \param start_count: Amount of elements to allocate. |
hlipka | 0:41a49a73580c | 33 | array(u32 start_count) |
hlipka | 0:41a49a73580c | 34 | : data(0), used(0), allocated(0), |
hlipka | 0:41a49a73580c | 35 | free_when_destroyed(true), is_sorted(true) |
hlipka | 0:41a49a73580c | 36 | { |
hlipka | 0:41a49a73580c | 37 | reallocate(start_count); |
hlipka | 0:41a49a73580c | 38 | } |
hlipka | 0:41a49a73580c | 39 | |
hlipka | 0:41a49a73580c | 40 | |
hlipka | 0:41a49a73580c | 41 | //! Copy constructor |
hlipka | 0:41a49a73580c | 42 | array(const array<T>& other) |
hlipka | 0:41a49a73580c | 43 | : data(0) |
hlipka | 0:41a49a73580c | 44 | { |
hlipka | 0:41a49a73580c | 45 | *this = other; |
hlipka | 0:41a49a73580c | 46 | } |
hlipka | 0:41a49a73580c | 47 | |
hlipka | 0:41a49a73580c | 48 | |
hlipka | 0:41a49a73580c | 49 | |
hlipka | 0:41a49a73580c | 50 | //! Destructor. Frees allocated memory, if set_free_when_destroyed |
hlipka | 0:41a49a73580c | 51 | //! was not set to false by the user before. |
hlipka | 0:41a49a73580c | 52 | ~array() |
hlipka | 0:41a49a73580c | 53 | { |
hlipka | 0:41a49a73580c | 54 | if (free_when_destroyed) |
hlipka | 0:41a49a73580c | 55 | delete [] data; |
hlipka | 0:41a49a73580c | 56 | } |
hlipka | 0:41a49a73580c | 57 | |
hlipka | 0:41a49a73580c | 58 | |
hlipka | 0:41a49a73580c | 59 | |
hlipka | 0:41a49a73580c | 60 | //! Reallocates the array, make it bigger or smaller. |
hlipka | 0:41a49a73580c | 61 | //! \param new_size: New size of array. |
hlipka | 0:41a49a73580c | 62 | void reallocate(u32 new_size) |
hlipka | 0:41a49a73580c | 63 | { |
hlipka | 0:41a49a73580c | 64 | T* old_data = data; |
hlipka | 0:41a49a73580c | 65 | |
hlipka | 0:41a49a73580c | 66 | data = new T[new_size]; |
hlipka | 0:41a49a73580c | 67 | allocated = new_size; |
hlipka | 0:41a49a73580c | 68 | |
hlipka | 0:41a49a73580c | 69 | s32 end = used < new_size ? used : new_size; |
hlipka | 0:41a49a73580c | 70 | for (s32 i=0; i<end; ++i) |
hlipka | 0:41a49a73580c | 71 | data[i] = old_data[i]; |
hlipka | 0:41a49a73580c | 72 | |
hlipka | 0:41a49a73580c | 73 | if (allocated < used) |
hlipka | 0:41a49a73580c | 74 | used = allocated; |
hlipka | 0:41a49a73580c | 75 | |
hlipka | 0:41a49a73580c | 76 | delete [] old_data; |
hlipka | 0:41a49a73580c | 77 | } |
hlipka | 0:41a49a73580c | 78 | |
hlipka | 0:41a49a73580c | 79 | //! Adds an element at back of array. If the array is to small to |
hlipka | 0:41a49a73580c | 80 | //! add this new element, the array is made bigger. |
hlipka | 0:41a49a73580c | 81 | //! \param element: Element to add at the back of the array. |
hlipka | 0:41a49a73580c | 82 | void push_back(const T& element) |
hlipka | 0:41a49a73580c | 83 | { |
hlipka | 0:41a49a73580c | 84 | if (used + 1 > allocated) |
hlipka | 0:41a49a73580c | 85 | { |
hlipka | 0:41a49a73580c | 86 | // reallocate(used * 2 +1); |
hlipka | 0:41a49a73580c | 87 | // this doesn't work if the element is in the same array. So |
hlipka | 0:41a49a73580c | 88 | // we'll copy the element first to be sure we'll get no data |
hlipka | 0:41a49a73580c | 89 | // corruption |
hlipka | 0:41a49a73580c | 90 | |
hlipka | 0:41a49a73580c | 91 | T e; |
hlipka | 0:41a49a73580c | 92 | e = element; // copy element |
hlipka | 0:41a49a73580c | 93 | reallocate(used * 2 +1); // increase data block |
hlipka | 0:41a49a73580c | 94 | data[used++] = e; // push_back |
hlipka | 0:41a49a73580c | 95 | is_sorted = false; |
hlipka | 0:41a49a73580c | 96 | return; |
hlipka | 0:41a49a73580c | 97 | } |
hlipka | 0:41a49a73580c | 98 | |
hlipka | 0:41a49a73580c | 99 | data[used++] = element; |
hlipka | 0:41a49a73580c | 100 | is_sorted = false; |
hlipka | 0:41a49a73580c | 101 | } |
hlipka | 0:41a49a73580c | 102 | |
hlipka | 0:41a49a73580c | 103 | |
hlipka | 0:41a49a73580c | 104 | //! Adds an element at the front of the array. If the array is to small to |
hlipka | 0:41a49a73580c | 105 | //! add this new element, the array is made bigger. Please note that this |
hlipka | 0:41a49a73580c | 106 | //! is slow, because the whole array needs to be copied for this. |
hlipka | 0:41a49a73580c | 107 | //! \param element: Element to add at the back of the array. |
hlipka | 0:41a49a73580c | 108 | void push_front(const T& element) |
hlipka | 0:41a49a73580c | 109 | { |
hlipka | 0:41a49a73580c | 110 | if (used + 1 > allocated) |
hlipka | 0:41a49a73580c | 111 | reallocate(used * 2 +1); |
hlipka | 0:41a49a73580c | 112 | |
hlipka | 0:41a49a73580c | 113 | for (int i=(int)used; i>0; --i) |
hlipka | 0:41a49a73580c | 114 | data[i] = data[i-1]; |
hlipka | 0:41a49a73580c | 115 | |
hlipka | 0:41a49a73580c | 116 | data[0] = element; |
hlipka | 0:41a49a73580c | 117 | is_sorted = false; |
hlipka | 0:41a49a73580c | 118 | ++used; |
hlipka | 0:41a49a73580c | 119 | } |
hlipka | 0:41a49a73580c | 120 | |
hlipka | 0:41a49a73580c | 121 | |
hlipka | 0:41a49a73580c | 122 | //! Insert item into array at specified position. Please use this |
hlipka | 0:41a49a73580c | 123 | //! only if you know what you are doing (possible performance loss). |
hlipka | 0:41a49a73580c | 124 | //! The preferred method of adding elements should be push_back(). |
hlipka | 0:41a49a73580c | 125 | //! \param element: Element to be inserted |
hlipka | 0:41a49a73580c | 126 | //! \param index: Where position to insert the new element. |
hlipka | 0:41a49a73580c | 127 | void insert(const T& element, u32 index=0) |
hlipka | 0:41a49a73580c | 128 | { |
hlipka | 0:41a49a73580c | 129 | _IRR_DEBUG_BREAK_IF(index>used) // access violation |
hlipka | 0:41a49a73580c | 130 | |
hlipka | 0:41a49a73580c | 131 | if (used + 1 > allocated) |
hlipka | 0:41a49a73580c | 132 | reallocate(used * 2 +1); |
hlipka | 0:41a49a73580c | 133 | |
hlipka | 0:41a49a73580c | 134 | for (u32 i=used++; i>index; i--) |
hlipka | 0:41a49a73580c | 135 | data[i] = data[i-1]; |
hlipka | 0:41a49a73580c | 136 | |
hlipka | 0:41a49a73580c | 137 | data[index] = element; |
hlipka | 0:41a49a73580c | 138 | is_sorted = false; |
hlipka | 0:41a49a73580c | 139 | } |
hlipka | 0:41a49a73580c | 140 | |
hlipka | 0:41a49a73580c | 141 | |
hlipka | 0:41a49a73580c | 142 | |
hlipka | 0:41a49a73580c | 143 | |
hlipka | 0:41a49a73580c | 144 | //! Clears the array and deletes all allocated memory. |
hlipka | 0:41a49a73580c | 145 | void clear() |
hlipka | 0:41a49a73580c | 146 | { |
hlipka | 0:41a49a73580c | 147 | delete [] data; |
hlipka | 0:41a49a73580c | 148 | data = 0; |
hlipka | 0:41a49a73580c | 149 | used = 0; |
hlipka | 0:41a49a73580c | 150 | allocated = 0; |
hlipka | 0:41a49a73580c | 151 | is_sorted = true; |
hlipka | 0:41a49a73580c | 152 | } |
hlipka | 0:41a49a73580c | 153 | |
hlipka | 0:41a49a73580c | 154 | |
hlipka | 0:41a49a73580c | 155 | |
hlipka | 0:41a49a73580c | 156 | //! Sets pointer to new array, using this as new workspace. |
hlipka | 0:41a49a73580c | 157 | //! \param newPointer: Pointer to new array of elements. |
hlipka | 0:41a49a73580c | 158 | //! \param size: Size of the new array. |
hlipka | 0:41a49a73580c | 159 | void set_pointer(T* newPointer, u32 size) |
hlipka | 0:41a49a73580c | 160 | { |
hlipka | 0:41a49a73580c | 161 | delete [] data; |
hlipka | 0:41a49a73580c | 162 | data = newPointer; |
hlipka | 0:41a49a73580c | 163 | allocated = size; |
hlipka | 0:41a49a73580c | 164 | used = size; |
hlipka | 0:41a49a73580c | 165 | is_sorted = false; |
hlipka | 0:41a49a73580c | 166 | } |
hlipka | 0:41a49a73580c | 167 | |
hlipka | 0:41a49a73580c | 168 | |
hlipka | 0:41a49a73580c | 169 | |
hlipka | 0:41a49a73580c | 170 | //! Sets if the array should delete the memory it used. |
hlipka | 0:41a49a73580c | 171 | //! \param f: If true, the array frees the allocated memory in its |
hlipka | 0:41a49a73580c | 172 | //! destructor, otherwise not. The default is true. |
hlipka | 0:41a49a73580c | 173 | void set_free_when_destroyed(bool f) |
hlipka | 0:41a49a73580c | 174 | { |
hlipka | 0:41a49a73580c | 175 | free_when_destroyed = f; |
hlipka | 0:41a49a73580c | 176 | } |
hlipka | 0:41a49a73580c | 177 | |
hlipka | 0:41a49a73580c | 178 | |
hlipka | 0:41a49a73580c | 179 | |
hlipka | 0:41a49a73580c | 180 | //! Sets the size of the array. |
hlipka | 0:41a49a73580c | 181 | //! \param usedNow: Amount of elements now used. |
hlipka | 0:41a49a73580c | 182 | void set_used(u32 usedNow) |
hlipka | 0:41a49a73580c | 183 | { |
hlipka | 0:41a49a73580c | 184 | if (allocated < usedNow) |
hlipka | 0:41a49a73580c | 185 | reallocate(usedNow); |
hlipka | 0:41a49a73580c | 186 | |
hlipka | 0:41a49a73580c | 187 | used = usedNow; |
hlipka | 0:41a49a73580c | 188 | } |
hlipka | 0:41a49a73580c | 189 | |
hlipka | 0:41a49a73580c | 190 | |
hlipka | 0:41a49a73580c | 191 | |
hlipka | 0:41a49a73580c | 192 | //! Assignement operator |
hlipka | 0:41a49a73580c | 193 | void operator=(const array<T>& other) |
hlipka | 0:41a49a73580c | 194 | { |
hlipka | 0:41a49a73580c | 195 | if (data) |
hlipka | 0:41a49a73580c | 196 | delete [] data; |
hlipka | 0:41a49a73580c | 197 | |
hlipka | 0:41a49a73580c | 198 | //if (allocated < other.allocated) |
hlipka | 0:41a49a73580c | 199 | if (other.allocated == 0) |
hlipka | 0:41a49a73580c | 200 | data = 0; |
hlipka | 0:41a49a73580c | 201 | else |
hlipka | 0:41a49a73580c | 202 | data = new T[other.allocated]; |
hlipka | 0:41a49a73580c | 203 | |
hlipka | 0:41a49a73580c | 204 | used = other.used; |
hlipka | 0:41a49a73580c | 205 | free_when_destroyed = other.free_when_destroyed; |
hlipka | 0:41a49a73580c | 206 | is_sorted = other.is_sorted; |
hlipka | 0:41a49a73580c | 207 | allocated = other.allocated; |
hlipka | 0:41a49a73580c | 208 | |
hlipka | 0:41a49a73580c | 209 | for (u32 i=0; i<other.used; ++i) |
hlipka | 0:41a49a73580c | 210 | data[i] = other.data[i]; |
hlipka | 0:41a49a73580c | 211 | } |
hlipka | 0:41a49a73580c | 212 | |
hlipka | 0:41a49a73580c | 213 | |
hlipka | 0:41a49a73580c | 214 | //! Direct access operator |
hlipka | 0:41a49a73580c | 215 | T& operator [](u32 index) |
hlipka | 0:41a49a73580c | 216 | { |
hlipka | 0:41a49a73580c | 217 | _IRR_DEBUG_BREAK_IF(index>=used) // access violation |
hlipka | 0:41a49a73580c | 218 | |
hlipka | 0:41a49a73580c | 219 | return data[index]; |
hlipka | 0:41a49a73580c | 220 | } |
hlipka | 0:41a49a73580c | 221 | |
hlipka | 0:41a49a73580c | 222 | |
hlipka | 0:41a49a73580c | 223 | |
hlipka | 0:41a49a73580c | 224 | //! Direct access operator |
hlipka | 0:41a49a73580c | 225 | const T& operator [](u32 index) const |
hlipka | 0:41a49a73580c | 226 | { |
hlipka | 0:41a49a73580c | 227 | _IRR_DEBUG_BREAK_IF(index>=used) // access violation |
hlipka | 0:41a49a73580c | 228 | |
hlipka | 0:41a49a73580c | 229 | return data[index]; |
hlipka | 0:41a49a73580c | 230 | } |
hlipka | 0:41a49a73580c | 231 | |
hlipka | 0:41a49a73580c | 232 | //! Gets last frame |
hlipka | 0:41a49a73580c | 233 | const T& getLast() const |
hlipka | 0:41a49a73580c | 234 | { |
hlipka | 0:41a49a73580c | 235 | _IRR_DEBUG_BREAK_IF(!used) // access violation |
hlipka | 0:41a49a73580c | 236 | |
hlipka | 0:41a49a73580c | 237 | return data[used-1]; |
hlipka | 0:41a49a73580c | 238 | } |
hlipka | 0:41a49a73580c | 239 | |
hlipka | 0:41a49a73580c | 240 | //! Gets last frame |
hlipka | 0:41a49a73580c | 241 | T& getLast() |
hlipka | 0:41a49a73580c | 242 | { |
hlipka | 0:41a49a73580c | 243 | _IRR_DEBUG_BREAK_IF(!used) // access violation |
hlipka | 0:41a49a73580c | 244 | |
hlipka | 0:41a49a73580c | 245 | return data[used-1]; |
hlipka | 0:41a49a73580c | 246 | } |
hlipka | 0:41a49a73580c | 247 | |
hlipka | 0:41a49a73580c | 248 | |
hlipka | 0:41a49a73580c | 249 | //! Returns a pointer to the array. |
hlipka | 0:41a49a73580c | 250 | //! \return Pointer to the array. |
hlipka | 0:41a49a73580c | 251 | T* pointer() |
hlipka | 0:41a49a73580c | 252 | { |
hlipka | 0:41a49a73580c | 253 | return data; |
hlipka | 0:41a49a73580c | 254 | } |
hlipka | 0:41a49a73580c | 255 | |
hlipka | 0:41a49a73580c | 256 | |
hlipka | 0:41a49a73580c | 257 | |
hlipka | 0:41a49a73580c | 258 | //! Returns a const pointer to the array. |
hlipka | 0:41a49a73580c | 259 | //! \return Pointer to the array. |
hlipka | 0:41a49a73580c | 260 | const T* const_pointer() const |
hlipka | 0:41a49a73580c | 261 | { |
hlipka | 0:41a49a73580c | 262 | return data; |
hlipka | 0:41a49a73580c | 263 | } |
hlipka | 0:41a49a73580c | 264 | |
hlipka | 0:41a49a73580c | 265 | |
hlipka | 0:41a49a73580c | 266 | |
hlipka | 0:41a49a73580c | 267 | //! Returns size of used array. |
hlipka | 0:41a49a73580c | 268 | //! \return Size of elements in the array. |
hlipka | 0:41a49a73580c | 269 | u32 size() const |
hlipka | 0:41a49a73580c | 270 | { |
hlipka | 0:41a49a73580c | 271 | return used; |
hlipka | 0:41a49a73580c | 272 | } |
hlipka | 0:41a49a73580c | 273 | |
hlipka | 0:41a49a73580c | 274 | |
hlipka | 0:41a49a73580c | 275 | |
hlipka | 0:41a49a73580c | 276 | //! Returns amount memory allocated. |
hlipka | 0:41a49a73580c | 277 | //! \return Returns amount of memory allocated. The amount of bytes |
hlipka | 0:41a49a73580c | 278 | //! allocated would be allocated_size() * sizeof(ElementsUsed); |
hlipka | 0:41a49a73580c | 279 | u32 allocated_size() const |
hlipka | 0:41a49a73580c | 280 | { |
hlipka | 0:41a49a73580c | 281 | return allocated; |
hlipka | 0:41a49a73580c | 282 | } |
hlipka | 0:41a49a73580c | 283 | |
hlipka | 0:41a49a73580c | 284 | |
hlipka | 0:41a49a73580c | 285 | |
hlipka | 0:41a49a73580c | 286 | //! Returns true if array is empty |
hlipka | 0:41a49a73580c | 287 | //! \return True if the array is empty, false if not. |
hlipka | 0:41a49a73580c | 288 | bool empty() const |
hlipka | 0:41a49a73580c | 289 | { |
hlipka | 0:41a49a73580c | 290 | return used == 0; |
hlipka | 0:41a49a73580c | 291 | } |
hlipka | 0:41a49a73580c | 292 | |
hlipka | 0:41a49a73580c | 293 | |
hlipka | 0:41a49a73580c | 294 | |
hlipka | 0:41a49a73580c | 295 | //! Sorts the array using heapsort. There is no additional memory waste and |
hlipka | 0:41a49a73580c | 296 | //! the algorithm performs (O) n log n in worst case. |
hlipka | 0:41a49a73580c | 297 | void sort() |
hlipka | 0:41a49a73580c | 298 | { |
hlipka | 0:41a49a73580c | 299 | if (is_sorted || used<2) |
hlipka | 0:41a49a73580c | 300 | return; |
hlipka | 0:41a49a73580c | 301 | |
hlipka | 0:41a49a73580c | 302 | heapsort(data, used); |
hlipka | 0:41a49a73580c | 303 | is_sorted = true; |
hlipka | 0:41a49a73580c | 304 | } |
hlipka | 0:41a49a73580c | 305 | |
hlipka | 0:41a49a73580c | 306 | |
hlipka | 0:41a49a73580c | 307 | |
hlipka | 0:41a49a73580c | 308 | //! Performs a binary search for an element, returns -1 if not found. |
hlipka | 0:41a49a73580c | 309 | //! The array will be sorted before the binary search if it is not |
hlipka | 0:41a49a73580c | 310 | //! already sorted. |
hlipka | 0:41a49a73580c | 311 | //! \param element: Element to search for. |
hlipka | 0:41a49a73580c | 312 | //! \return Returns position of the searched element if it was found, |
hlipka | 0:41a49a73580c | 313 | //! otherwise -1 is returned. |
hlipka | 0:41a49a73580c | 314 | s32 binary_search(const T& element) |
hlipka | 0:41a49a73580c | 315 | { |
hlipka | 0:41a49a73580c | 316 | return binary_search(element, 0, used-1); |
hlipka | 0:41a49a73580c | 317 | } |
hlipka | 0:41a49a73580c | 318 | |
hlipka | 0:41a49a73580c | 319 | |
hlipka | 0:41a49a73580c | 320 | |
hlipka | 0:41a49a73580c | 321 | //! Performs a binary search for an element, returns -1 if not found. |
hlipka | 0:41a49a73580c | 322 | //! The array will be sorted before the binary search if it is not |
hlipka | 0:41a49a73580c | 323 | //! already sorted. |
hlipka | 0:41a49a73580c | 324 | //! \param element: Element to search for. |
hlipka | 0:41a49a73580c | 325 | //! \param left: First left index |
hlipka | 0:41a49a73580c | 326 | //! \param right: Last right index. |
hlipka | 0:41a49a73580c | 327 | //! \return Returns position of the searched element if it was found, |
hlipka | 0:41a49a73580c | 328 | //! otherwise -1 is returned. |
hlipka | 0:41a49a73580c | 329 | s32 binary_search(const T& element, s32 left, s32 right) |
hlipka | 0:41a49a73580c | 330 | { |
hlipka | 0:41a49a73580c | 331 | if (!used) |
hlipka | 0:41a49a73580c | 332 | return -1; |
hlipka | 0:41a49a73580c | 333 | |
hlipka | 0:41a49a73580c | 334 | sort(); |
hlipka | 0:41a49a73580c | 335 | |
hlipka | 0:41a49a73580c | 336 | s32 m; |
hlipka | 0:41a49a73580c | 337 | |
hlipka | 0:41a49a73580c | 338 | do |
hlipka | 0:41a49a73580c | 339 | { |
hlipka | 0:41a49a73580c | 340 | m = (left+right)>>1; |
hlipka | 0:41a49a73580c | 341 | |
hlipka | 0:41a49a73580c | 342 | if (element < data[m]) |
hlipka | 0:41a49a73580c | 343 | right = m - 1; |
hlipka | 0:41a49a73580c | 344 | else |
hlipka | 0:41a49a73580c | 345 | left = m + 1; |
hlipka | 0:41a49a73580c | 346 | |
hlipka | 0:41a49a73580c | 347 | } while((element < data[m] || data[m] < element) && left<=right); |
hlipka | 0:41a49a73580c | 348 | |
hlipka | 0:41a49a73580c | 349 | // this last line equals to: |
hlipka | 0:41a49a73580c | 350 | // " while((element != array[m]) && left<=right);" |
hlipka | 0:41a49a73580c | 351 | // but we only want to use the '<' operator. |
hlipka | 0:41a49a73580c | 352 | // the same in next line, it is "(element == array[m])" |
hlipka | 0:41a49a73580c | 353 | |
hlipka | 0:41a49a73580c | 354 | if (!(element < data[m]) && !(data[m] < element)) |
hlipka | 0:41a49a73580c | 355 | return m; |
hlipka | 0:41a49a73580c | 356 | |
hlipka | 0:41a49a73580c | 357 | return -1; |
hlipka | 0:41a49a73580c | 358 | } |
hlipka | 0:41a49a73580c | 359 | |
hlipka | 0:41a49a73580c | 360 | |
hlipka | 0:41a49a73580c | 361 | //! Finds an element in linear time, which is very slow. Use |
hlipka | 0:41a49a73580c | 362 | //! binary_search for faster finding. Only works if =operator is implemented. |
hlipka | 0:41a49a73580c | 363 | //! \param element: Element to search for. |
hlipka | 0:41a49a73580c | 364 | //! \return Returns position of the searched element if it was found, |
hlipka | 0:41a49a73580c | 365 | //! otherwise -1 is returned. |
hlipka | 0:41a49a73580c | 366 | s32 linear_search(T& element) |
hlipka | 0:41a49a73580c | 367 | { |
hlipka | 0:41a49a73580c | 368 | for (u32 i=0; i<used; ++i) |
hlipka | 0:41a49a73580c | 369 | if (!(element < data[i]) && !(data[i] < element)) |
hlipka | 0:41a49a73580c | 370 | return (s32)i; |
hlipka | 0:41a49a73580c | 371 | |
hlipka | 0:41a49a73580c | 372 | return -1; |
hlipka | 0:41a49a73580c | 373 | } |
hlipka | 0:41a49a73580c | 374 | |
hlipka | 0:41a49a73580c | 375 | |
hlipka | 0:41a49a73580c | 376 | //! Finds an element in linear time, which is very slow. Use |
hlipka | 0:41a49a73580c | 377 | //! binary_search for faster finding. Only works if =operator is implemented. |
hlipka | 0:41a49a73580c | 378 | //! \param element: Element to search for. |
hlipka | 0:41a49a73580c | 379 | //! \return Returns position of the searched element if it was found, |
hlipka | 0:41a49a73580c | 380 | //! otherwise -1 is returned. |
hlipka | 0:41a49a73580c | 381 | s32 linear_reverse_search(T& element) |
hlipka | 0:41a49a73580c | 382 | { |
hlipka | 0:41a49a73580c | 383 | for (s32 i=used-1; i>=0; --i) |
hlipka | 0:41a49a73580c | 384 | if (data[i] == element) |
hlipka | 0:41a49a73580c | 385 | return (s32)i; |
hlipka | 0:41a49a73580c | 386 | |
hlipka | 0:41a49a73580c | 387 | return -1; |
hlipka | 0:41a49a73580c | 388 | } |
hlipka | 0:41a49a73580c | 389 | |
hlipka | 0:41a49a73580c | 390 | |
hlipka | 0:41a49a73580c | 391 | |
hlipka | 0:41a49a73580c | 392 | //! Erases an element from the array. May be slow, because all elements |
hlipka | 0:41a49a73580c | 393 | //! following after the erased element have to be copied. |
hlipka | 0:41a49a73580c | 394 | //! \param index: Index of element to be erased. |
hlipka | 0:41a49a73580c | 395 | void erase(u32 index) |
hlipka | 0:41a49a73580c | 396 | { |
hlipka | 0:41a49a73580c | 397 | _IRR_DEBUG_BREAK_IF(index>=used || index<0) // access violation |
hlipka | 0:41a49a73580c | 398 | |
hlipka | 0:41a49a73580c | 399 | for (u32 i=index+1; i<used; ++i) |
hlipka | 0:41a49a73580c | 400 | data[i-1] = data[i]; |
hlipka | 0:41a49a73580c | 401 | |
hlipka | 0:41a49a73580c | 402 | --used; |
hlipka | 0:41a49a73580c | 403 | } |
hlipka | 0:41a49a73580c | 404 | |
hlipka | 0:41a49a73580c | 405 | |
hlipka | 0:41a49a73580c | 406 | //! Erases some elements from the array. may be slow, because all elements |
hlipka | 0:41a49a73580c | 407 | //! following after the erased element have to be copied. |
hlipka | 0:41a49a73580c | 408 | //! \param index: Index of the first element to be erased. |
hlipka | 0:41a49a73580c | 409 | //! \param count: Amount of elements to be erased. |
hlipka | 0:41a49a73580c | 410 | void erase(u32 index, s32 count) |
hlipka | 0:41a49a73580c | 411 | { |
hlipka | 0:41a49a73580c | 412 | _IRR_DEBUG_BREAK_IF(index>=used || index<0 || count<1 || index+count>used) // access violation |
hlipka | 0:41a49a73580c | 413 | |
hlipka | 0:41a49a73580c | 414 | for (u32 i=index+count; i<used; ++i) |
hlipka | 0:41a49a73580c | 415 | data[i-count] = data[i]; |
hlipka | 0:41a49a73580c | 416 | |
hlipka | 0:41a49a73580c | 417 | used-= count; |
hlipka | 0:41a49a73580c | 418 | } |
hlipka | 0:41a49a73580c | 419 | |
hlipka | 0:41a49a73580c | 420 | |
hlipka | 0:41a49a73580c | 421 | //! Sets if the array is sorted |
hlipka | 0:41a49a73580c | 422 | void set_sorted(bool _is_sorted) |
hlipka | 0:41a49a73580c | 423 | { |
hlipka | 0:41a49a73580c | 424 | is_sorted = _is_sorted; |
hlipka | 0:41a49a73580c | 425 | } |
hlipka | 0:41a49a73580c | 426 | |
hlipka | 0:41a49a73580c | 427 | |
hlipka | 0:41a49a73580c | 428 | private: |
hlipka | 0:41a49a73580c | 429 | |
hlipka | 0:41a49a73580c | 430 | T* data; |
hlipka | 0:41a49a73580c | 431 | u32 allocated; |
hlipka | 0:41a49a73580c | 432 | u32 used; |
hlipka | 0:41a49a73580c | 433 | bool free_when_destroyed; |
hlipka | 0:41a49a73580c | 434 | bool is_sorted; |
hlipka | 0:41a49a73580c | 435 | }; |
hlipka | 0:41a49a73580c | 436 | |
hlipka | 0:41a49a73580c | 437 | |
hlipka | 0:41a49a73580c | 438 | } // end namespace core |
hlipka | 0:41a49a73580c | 439 | } // end namespace irr |
hlipka | 0:41a49a73580c | 440 | |
hlipka | 0:41a49a73580c | 441 | |
hlipka | 0:41a49a73580c | 442 | |
hlipka | 0:41a49a73580c | 443 | #endif |