Vector.h 33 KB

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