Vector.h 30 KB

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