Vector.pkg 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. $#include "Vector.h"
  2. /// %Vector template class.
  3. class Vector : public VectorBase
  4. {
  5. TOLUA_TEMMPLATE_BIND(T, String)
  6. public:
  7. /// Construct empty.
  8. Vector()
  9. {
  10. }
  11. /// Construct with initial size.
  12. explicit Vector(unsigned size)
  13. {
  14. Resize(size, 0);
  15. }
  16. /// Construct with initial data.
  17. Vector(const T* data, unsigned size)
  18. {
  19. Resize(size, data);
  20. }
  21. /// Construct from another vector.
  22. Vector(const Vector<T>& vector)
  23. {
  24. *this = vector;
  25. }
  26. /// Destruct.
  27. ~Vector()
  28. {
  29. Clear();
  30. delete[] buffer_;
  31. }
  32. /// Add an element.
  33. Vector<T> operator + (const T& rhs) const
  34. {
  35. Vector<T> ret(*this);
  36. ret.Push(rhs);
  37. return ret;
  38. }
  39. /// Add another vector.
  40. Vector<T> operator + (const Vector<T>& rhs) const
  41. {
  42. Vector<T> ret(*this);
  43. ret.Push(rhs);
  44. return ret;
  45. }
  46. /// Test for equality with another vector.
  47. bool operator == (const Vector<T>& rhs) const
  48. {
  49. if (rhs.size_ != size_)
  50. return false;
  51. T* buffer = Buffer();
  52. T* rhsBuffer = rhs.Buffer();
  53. for (unsigned i = 0; i < size_; ++i)
  54. {
  55. if (buffer[i] != rhsBuffer[i])
  56. return false;
  57. }
  58. return true;
  59. }
  60. /// Return element at index.
  61. T& operator [] (unsigned index) { assert(index < size_); return Buffer()[index]; }
  62. /// Return const element at index.
  63. const T& operator [] (unsigned index) const { assert(index < size_); return Buffer()[index]; }
  64. /// Return element at index.
  65. T& At(unsigned index) { assert(index < size_); return Buffer()[index]; }
  66. /// Return const element at index.
  67. const T& At(unsigned index) const { assert(index < size_); return Buffer()[index]; }
  68. /// Add an element at the end.
  69. void Push(const T& value) { Resize(size_ + 1, &value); }
  70. /// Add another vector at the end.
  71. void Push(const Vector<T>& vector) { Resize(size_ + vector.size_, vector.Buffer()); }
  72. /// Remove the last element.
  73. void Pop()
  74. {
  75. if (size_)
  76. Resize(size_ - 1, 0);
  77. }
  78. /// Insert an element at position.
  79. void Insert(unsigned pos, const T& value)
  80. {
  81. if (pos > size_)
  82. pos = size_;
  83. unsigned oldSize = size_;
  84. Resize(size_ + 1, 0);
  85. MoveRange(pos + 1, pos, oldSize - pos);
  86. Buffer()[pos] = value;
  87. }
  88. /// Insert another vector at position.
  89. void Insert(unsigned pos, const Vector<T>& vector)
  90. {
  91. if (pos > size_)
  92. pos = size_;
  93. unsigned oldSize = size_;
  94. Resize(size_ + vector.size_, 0);
  95. MoveRange(pos + vector.size_, pos, oldSize - pos);
  96. CopyElements(Buffer() + pos, vector.Buffer(), vector.size_);
  97. }
  98. /// Erase a range of elements.
  99. void Erase(unsigned pos, unsigned length = 1)
  100. {
  101. // Return if the range is illegal
  102. if (pos + length > size_ || !length)
  103. return;
  104. MoveRange(pos, pos + length, size_ - pos - length);
  105. Resize(size_ - length, 0);
  106. }
  107. /// Erase an element if found.
  108. bool Remove(const T& value)
  109. {
  110. Iterator i = Find(value);
  111. if (i != End())
  112. {
  113. Erase(i);
  114. return true;
  115. }
  116. else
  117. return false;
  118. }
  119. /// Clear the vector.
  120. void Clear() { Resize(0); }
  121. /// Resize the vector.
  122. void Resize(unsigned newSize) { Resize(newSize, 0); }
  123. /// Set new capacity.
  124. void Reserve(unsigned newCapacity)
  125. {
  126. if (newCapacity < size_)
  127. newCapacity = size_;
  128. if (newCapacity != capacity_)
  129. {
  130. T* newBuffer = 0;
  131. capacity_ = newCapacity;
  132. if (capacity_)
  133. {
  134. newBuffer = reinterpret_cast<T*>(AllocateBuffer(capacity_ * sizeof(T)));
  135. // Move the data into the new buffer
  136. ConstructElements(newBuffer, Buffer(), size_);
  137. }
  138. // Delete the old buffer
  139. DestructElements(Buffer(), size_);
  140. delete[] buffer_;
  141. buffer_ = reinterpret_cast<unsigned char*>(newBuffer);
  142. }
  143. }
  144. /// Reallocate so that no extra memory is used.
  145. void Compact() { Reserve(size_); }
  146. /// Return whether contains a specific value.
  147. bool Contains(const T& value) const { return Find(value) != End(); }
  148. /// Return first element.
  149. T& Front() { assert(size_); return Buffer()[0]; }
  150. /// Return const first element.
  151. const T& Front() const { assert(size_); return Buffer()[0]; }
  152. /// Return last element.
  153. T& Back() { assert(size_); return Buffer()[size_ - 1]; }
  154. /// Return const last element.
  155. const T& Back() const { assert(size_); return Buffer()[size_ - 1]; }
  156. /// Return size of vector.
  157. unsigned Size() const { return size_; }
  158. /// Return capacity of vector.
  159. unsigned Capacity() const { return capacity_; }
  160. /// Return whether vector is empty.
  161. bool Empty() const { return size_ == 0; }
  162. };
  163. /// %Vector template class for POD types. Does not call constructors or destructors and uses block move.
  164. class PODVector
  165. {
  166. TOLUA_TEMPLATE_BIND(T, Vector3)
  167. public:
  168. /// Construct empty.
  169. PODVector()
  170. {
  171. }
  172. /// Construct with initial size.
  173. explicit PODVector(unsigned size)
  174. {
  175. Resize(size);
  176. }
  177. /// Construct with initial data.
  178. PODVector(const T* data, unsigned size)
  179. {
  180. Resize(size);
  181. CopyElements(Buffer(), data, size);
  182. }
  183. /// Destruct.
  184. ~PODVector()
  185. {
  186. delete[] buffer_;
  187. }
  188. /// Add an element.
  189. PODVector<T> operator + (const T& rhs) const
  190. {
  191. PODVector<T> ret(*this);
  192. ret.Push(rhs);
  193. return ret;
  194. }
  195. /// Add another vector.
  196. PODVector<T> operator + (const PODVector<T>& rhs) const
  197. {
  198. PODVector<T> ret(*this);
  199. ret.Push(rhs);
  200. return ret;
  201. }
  202. /// Test for equality with another vector.
  203. bool operator == (const PODVector<T>& rhs) const
  204. {
  205. if (rhs.size_ != size_)
  206. return false;
  207. T* buffer = Buffer();
  208. T* rhsBuffer = rhs.Buffer();
  209. for (unsigned i = 0; i < size_; ++i)
  210. {
  211. if (buffer[i] != rhsBuffer[i])
  212. return false;
  213. }
  214. return true;
  215. }
  216. /// Return element at index.
  217. T& operator [] (unsigned index) { assert(index < size_); return Buffer()[index]; }
  218. /// Return const element at index.
  219. const T& operator [] (unsigned index) const { assert(index < size_); return Buffer()[index]; }
  220. /// Return element at index.
  221. T& At(unsigned index) { assert(index < size_); return Buffer()[index]; }
  222. /// Return const element at index.
  223. const T& At(unsigned index) const { assert(index < size_); return Buffer()[index]; }
  224. /// Add an element at the end.
  225. void Push(const T& value)
  226. {
  227. if (size_ < capacity_)
  228. ++size_;
  229. else
  230. Resize(size_ + 1);
  231. Back() = value;
  232. }
  233. /// Add another vector at the end.
  234. void Push(const PODVector<T>& vector)
  235. {
  236. unsigned oldSize = size_;
  237. Resize(size_ + vector.size_);
  238. CopyElements(Buffer() + oldSize, vector.Buffer(), vector.size_);
  239. }
  240. /// Remove the last element.
  241. void Pop()
  242. {
  243. if (size_)
  244. Resize(size_ - 1);
  245. }
  246. /// Insert an element at position.
  247. void Insert(unsigned pos, const T& value)
  248. {
  249. if (pos > size_)
  250. pos = size_;
  251. unsigned oldSize = size_;
  252. Resize(size_ + 1);
  253. MoveRange(pos + 1, pos, oldSize - pos);
  254. Buffer()[pos] = value;
  255. }
  256. /// Insert another vector at position.
  257. void Insert(unsigned pos, const PODVector<T>& vector)
  258. {
  259. if (pos > size_)
  260. pos = size_;
  261. unsigned oldSize = size_;
  262. Resize(size_ + vector.size_);
  263. MoveRange(pos + vector.size_, pos, oldSize - pos);
  264. CopyElements(Buffer() + pos, vector.Buffer(), vector.size_);
  265. }
  266. /// Erase a range of elements.
  267. void Erase(unsigned pos, unsigned length = 1)
  268. {
  269. // Return if the range is illegal
  270. if (!length || pos + length > size_)
  271. return;
  272. MoveRange(pos, pos + length, size_ - pos - length);
  273. Resize(size_ - length);
  274. }
  275. /// Erase an element if found.
  276. bool Remove(const T& value)
  277. {
  278. Iterator i = Find(value);
  279. if (i != End())
  280. {
  281. Erase(i);
  282. return true;
  283. }
  284. else
  285. return false;
  286. }
  287. /// Clear the vector.
  288. void Clear() { Resize(0); }
  289. /// Resize the vector.
  290. void Resize(unsigned newSize)
  291. {
  292. if (newSize > capacity_)
  293. {
  294. if (!capacity_)
  295. capacity_ = newSize;
  296. else
  297. {
  298. while (capacity_ < newSize)
  299. capacity_ += (capacity_ + 1) >> 1;
  300. }
  301. unsigned char* newBuffer = AllocateBuffer(capacity_ * sizeof(T));
  302. // Move the data into the new buffer and delete the old
  303. if (buffer_)
  304. {
  305. CopyElements(reinterpret_cast<T*>(newBuffer), Buffer(), size_);
  306. delete[] buffer_;
  307. }
  308. buffer_ = newBuffer;
  309. }
  310. size_ = newSize;
  311. }
  312. /// Set new capacity.
  313. void Reserve(unsigned newCapacity)
  314. {
  315. if (newCapacity < size_)
  316. newCapacity = size_;
  317. if (newCapacity != capacity_)
  318. {
  319. unsigned char* newBuffer = 0;
  320. capacity_ = newCapacity;
  321. if (capacity_)
  322. {
  323. newBuffer = AllocateBuffer(capacity_ * sizeof(T));
  324. // Move the data into the new buffer
  325. CopyElements(reinterpret_cast<T*>(newBuffer), Buffer(), size_);
  326. }
  327. // Delete the old buffer
  328. delete[] buffer_;
  329. buffer_ = newBuffer;
  330. }
  331. }
  332. /// Reallocate so that no extra memory is used.
  333. void Compact() { Reserve(size_); }
  334. /// Return whether contains a specific value.
  335. bool Contains(const T& value) const { return Find(value) != End(); }
  336. /// Return first element.
  337. T& Front() { return Buffer()[0]; }
  338. /// Return const first element.
  339. const T& Front() const { return Buffer()[0]; }
  340. /// Return last element.
  341. T& Back() { assert(size_); return Buffer()[size_ - 1]; }
  342. /// Return const last element.
  343. const T& Back() const { assert(size_); return Buffer()[size_ - 1]; }
  344. /// Return number of elements.
  345. unsigned Size() const { return size_; }
  346. /// Return capacity of vector.
  347. unsigned Capacity() const { return capacity_; }
  348. /// Return whether vector is empty.
  349. bool Empty() const { return size_ == 0; }
  350. };