Vector.h 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
  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. 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. // Obtain the size before resizing, in case the other vector is another reference to this vector
  730. unsigned thisSize = size_;
  731. unsigned vectorSize = vector.size_;
  732. Resize(thisSize + vectorSize);
  733. CopyElements(Buffer() + thisSize, vector.Buffer(), vectorSize);
  734. }
  735. /// Remove the last element.
  736. void Pop()
  737. {
  738. if (size_)
  739. Resize(size_ - 1);
  740. }
  741. /// Insert an element at position.
  742. void Insert(unsigned pos, const T& value)
  743. {
  744. if (pos > size_)
  745. pos = size_;
  746. unsigned oldSize = size_;
  747. Resize(size_ + 1);
  748. MoveRange(pos + 1, pos, oldSize - pos);
  749. Buffer()[pos] = value;
  750. }
  751. /// Insert another vector at position.
  752. void Insert(unsigned pos, const PODVector<T>& vector)
  753. {
  754. if (pos > size_)
  755. pos = size_;
  756. unsigned oldSize = size_;
  757. Resize(size_ + vector.size_);
  758. MoveRange(pos + vector.size_, pos, oldSize - pos);
  759. CopyElements(Buffer() + pos, vector.Buffer(), vector.size_);
  760. }
  761. /// Insert an element by iterator.
  762. Iterator Insert(const Iterator& dest, const T& value)
  763. {
  764. auto pos = (unsigned)(dest - Begin());
  765. if (pos > size_)
  766. pos = size_;
  767. Insert(pos, value);
  768. return Begin() + pos;
  769. }
  770. /// Insert a vector by iterator.
  771. Iterator Insert(const Iterator& dest, const PODVector<T>& vector)
  772. {
  773. auto pos = (unsigned)(dest - Begin());
  774. if (pos > size_)
  775. pos = size_;
  776. Insert(pos, vector);
  777. return Begin() + pos;
  778. }
  779. /// Insert a vector partially by iterators.
  780. Iterator Insert(const Iterator& dest, const ConstIterator& start, const ConstIterator& end)
  781. {
  782. auto pos = (unsigned)(dest - Begin());
  783. if (pos > size_)
  784. pos = size_;
  785. auto length = (unsigned)(end - start);
  786. Resize(size_ + length);
  787. MoveRange(pos + length, pos, size_ - pos - length);
  788. CopyElements(Buffer() + pos, &(*start), length);
  789. return Begin() + pos;
  790. }
  791. /// Insert elements.
  792. Iterator Insert(const Iterator& dest, const T* start, const T* end)
  793. {
  794. auto pos = (unsigned)(dest - Begin());
  795. if (pos > size_)
  796. pos = size_;
  797. auto length = (unsigned)(end - start);
  798. Resize(size_ + length);
  799. MoveRange(pos + length, pos, size_ - pos - length);
  800. T* destPtr = Buffer() + pos;
  801. for (const T* i = start; i != end; ++i)
  802. *destPtr++ = *i;
  803. return Begin() + pos;
  804. }
  805. /// Erase a range of elements.
  806. void Erase(unsigned pos, unsigned length = 1)
  807. {
  808. // Return if the range is illegal
  809. if (!length || pos + length > size_)
  810. return;
  811. MoveRange(pos, pos + length, size_ - pos - length);
  812. Resize(size_ - length);
  813. }
  814. /// Erase an element by iterator. Return iterator to the next element.
  815. Iterator Erase(const Iterator& it)
  816. {
  817. auto pos = (unsigned)(it - Begin());
  818. if (pos >= size_)
  819. return End();
  820. Erase(pos);
  821. return Begin() + pos;
  822. }
  823. /// Erase a range by iterators. Return iterator to the next element.
  824. Iterator Erase(const Iterator& start, const Iterator& end)
  825. {
  826. auto pos = (unsigned)(start - Begin());
  827. if (pos >= size_)
  828. return End();
  829. auto length = (unsigned)(end - start);
  830. Erase(pos, length);
  831. return Begin() + pos;
  832. }
  833. /// Erase a range of elements by swapping elements from the end of the array.
  834. void EraseSwap(unsigned pos, unsigned length = 1)
  835. {
  836. unsigned shiftStartIndex = pos + length;
  837. // Return if the range is illegal
  838. if (shiftStartIndex > size_ || !length)
  839. return;
  840. unsigned newSize = size_ - length;
  841. unsigned trailingCount = size_ - shiftStartIndex;
  842. if (trailingCount <= length)
  843. {
  844. // 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
  845. MoveRange(pos, shiftStartIndex, trailingCount);
  846. }
  847. else
  848. {
  849. // Swap elements from the end of the array into the empty space
  850. CopyElements(Buffer() + pos, Buffer() + newSize, length);
  851. }
  852. Resize(newSize);
  853. }
  854. /// Erase an element by value. Return true if was found and erased.
  855. bool Remove(const T& value)
  856. {
  857. Iterator i = Find(value);
  858. if (i != End())
  859. {
  860. Erase(i);
  861. return true;
  862. }
  863. else
  864. return false;
  865. }
  866. /// Erase an element by value by swapping with the last element. Return true if was found and erased.
  867. bool RemoveSwap(const T& value)
  868. {
  869. Iterator i = Find(value);
  870. if (i != End())
  871. {
  872. EraseSwap(i - Begin());
  873. return true;
  874. }
  875. else
  876. return false;
  877. }
  878. /// Clear the vector.
  879. void Clear() { Resize(0); }
  880. /// Resize the vector.
  881. void Resize(unsigned newSize)
  882. {
  883. if (newSize > capacity_)
  884. {
  885. if (!capacity_)
  886. capacity_ = newSize;
  887. else
  888. {
  889. while (capacity_ < newSize)
  890. capacity_ += (capacity_ + 1) >> 1;
  891. }
  892. unsigned char* newBuffer = AllocateBuffer((unsigned)(capacity_ * sizeof(T)));
  893. // Move the data into the new buffer and delete the old
  894. if (buffer_)
  895. {
  896. CopyElements(reinterpret_cast<T*>(newBuffer), Buffer(), size_);
  897. delete[] buffer_;
  898. }
  899. buffer_ = newBuffer;
  900. }
  901. size_ = newSize;
  902. }
  903. /// Set new capacity.
  904. void Reserve(unsigned newCapacity)
  905. {
  906. if (newCapacity < size_)
  907. newCapacity = size_;
  908. if (newCapacity != capacity_)
  909. {
  910. unsigned char* newBuffer = nullptr;
  911. capacity_ = newCapacity;
  912. if (capacity_)
  913. {
  914. newBuffer = AllocateBuffer((unsigned)(capacity_ * sizeof(T)));
  915. // Move the data into the new buffer
  916. CopyElements(reinterpret_cast<T*>(newBuffer), Buffer(), size_);
  917. }
  918. // Delete the old buffer
  919. delete[] buffer_;
  920. buffer_ = newBuffer;
  921. }
  922. }
  923. /// Reallocate so that no extra memory is used.
  924. void Compact() { Reserve(size_); }
  925. /// Return iterator to value, or to the end if not found.
  926. Iterator Find(const T& value)
  927. {
  928. Iterator it = Begin();
  929. while (it != End() && *it != value)
  930. ++it;
  931. return it;
  932. }
  933. /// Return const iterator to value, or to the end if not found.
  934. ConstIterator Find(const T& value) const
  935. {
  936. ConstIterator it = Begin();
  937. while (it != End() && *it != value)
  938. ++it;
  939. return it;
  940. }
  941. /// Return index of value in vector, or size if not found.
  942. unsigned IndexOf(const T& value) const
  943. {
  944. return Find(value) - Begin();
  945. }
  946. /// Return whether contains a specific value.
  947. bool Contains(const T& value) const { return Find(value) != End(); }
  948. /// Return iterator to the beginning.
  949. Iterator Begin() { return Iterator(Buffer()); }
  950. /// Return const iterator to the beginning.
  951. ConstIterator Begin() const { return ConstIterator(Buffer()); }
  952. /// Return iterator to the end.
  953. Iterator End() { return Iterator(Buffer() + size_); }
  954. /// Return const iterator to the end.
  955. ConstIterator End() const { return ConstIterator(Buffer() + size_); }
  956. /// Return first element.
  957. T& Front() { return Buffer()[0]; }
  958. /// Return const first element.
  959. const T& Front() const { return Buffer()[0]; }
  960. /// Return last element.
  961. T& Back()
  962. {
  963. assert(size_);
  964. return Buffer()[size_ - 1];
  965. }
  966. /// Return const last element.
  967. const T& Back() const
  968. {
  969. assert(size_);
  970. return Buffer()[size_ - 1];
  971. }
  972. /// Return number of elements.
  973. unsigned Size() const { return size_; }
  974. /// Return capacity of vector.
  975. unsigned Capacity() const { return capacity_; }
  976. /// Return whether vector is empty.
  977. bool Empty() const { return size_ == 0; }
  978. /// Return the buffer with right type.
  979. T* Buffer() const { return reinterpret_cast<T*>(buffer_); }
  980. private:
  981. /// Move a range of elements within the vector.
  982. void MoveRange(unsigned dest, unsigned src, unsigned count)
  983. {
  984. if (count)
  985. memmove(Buffer() + dest, Buffer() + src, count * sizeof(T));
  986. }
  987. /// Copy elements from one buffer to another.
  988. static void CopyElements(T* dest, const T* src, unsigned count)
  989. {
  990. if (count)
  991. memcpy(dest, src, count * sizeof(T));
  992. }
  993. };
  994. template <class T> typename Urho3D::Vector<T>::ConstIterator begin(const Urho3D::Vector<T>& v) { return v.Begin(); }
  995. template <class T> typename Urho3D::Vector<T>::ConstIterator end(const Urho3D::Vector<T>& v) { return v.End(); }
  996. template <class T> typename Urho3D::Vector<T>::Iterator begin(Urho3D::Vector<T>& v) { return v.Begin(); }
  997. template <class T> typename Urho3D::Vector<T>::Iterator end(Urho3D::Vector<T>& v) { return v.End(); }
  998. template <class T> typename Urho3D::PODVector<T>::ConstIterator begin(const Urho3D::PODVector<T>& v) { return v.Begin(); }
  999. template <class T> typename Urho3D::PODVector<T>::ConstIterator end(const Urho3D::PODVector<T>& v) { return v.End(); }
  1000. template <class T> typename Urho3D::PODVector<T>::Iterator begin(Urho3D::PODVector<T>& v) { return v.Begin(); }
  1001. template <class T> typename Urho3D::PODVector<T>::Iterator end(Urho3D::PODVector<T>& v) { return v.End(); }
  1002. }
  1003. #ifdef _MSC_VER
  1004. #pragma warning(pop)
  1005. #endif