1 //////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // Nestopia - NES/Famicom emulator written in C++ 4 // 5 // Copyright (C) 2003-2008 Martin Freij 6 // 7 // This file is part of Nestopia. 8 // 9 // Nestopia is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU General Public License as published by 11 // the Free Software Foundation; either version 2 of the License, or 12 // (at your option) any later version. 13 // 14 // Nestopia is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with Nestopia; if not, write to the Free Software 21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 // 23 //////////////////////////////////////////////////////////////////////////////////////// 24 25 #ifndef NST_COLLECTION_VECTOR_H 26 #define NST_COLLECTION_VECTOR_H 27 28 #pragma once 29 30 #include <cstdlib> 31 #include "NstMain.hpp" 32 33 namespace Nestopia 34 { 35 namespace Collection 36 { 37 template<typename T> class Vector; 38 39 template<> 40 class Vector<void> 41 { 42 protected: 43 44 union 45 { 46 void* data; 47 uchar* bytes; 48 }; 49 50 uint capacity; 51 uint size; 52 53 explicit Vector(uint); 54 Vector(const Vector&); 55 Vector(const void* NST_RESTRICT,uint); 56 57 void operator = (const Vector&); 58 59 void Assign(const void* NST_RESTRICT,uint); 60 void Append(const void* NST_RESTRICT,uint); 61 void Insert(void*,const void* NST_RESTRICT,uint); 62 void Erase(void*,void*); 63 void Reserve(uint); 64 void Resize(uint); 65 void Grow(uint); 66 67 bool Valid(const void*) const; 68 bool InBound(const void*) const; 69 Vector()70 Vector() 71 : data(NULL), capacity(0), size(0) {} 72 ~Vector()73 ~Vector() 74 { 75 NST_ASSERT 76 ( 77 capacity >= size && 78 bool(data) >= bool(size) && 79 bool(data) >= bool(capacity) 80 ); 81 82 std::free( data ); 83 } 84 Shrink(uint inSize)85 void Shrink(uint inSize) 86 { 87 NST_ASSERT( size >= inSize ); 88 size -= inSize; 89 } 90 91 public: 92 93 void Destroy(); 94 void Defrag(); 95 void Import(Vector&); 96 Empty() const97 bool Empty() const 98 { 99 return !size; 100 } 101 Clear()102 void Clear() 103 { 104 size = 0; 105 } 106 }; 107 108 template<typename T> class Vector : public Vector<void> 109 { 110 public: 111 112 typedef T Type; 113 typedef T* Iterator; 114 typedef const T* ConstIterator; 115 116 enum 117 { 118 ITEM_SIZE = sizeof(Type) 119 }; 120 Vector()121 Vector() {} 122 Vector(const Type * items,uint count)123 Vector(const Type* items,uint count) 124 : Vector<void>(items,ITEM_SIZE * count) {} 125 Vector(uint count)126 explicit Vector(uint count) 127 : Vector<void>(count * ITEM_SIZE) {} 128 Vector(const Vector<T> & vector)129 Vector(const Vector<T>& vector) 130 : Vector<void>(vector) {} 131 operator =(const Vector<T> & vector)132 Vector& operator = (const Vector<T>& vector) 133 { 134 Vector<void>::operator = (vector); 135 return *this; 136 } 137 PushBack(const Type & item)138 void PushBack(const Type& item) 139 { 140 Vector<void>::Append( &item, ITEM_SIZE ); 141 } 142 PushBack(const Vector<T> & vector)143 void PushBack(const Vector<T>& vector) 144 { 145 Vector<void>::Append( vector.data, vector.size ); 146 } 147 Assign(ConstIterator items,uint count)148 void Assign(ConstIterator items,uint count) 149 { 150 Vector<void>::Assign( items, ITEM_SIZE * count ); 151 } 152 Append(ConstIterator items,uint count)153 void Append(ConstIterator items,uint count) 154 { 155 Vector<void>::Append( items, ITEM_SIZE * count ); 156 } 157 Insert(Iterator pos,ConstIterator items,uint count)158 void Insert(Iterator pos,ConstIterator items,uint count) 159 { 160 Vector<void>::Insert( pos, items, ITEM_SIZE * count ); 161 } 162 Insert(Iterator pos,const Type & item)163 void Insert(Iterator pos,const Type& item) 164 { 165 Vector<void>::Insert( pos, &item, ITEM_SIZE ); 166 } 167 Erase(Iterator begin,Iterator end)168 void Erase(Iterator begin,Iterator end) 169 { 170 Vector<void>::Erase( begin, end ); 171 } 172 Erase(Iterator offset,uint count=1)173 void Erase(Iterator offset,uint count=1) 174 { 175 Vector<void>::Erase( offset, offset + count ); 176 } 177 operator [](uint i)178 Type& operator [] (uint i) 179 { 180 return static_cast<Type*>(data)[i]; 181 } 182 operator [](uint i) const183 const Type& operator [] (uint i) const 184 { 185 return static_cast<Type*>(data)[i]; 186 } 187 Ptr()188 Type* Ptr() 189 { 190 return static_cast<Type*>(data); 191 } 192 Ptr() const193 const Type* Ptr() const 194 { 195 return static_cast<const Type*>(data); 196 } 197 Begin()198 Iterator Begin() 199 { 200 return static_cast<Iterator>(data); 201 } 202 Begin() const203 ConstIterator Begin() const 204 { 205 return static_cast<ConstIterator>(data); 206 } 207 End()208 Iterator End() 209 { 210 return reinterpret_cast<Iterator>(bytes + size); 211 } 212 End() const213 ConstIterator End() const 214 { 215 return reinterpret_cast<ConstIterator>(bytes + size); 216 } 217 At(uint pos)218 Iterator At(uint pos) 219 { 220 return static_cast<Iterator>(data) + pos; 221 } 222 At(uint pos) const223 ConstIterator At(uint pos) const 224 { 225 return static_cast<ConstIterator>(data) + pos; 226 } 227 Front()228 Type& Front() 229 { 230 NST_ASSERT( size ); 231 return *static_cast<Iterator>(data); 232 } 233 Front() const234 const Type& Front() const 235 { 236 NST_ASSERT( size ); 237 return *static_cast<ConstIterator>(data); 238 } 239 Back()240 Type& Back() 241 { 242 NST_ASSERT( size ); 243 return *(reinterpret_cast<Iterator>(bytes + size) - 1); 244 } 245 Back() const246 const Type& Back() const 247 { 248 NST_ASSERT( size ); 249 return *(reinterpret_cast<ConstIterator>(bytes + size) - 1); 250 } 251 Size() const252 uint Size() const 253 { 254 NST_ASSERT( size % ITEM_SIZE == 0 ); 255 return size / ITEM_SIZE; 256 } 257 Length() const258 uint Length() const 259 { 260 return Size(); 261 } 262 Capacity() const263 uint Capacity() const 264 { 265 NST_ASSERT( capacity % ITEM_SIZE == 0 ); 266 return capacity / ITEM_SIZE; 267 } 268 Reserve(uint count)269 void Reserve(uint count) 270 { 271 Vector<void>::Reserve( count * ITEM_SIZE ); 272 } 273 Resize(uint count)274 void Resize(uint count) 275 { 276 Vector<void>::Resize( count * ITEM_SIZE ); 277 } 278 SetTo(uint count)279 void SetTo(uint count) 280 { 281 size = count * ITEM_SIZE; 282 NST_ASSERT( capacity >= size ); 283 } 284 Grow(uint count=1)285 void Grow(uint count=1) 286 { 287 Vector<void>::Grow( count * ITEM_SIZE ); 288 } 289 Shrink(uint count=1)290 void Shrink(uint count=1) 291 { 292 Vector<void>::Shrink( count * ITEM_SIZE ); 293 } 294 InBound(ConstIterator it) const295 bool InBound(ConstIterator it) const 296 { 297 return Vector<void>::InBound( it ); 298 } 299 Valid(ConstIterator it) const300 bool Valid(ConstIterator it) const 301 { 302 return Vector<void>::Valid( it ); 303 } 304 305 template<typename Value> 306 ConstIterator Find(const Value&) const; 307 308 template<typename Value> Find(const Value & value)309 Iterator Find(const Value& value) 310 { 311 ConstIterator const it = static_cast<const Vector<T>*>(this)->Find( value ); 312 return reinterpret_cast<Type*>(bytes + (reinterpret_cast<const uchar*>(it) - bytes)); 313 } 314 }; 315 316 template<typename T> template<typename Value> Find(const Value & value) const317 typename Vector<T>::ConstIterator Vector<T>::Find(const Value& value) const 318 { 319 for (ConstIterator it(Ptr()), end(End()); it != end; ++it) 320 if (*it == value) 321 return it; 322 323 return NULL; 324 } 325 } 326 } 327 328 #endif 329