Vector.h 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  1. //
  2. // Copyright (c) 2008-2019 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Container/VectorBase.h"
  24. #include <cassert>
  25. #include <cstring>
  26. #include <algorithm>
  27. #include <initializer_list>
  28. #include <new>
  29. #include <utility>
  30. #ifdef _MSC_VER
  31. #pragma warning(push)
  32. #pragma warning(disable:6293)
  33. #endif
  34. namespace Urho3D
  35. {
  36. /// %Vector template class.
  37. template <class T> class Vector : public VectorBase
  38. {
  39. struct CopyTag {};
  40. struct MoveTag {};
  41. public:
  42. using ValueType = T;
  43. using Iterator = RandomAccessIterator<T>;
  44. using ConstIterator = RandomAccessConstIterator<T>;
  45. /// Construct empty.
  46. Vector() noexcept = default;
  47. /// Construct with initial size.
  48. explicit Vector(unsigned size)
  49. {
  50. Resize(size);
  51. }
  52. /// Construct with initial size and default value.
  53. Vector(unsigned size, const T& value)
  54. {
  55. Resize(size);
  56. for (unsigned i = 0; i < size; ++i)
  57. At(i) = value;
  58. }
  59. /// Construct with initial data.
  60. Vector(const T* data, unsigned size)
  61. {
  62. DoInsertElements(0, data, data + size, CopyTag{});
  63. }
  64. /// Copy-construct from another vector.
  65. Vector(const Vector<T>& vector)
  66. {
  67. DoInsertElements(0, vector.Begin(), vector.End(), CopyTag{});
  68. }
  69. /// Copy-construct from another vector (iterator version)
  70. Vector(ConstIterator start, ConstIterator end)
  71. {
  72. DoInsertElements(0, start, end, CopyTag{});
  73. }
  74. /// Move-construct from another vector.
  75. Vector(Vector<T> && vector)
  76. {
  77. Swap(vector);
  78. }
  79. /// Aggregate initialization constructor.
  80. Vector(const std::initializer_list<T>& list) : Vector()
  81. {
  82. for (auto it = list.begin(); it != list.end(); it++)
  83. {
  84. Push(*it);
  85. }
  86. }
  87. /// Destruct.
  88. ~Vector()
  89. {
  90. DestructElements(Buffer(), size_);
  91. delete[] buffer_;
  92. }
  93. /// Assign from another vector.
  94. Vector<T>& operator =(const Vector<T>& rhs)
  95. {
  96. // In case of self-assignment do nothing
  97. if (&rhs != this)
  98. {
  99. Vector<T> copy(rhs);
  100. Swap(copy);
  101. }
  102. return *this;
  103. }
  104. /// Move-assign from another vector.
  105. Vector<T>& operator =(Vector<T> && rhs)
  106. {
  107. assert(&rhs != this);
  108. Swap(rhs);
  109. return *this;
  110. }
  111. /// Add-assign an element.
  112. Vector<T>& operator +=(const T& rhs)
  113. {
  114. Push(rhs);
  115. return *this;
  116. }
  117. /// Add-assign another vector.
  118. Vector<T>& operator +=(const Vector<T>& rhs)
  119. {
  120. Push(rhs);
  121. return *this;
  122. }
  123. /// Add an element.
  124. Vector<T> operator +(const T& rhs) const
  125. {
  126. Vector<T> ret(*this);
  127. ret.Push(rhs);
  128. return ret;
  129. }
  130. /// Add another vector.
  131. Vector<T> operator +(const Vector<T>& rhs) const
  132. {
  133. Vector<T> ret(*this);
  134. ret.Push(rhs);
  135. return ret;
  136. }
  137. /// Test for equality with another vector.
  138. bool operator ==(const Vector<T>& rhs) const
  139. {
  140. if (rhs.size_ != size_)
  141. return false;
  142. T* buffer = Buffer();
  143. T* rhsBuffer = rhs.Buffer();
  144. for (unsigned i = 0; i < size_; ++i)
  145. {
  146. if (buffer[i] != rhsBuffer[i])
  147. return false;
  148. }
  149. return true;
  150. }
  151. /// Test for inequality with another vector.
  152. bool operator !=(const Vector<T>& rhs) const
  153. {
  154. if (rhs.size_ != size_)
  155. return true;
  156. T* buffer = Buffer();
  157. T* rhsBuffer = rhs.Buffer();
  158. for (unsigned i = 0; i < size_; ++i)
  159. {
  160. if (buffer[i] != rhsBuffer[i])
  161. return true;
  162. }
  163. return false;
  164. }
  165. /// Return element at index.
  166. T& operator [](unsigned index)
  167. {
  168. assert(index < size_);
  169. return Buffer()[index];
  170. }
  171. /// Return const element at index.
  172. const T& operator [](unsigned index) const
  173. {
  174. assert(index < size_);
  175. return Buffer()[index];
  176. }
  177. /// Return element at index.
  178. T& At(unsigned index)
  179. {
  180. assert(index < size_);
  181. return Buffer()[index];
  182. }
  183. /// Return const element at index.
  184. const T& At(unsigned index) const
  185. {
  186. assert(index < size_);
  187. return Buffer()[index];
  188. }
  189. /// Create an element at the end.
  190. template <class... Args> T& EmplaceBack(Args&&... args)
  191. {
  192. if (size_ < capacity_)
  193. {
  194. // Optimize common case
  195. ++size_;
  196. new (&Back()) T(std::forward<Args>(args)...);
  197. }
  198. else
  199. {
  200. T value(std::forward<Args>(args)...);
  201. Push(std::move(value));
  202. }
  203. return Back();
  204. }
  205. /// Add an element at the end.
  206. #ifndef COVERITY_SCAN_MODEL
  207. void Push(const T& value)
  208. {
  209. if (size_ < capacity_)
  210. {
  211. // Optimize common case
  212. ++size_;
  213. new (&Back()) T(value);
  214. }
  215. else
  216. DoInsertElements(size_, &value, &value + 1, CopyTag{});
  217. }
  218. /// Move-add an element at the end.
  219. void Push(T && value)
  220. {
  221. if (size_ < capacity_)
  222. {
  223. // Optimize common case
  224. ++size_;
  225. new (&Back()) T(std::move(value));
  226. }
  227. else
  228. DoInsertElements(size_, &value, &value + 1, MoveTag{});
  229. }
  230. #else
  231. // FIXME: Attempt had been made to use this model in the Coverity-Scan model file without any success
  232. // Probably because the model had generated a different mangled name than the one used by static analyzer
  233. void Push(const T& value)
  234. {
  235. T array[] = {value};
  236. DoInsertElements(size_, array, array + 1, CopyTag{});
  237. }
  238. #endif
  239. /// Add another vector at the end.
  240. void Push(const Vector<T>& vector) { DoInsertElements(size_, vector.Begin(), vector.End(), CopyTag{}); }
  241. /// Remove the last element.
  242. void Pop()
  243. {
  244. if (size_)
  245. Resize(size_ - 1);
  246. }
  247. /// Insert an element at position.
  248. void Insert(unsigned pos, const T& value)
  249. {
  250. DoInsertElements(pos, &value, &value + 1, CopyTag{});
  251. }
  252. /// Insert an element at position.
  253. void Insert(unsigned pos, T && value)
  254. {
  255. DoInsertElements(pos, &value, &value + 1, MoveTag{});
  256. }
  257. /// Insert another vector at position.
  258. void Insert(unsigned pos, const Vector<T>& vector)
  259. {
  260. DoInsertElements(pos, vector.Begin(), vector.End(), CopyTag{});
  261. }
  262. /// Insert an element by iterator.
  263. Iterator Insert(const Iterator& dest, const T& value)
  264. {
  265. auto pos = (unsigned)(dest - Begin());
  266. return DoInsertElements(pos, &value, &value + 1, CopyTag{});
  267. }
  268. /// Move-insert an element by iterator.
  269. Iterator Insert(const Iterator& dest, T && value)
  270. {
  271. auto pos = (unsigned)(dest - Begin());
  272. return DoInsertElements(pos, &value, &value + 1, MoveTag{});
  273. }
  274. /// Insert a vector by iterator.
  275. Iterator Insert(const Iterator& dest, const Vector<T>& vector)
  276. {
  277. auto pos = (unsigned)(dest - Begin());
  278. return DoInsertElements(pos, vector.Begin(), vector.End(), CopyTag{});
  279. }
  280. /// Insert a vector partially by iterators.
  281. Iterator Insert(const Iterator& dest, const ConstIterator& start, const ConstIterator& end)
  282. {
  283. auto pos = (unsigned)(dest - Begin());
  284. return DoInsertElements(pos, start, end, CopyTag{});
  285. }
  286. /// Insert elements.
  287. Iterator Insert(const Iterator& dest, const T* start, const T* end)
  288. {
  289. auto pos = (unsigned)(dest - Begin());
  290. return DoInsertElements(pos, start, end, CopyTag{});
  291. }
  292. /// Erase a range of elements.
  293. void Erase(unsigned pos, unsigned length = 1)
  294. {
  295. // Return if the range is illegal
  296. if (pos + length > size_ || !length)
  297. return;
  298. DoEraseElements(pos, length);
  299. }
  300. /// Erase a range of elements by swapping elements from the end of the array.
  301. void EraseSwap(unsigned pos, unsigned length = 1)
  302. {
  303. unsigned shiftStartIndex = pos + length;
  304. // Return if the range is illegal
  305. if (shiftStartIndex > size_ || !length)
  306. return;
  307. unsigned newSize = size_ - length;
  308. unsigned trailingCount = size_ - shiftStartIndex;
  309. if (trailingCount <= length)
  310. {
  311. // We're removing more elements from the array than exist past the end of the range being removed, so perform a normal shift and destroy
  312. DoEraseElements(pos, length);
  313. }
  314. else
  315. {
  316. // Swap elements from the end of the array into the empty space
  317. T* buffer = Buffer();
  318. std::move(buffer + newSize, buffer + size_, buffer + pos);
  319. Resize(newSize);
  320. }
  321. }
  322. /// Erase an element by iterator. Return iterator to the next element.
  323. Iterator Erase(const Iterator& it)
  324. {
  325. auto pos = (unsigned)(it - Begin());
  326. if (pos >= size_)
  327. return End();
  328. Erase(pos);
  329. return Begin() + pos;
  330. }
  331. /// Erase a range by iterators. Return iterator to the next element.
  332. Iterator Erase(const Iterator& start, const Iterator& end)
  333. {
  334. auto pos = (unsigned)(start - Begin());
  335. if (pos >= size_)
  336. return End();
  337. auto length = (unsigned)(end - start);
  338. Erase(pos, length);
  339. return Begin() + pos;
  340. }
  341. /// Erase an element by value. Return true if was found and erased.
  342. bool Remove(const T& value)
  343. {
  344. Iterator i = Find(value);
  345. if (i != End())
  346. {
  347. Erase(i);
  348. return true;
  349. }
  350. else
  351. return false;
  352. }
  353. /// Erase an element by value by swapping with the last element. Return true if was found and erased.
  354. bool RemoveSwap(const T& value)
  355. {
  356. Iterator i = Find(value);
  357. if (i != End())
  358. {
  359. EraseSwap(i - Begin());
  360. return true;
  361. }
  362. else
  363. return false;
  364. }
  365. /// Clear the vector.
  366. void Clear() { Resize(0); }
  367. /// Resize the vector.
  368. void Resize(unsigned newSize) { DoResize(newSize); }
  369. /// Resize the vector and fill new elements with default value.
  370. void Resize(unsigned newSize, const T& value)
  371. {
  372. unsigned oldSize = Size();
  373. DoResize(newSize);
  374. for (unsigned i = oldSize; i < newSize; ++i)
  375. At(i) = value;
  376. }
  377. /// Set new capacity.
  378. void Reserve(unsigned newCapacity)
  379. {
  380. if (newCapacity < size_)
  381. newCapacity = size_;
  382. if (newCapacity != capacity_)
  383. {
  384. T* newBuffer = nullptr;
  385. capacity_ = newCapacity;
  386. if (capacity_)
  387. {
  388. newBuffer = reinterpret_cast<T*>(AllocateBuffer((unsigned)(capacity_ * sizeof(T))));
  389. // Move the data into the new buffer
  390. ConstructElements(newBuffer, Begin(), End(), MoveTag{});
  391. }
  392. // Delete the old buffer
  393. DestructElements(Buffer(), size_);
  394. delete[] buffer_;
  395. buffer_ = reinterpret_cast<unsigned char*>(newBuffer);
  396. }
  397. }
  398. /// Reallocate so that no extra memory is used.
  399. void Compact() { Reserve(size_); }
  400. /// Return iterator to value, or to the end if not found.
  401. Iterator Find(const T& value)
  402. {
  403. Iterator it = Begin();
  404. while (it != End() && *it != value)
  405. ++it;
  406. return it;
  407. }
  408. /// Return const iterator to value, or to the end if not found.
  409. ConstIterator Find(const T& value) const
  410. {
  411. ConstIterator it = Begin();
  412. while (it != End() && *it != value)
  413. ++it;
  414. return it;
  415. }
  416. /// Return index of value in vector, or size if not found.
  417. unsigned IndexOf(const T& value) const
  418. {
  419. return Find(value) - Begin();
  420. }
  421. /// Return whether contains a specific value.
  422. bool Contains(const T& value) const { return Find(value) != End(); }
  423. /// Return iterator to the beginning.
  424. Iterator Begin() { return Iterator(Buffer()); }
  425. /// Return const iterator to the beginning.
  426. ConstIterator Begin() const { return ConstIterator(Buffer()); }
  427. /// Return iterator to the end.
  428. Iterator End() { return Iterator(Buffer() + size_); }
  429. /// Return const iterator to the end.
  430. ConstIterator End() const { return ConstIterator(Buffer() + size_); }
  431. /// Return first element.
  432. T& Front()
  433. {
  434. assert(size_);
  435. return Buffer()[0];
  436. }
  437. /// Return const first element.
  438. const T& Front() const
  439. {
  440. assert(size_);
  441. return Buffer()[0];
  442. }
  443. /// Return last element.
  444. T& Back()
  445. {
  446. assert(size_);
  447. return Buffer()[size_ - 1];
  448. }
  449. /// Return const last element.
  450. const T& Back() const
  451. {
  452. assert(size_);
  453. return Buffer()[size_ - 1];
  454. }
  455. /// Return size of vector.
  456. unsigned Size() const { return size_; }
  457. /// Return capacity of vector.
  458. unsigned Capacity() const { return capacity_; }
  459. /// Return whether vector is empty.
  460. bool Empty() const { return size_ == 0; }
  461. /// Return the buffer with right type.
  462. T* Buffer() const { return reinterpret_cast<T*>(buffer_); }
  463. private:
  464. /// Construct elements using default ctor.
  465. static void ConstructElements(T* dest, unsigned count)
  466. {
  467. for (unsigned i = 0; i < count; ++i)
  468. new(dest + i) T();
  469. }
  470. /// Copy-construct elements.
  471. template <class RandomIteratorT>
  472. static void ConstructElements(T* dest, RandomIteratorT start, RandomIteratorT end, CopyTag)
  473. {
  474. const unsigned count = end - start;
  475. for (unsigned i = 0; i < count; ++i)
  476. new(dest + i) T(*(start + i));
  477. }
  478. /// Move-construct elements.
  479. template <class RandomIteratorT>
  480. static void ConstructElements(T* dest, RandomIteratorT start, RandomIteratorT end, MoveTag)
  481. {
  482. const unsigned count = end - start;
  483. for (unsigned i = 0; i < count; ++i)
  484. new(dest + i) T(std::move(*(start + i)));
  485. }
  486. /// Calculate new vector capacity.
  487. static unsigned CalculateCapacity(unsigned size, unsigned capacity)
  488. {
  489. if (!capacity)
  490. return size;
  491. else
  492. {
  493. while (capacity < size)
  494. capacity += (capacity + 1) >> 1;
  495. return capacity;
  496. }
  497. }
  498. /// Resize the vector and create/remove new elements as necessary.
  499. void DoResize(unsigned newSize)
  500. {
  501. // If size shrinks, destruct the removed elements
  502. if (newSize < size_)
  503. DestructElements(Buffer() + newSize, size_ - newSize);
  504. else
  505. {
  506. // Allocate new buffer if necessary and copy the current elements
  507. if (newSize > capacity_)
  508. {
  509. T* src = Buffer();
  510. // Reallocate vector
  511. Vector<T> newVector;
  512. newVector.Reserve(CalculateCapacity(newSize, capacity_));
  513. newVector.size_ = size_;
  514. T* dest = newVector.Buffer();
  515. // Move old elements
  516. ConstructElements(dest, src, src + size_, MoveTag{});
  517. Swap(newVector);
  518. }
  519. // Initialize the new elements
  520. ConstructElements(Buffer() + size_, newSize - size_);
  521. }
  522. size_ = newSize;
  523. }
  524. /// Insert elements into the vector using copy or move constructor.
  525. template <class Tag, class RandomIteratorT>
  526. Iterator DoInsertElements(unsigned pos, RandomIteratorT start, RandomIteratorT end, Tag)
  527. {
  528. if (pos > size_)
  529. pos = size_;
  530. const unsigned numElements = end - start;
  531. if (size_ + numElements > capacity_)
  532. {
  533. T* src = Buffer();
  534. // Reallocate vector
  535. Vector<T> newVector;
  536. newVector.Reserve(CalculateCapacity(size_ + numElements, capacity_));
  537. newVector.size_ = size_ + numElements;
  538. T* dest = newVector.Buffer();
  539. // Copy or move new elements
  540. ConstructElements(dest + pos, start, end, Tag{});
  541. // Move old elements
  542. if (pos > 0)
  543. ConstructElements(dest, src, src + pos, MoveTag{});
  544. if (pos < size_)
  545. ConstructElements(dest + pos + numElements, src + pos, src + size_, MoveTag{});
  546. Swap(newVector);
  547. }
  548. else if (numElements > 0)
  549. {
  550. T* buffer = Buffer();
  551. // Copy or move new elements
  552. ConstructElements(buffer + size_, start, end, Tag{});
  553. // Rotate buffer
  554. if (pos < size_)
  555. {
  556. std::rotate(buffer + pos, buffer + size_, buffer + size_ + numElements);
  557. }
  558. // Update size
  559. size_ += numElements;
  560. }
  561. return Begin() + pos;
  562. }
  563. /// Erase elements from the vector.
  564. Iterator DoEraseElements(unsigned pos, unsigned count)
  565. {
  566. assert(count > 0);
  567. assert(pos + count <= size_);
  568. T* buffer = Buffer();
  569. std::move(buffer + pos + count, buffer + size_, buffer + pos);
  570. Resize(size_ - count);
  571. return Begin() + pos;
  572. }
  573. /// Call the elements' destructors.
  574. static void DestructElements(T* dest, unsigned count)
  575. {
  576. while (count--)
  577. {
  578. dest->~T();
  579. ++dest;
  580. }
  581. }
  582. };
  583. /// %Vector template class for POD types. Does not call constructors or destructors and uses block move. Is intentionally (for performance reasons) unsafe for self-insertion.
  584. template <class T> class PODVector : public VectorBase
  585. {
  586. public:
  587. using ValueType = T;
  588. using Iterator = RandomAccessIterator<T>;
  589. using ConstIterator = RandomAccessConstIterator<T>;
  590. /// Construct empty.
  591. PODVector() noexcept = default;
  592. /// Construct with initial size.
  593. explicit PODVector(unsigned size)
  594. {
  595. Resize(size);
  596. }
  597. /// Construct with initial size and default value.
  598. PODVector(unsigned size, const T& value)
  599. {
  600. Resize(size);
  601. for (unsigned i = 0; i < size; ++i)
  602. At(i) = value;
  603. }
  604. /// Construct with initial data.
  605. PODVector(const T* data, unsigned size)
  606. {
  607. Resize(size);
  608. CopyElements(Buffer(), data, size);
  609. }
  610. /// Construct from another vector.
  611. PODVector(const PODVector<T>& vector)
  612. {
  613. *this = vector;
  614. }
  615. /// Aggregate initialization constructor.
  616. PODVector(const std::initializer_list<T>& list) : PODVector()
  617. {
  618. for (auto it = list.begin(); it != list.end(); it++)
  619. {
  620. Push(*it);
  621. }
  622. }
  623. /// Destruct.
  624. ~PODVector()
  625. {
  626. delete[] buffer_;
  627. }
  628. /// Assign from another vector.
  629. PODVector<T>& operator =(const PODVector<T>& rhs)
  630. {
  631. // In case of self-assignment do nothing
  632. if (&rhs != this)
  633. {
  634. Resize(rhs.size_);
  635. CopyElements(Buffer(), rhs.Buffer(), rhs.size_);
  636. }
  637. return *this;
  638. }
  639. /// Add-assign an element.
  640. PODVector<T>& operator +=(const T& rhs)
  641. {
  642. Push(rhs);
  643. return *this;
  644. }
  645. /// Add-assign another vector.
  646. PODVector<T>& operator +=(const PODVector<T>& rhs)
  647. {
  648. Push(rhs);
  649. return *this;
  650. }
  651. /// Add an element.
  652. PODVector<T> operator +(const T& rhs) const
  653. {
  654. PODVector<T> ret(*this);
  655. ret.Push(rhs);
  656. return ret;
  657. }
  658. /// Add another vector.
  659. PODVector<T> operator +(const PODVector<T>& rhs) const
  660. {
  661. PODVector<T> ret(*this);
  662. ret.Push(rhs);
  663. return ret;
  664. }
  665. /// Test for equality with another vector.
  666. bool operator ==(const PODVector<T>& rhs) const
  667. {
  668. if (rhs.size_ != size_)
  669. return false;
  670. T* buffer = Buffer();
  671. T* rhsBuffer = rhs.Buffer();
  672. for (unsigned i = 0; i < size_; ++i)
  673. {
  674. if (buffer[i] != rhsBuffer[i])
  675. return false;
  676. }
  677. return true;
  678. }
  679. /// Test for inequality with another vector.
  680. bool operator !=(const PODVector<T>& rhs) const
  681. {
  682. if (rhs.size_ != size_)
  683. return true;
  684. T* buffer = Buffer();
  685. T* rhsBuffer = rhs.Buffer();
  686. for (unsigned i = 0; i < size_; ++i)
  687. {
  688. if (buffer[i] != rhsBuffer[i])
  689. return true;
  690. }
  691. return false;
  692. }
  693. /// Return element at index.
  694. T& operator [](unsigned index)
  695. {
  696. assert(index < size_);
  697. return Buffer()[index];
  698. }
  699. /// Return const element at index.
  700. const T& operator [](unsigned index) const
  701. {
  702. assert(index < size_);
  703. return Buffer()[index];
  704. }
  705. /// Return element at index.
  706. T& At(unsigned index)
  707. {
  708. assert(index < size_);
  709. return Buffer()[index];
  710. }
  711. /// Return const element at index.
  712. const T& At(unsigned index) const
  713. {
  714. assert(index < size_);
  715. return Buffer()[index];
  716. }
  717. /// Add an element at the end.
  718. void Push(const T& value)
  719. {
  720. if (size_ < capacity_)
  721. ++size_;
  722. else
  723. Resize(size_ + 1);
  724. Back() = value;
  725. }
  726. /// Add another vector at the end.
  727. void Push(const PODVector<T>& vector)
  728. {
  729. unsigned oldSize = size_;
  730. Resize(size_ + vector.size_);
  731. CopyElements(Buffer() + oldSize, vector.Buffer(), vector.size_);
  732. }
  733. /// Remove the last element.
  734. void Pop()
  735. {
  736. if (size_)
  737. Resize(size_ - 1);
  738. }
  739. /// Insert an element at position.
  740. void Insert(unsigned pos, const T& value)
  741. {
  742. if (pos > size_)
  743. pos = size_;
  744. unsigned oldSize = size_;
  745. Resize(size_ + 1);
  746. MoveRange(pos + 1, pos, oldSize - pos);
  747. Buffer()[pos] = value;
  748. }
  749. /// Insert another vector at position.
  750. void Insert(unsigned pos, const PODVector<T>& vector)
  751. {
  752. if (pos > size_)
  753. pos = size_;
  754. unsigned oldSize = size_;
  755. Resize(size_ + vector.size_);
  756. MoveRange(pos + vector.size_, pos, oldSize - pos);
  757. CopyElements(Buffer() + pos, vector.Buffer(), vector.size_);
  758. }
  759. /// Insert an element by iterator.
  760. Iterator Insert(const Iterator& dest, const T& value)
  761. {
  762. auto pos = (unsigned)(dest - Begin());
  763. if (pos > size_)
  764. pos = size_;
  765. Insert(pos, value);
  766. return Begin() + pos;
  767. }
  768. /// Insert a vector by iterator.
  769. Iterator Insert(const Iterator& dest, const PODVector<T>& vector)
  770. {
  771. auto pos = (unsigned)(dest - Begin());
  772. if (pos > size_)
  773. pos = size_;
  774. Insert(pos, vector);
  775. return Begin() + pos;
  776. }
  777. /// Insert a vector partially by iterators.
  778. Iterator Insert(const Iterator& dest, const ConstIterator& start, const ConstIterator& end)
  779. {
  780. auto pos = (unsigned)(dest - Begin());
  781. if (pos > size_)
  782. pos = size_;
  783. auto length = (unsigned)(end - start);
  784. Resize(size_ + length);
  785. MoveRange(pos + length, pos, size_ - pos - length);
  786. CopyElements(Buffer() + pos, &(*start), length);
  787. return Begin() + pos;
  788. }
  789. /// Insert elements.
  790. Iterator Insert(const Iterator& dest, const T* start, const T* end)
  791. {
  792. auto pos = (unsigned)(dest - Begin());
  793. if (pos > size_)
  794. pos = size_;
  795. auto length = (unsigned)(end - start);
  796. Resize(size_ + length);
  797. MoveRange(pos + length, pos, size_ - pos - length);
  798. T* destPtr = Buffer() + pos;
  799. for (const T* i = start; i != end; ++i)
  800. *destPtr++ = *i;
  801. return Begin() + pos;
  802. }
  803. /// Erase a range of elements.
  804. void Erase(unsigned pos, unsigned length = 1)
  805. {
  806. // Return if the range is illegal
  807. if (!length || pos + length > size_)
  808. return;
  809. MoveRange(pos, pos + length, size_ - pos - length);
  810. Resize(size_ - length);
  811. }
  812. /// Erase an element by iterator. Return iterator to the next element.
  813. Iterator Erase(const Iterator& it)
  814. {
  815. auto pos = (unsigned)(it - Begin());
  816. if (pos >= size_)
  817. return End();
  818. Erase(pos);
  819. return Begin() + pos;
  820. }
  821. /// Erase a range by iterators. Return iterator to the next element.
  822. Iterator Erase(const Iterator& start, const Iterator& end)
  823. {
  824. auto pos = (unsigned)(start - Begin());
  825. if (pos >= size_)
  826. return End();
  827. auto length = (unsigned)(end - start);
  828. Erase(pos, length);
  829. return Begin() + pos;
  830. }
  831. /// Erase a range of elements by swapping elements from the end of the array.
  832. void EraseSwap(unsigned pos, unsigned length = 1)
  833. {
  834. unsigned shiftStartIndex = pos + length;
  835. // Return if the range is illegal
  836. if (shiftStartIndex > size_ || !length)
  837. return;
  838. unsigned newSize = size_ - length;
  839. unsigned trailingCount = size_ - shiftStartIndex;
  840. if (trailingCount <= length)
  841. {
  842. // We're removing more elements from the array than exist past the end of the range being removed, so perform a normal shift and destroy
  843. MoveRange(pos, shiftStartIndex, trailingCount);
  844. }
  845. else
  846. {
  847. // Swap elements from the end of the array into the empty space
  848. CopyElements(Buffer() + pos, Buffer() + newSize, length);
  849. }
  850. Resize(newSize);
  851. }
  852. /// Erase an element by value. Return true if was found and erased.
  853. bool Remove(const T& value)
  854. {
  855. Iterator i = Find(value);
  856. if (i != End())
  857. {
  858. Erase(i);
  859. return true;
  860. }
  861. else
  862. return false;
  863. }
  864. /// Erase an element by value by swapping with the last element. Return true if was found and erased.
  865. bool RemoveSwap(const T& value)
  866. {
  867. Iterator i = Find(value);
  868. if (i != End())
  869. {
  870. EraseSwap(i - Begin());
  871. return true;
  872. }
  873. else
  874. return false;
  875. }
  876. /// Clear the vector.
  877. void Clear() { Resize(0); }
  878. /// Resize the vector.
  879. void Resize(unsigned newSize)
  880. {
  881. if (newSize > capacity_)
  882. {
  883. if (!capacity_)
  884. capacity_ = newSize;
  885. else
  886. {
  887. while (capacity_ < newSize)
  888. capacity_ += (capacity_ + 1) >> 1;
  889. }
  890. unsigned char* newBuffer = AllocateBuffer((unsigned)(capacity_ * sizeof(T)));
  891. // Move the data into the new buffer and delete the old
  892. if (buffer_)
  893. {
  894. CopyElements(reinterpret_cast<T*>(newBuffer), Buffer(), size_);
  895. delete[] buffer_;
  896. }
  897. buffer_ = newBuffer;
  898. }
  899. size_ = newSize;
  900. }
  901. /// Set new capacity.
  902. void Reserve(unsigned newCapacity)
  903. {
  904. if (newCapacity < size_)
  905. newCapacity = size_;
  906. if (newCapacity != capacity_)
  907. {
  908. unsigned char* newBuffer = nullptr;
  909. capacity_ = newCapacity;
  910. if (capacity_)
  911. {
  912. newBuffer = AllocateBuffer((unsigned)(capacity_ * sizeof(T)));
  913. // Move the data into the new buffer
  914. CopyElements(reinterpret_cast<T*>(newBuffer), Buffer(), size_);
  915. }
  916. // Delete the old buffer
  917. delete[] buffer_;
  918. buffer_ = newBuffer;
  919. }
  920. }
  921. /// Reallocate so that no extra memory is used.
  922. void Compact() { Reserve(size_); }
  923. /// Return iterator to value, or to the end if not found.
  924. Iterator Find(const T& value)
  925. {
  926. Iterator it = Begin();
  927. while (it != End() && *it != value)
  928. ++it;
  929. return it;
  930. }
  931. /// Return const iterator to value, or to the end if not found.
  932. ConstIterator Find(const T& value) const
  933. {
  934. ConstIterator it = Begin();
  935. while (it != End() && *it != value)
  936. ++it;
  937. return it;
  938. }
  939. /// Return index of value in vector, or size if not found.
  940. unsigned IndexOf(const T& value) const
  941. {
  942. return Find(value) - Begin();
  943. }
  944. /// Return whether contains a specific value.
  945. bool Contains(const T& value) const { return Find(value) != End(); }
  946. /// Return iterator to the beginning.
  947. Iterator Begin() { return Iterator(Buffer()); }
  948. /// Return const iterator to the beginning.
  949. ConstIterator Begin() const { return ConstIterator(Buffer()); }
  950. /// Return iterator to the end.
  951. Iterator End() { return Iterator(Buffer() + size_); }
  952. /// Return const iterator to the end.
  953. ConstIterator End() const { return ConstIterator(Buffer() + size_); }
  954. /// Return first element.
  955. T& Front() { return Buffer()[0]; }
  956. /// Return const first element.
  957. const T& Front() const { return Buffer()[0]; }
  958. /// Return last element.
  959. T& Back()
  960. {
  961. assert(size_);
  962. return Buffer()[size_ - 1];
  963. }
  964. /// Return const last element.
  965. const T& Back() const
  966. {
  967. assert(size_);
  968. return Buffer()[size_ - 1];
  969. }
  970. /// Return number of elements.
  971. unsigned Size() const { return size_; }
  972. /// Return capacity of vector.
  973. unsigned Capacity() const { return capacity_; }
  974. /// Return whether vector is empty.
  975. bool Empty() const { return size_ == 0; }
  976. /// Return the buffer with right type.
  977. T* Buffer() const { return reinterpret_cast<T*>(buffer_); }
  978. private:
  979. /// Move a range of elements within the vector.
  980. void MoveRange(unsigned dest, unsigned src, unsigned count)
  981. {
  982. if (count)
  983. memmove(Buffer() + dest, Buffer() + src, count * sizeof(T));
  984. }
  985. /// Copy elements from one buffer to another.
  986. static void CopyElements(T* dest, const T* src, unsigned count)
  987. {
  988. if (count)
  989. memcpy(dest, src, count * sizeof(T));
  990. }
  991. };
  992. template <class T> typename Urho3D::Vector<T>::ConstIterator begin(const Urho3D::Vector<T>& v) { return v.Begin(); }
  993. template <class T> typename Urho3D::Vector<T>::ConstIterator end(const Urho3D::Vector<T>& v) { return v.End(); }
  994. template <class T> typename Urho3D::Vector<T>::Iterator begin(Urho3D::Vector<T>& v) { return v.Begin(); }
  995. template <class T> typename Urho3D::Vector<T>::Iterator end(Urho3D::Vector<T>& v) { return v.End(); }
  996. template <class T> typename Urho3D::PODVector<T>::ConstIterator begin(const Urho3D::PODVector<T>& v) { return v.Begin(); }
  997. template <class T> typename Urho3D::PODVector<T>::ConstIterator end(const Urho3D::PODVector<T>& v) { return v.End(); }
  998. template <class T> typename Urho3D::PODVector<T>::Iterator begin(Urho3D::PODVector<T>& v) { return v.Begin(); }
  999. template <class T> typename Urho3D::PODVector<T>::Iterator end(Urho3D::PODVector<T>& v) { return v.End(); }
  1000. }
  1001. #ifdef _MSC_VER
  1002. #pragma warning(pop)
  1003. #endif