Vector.h 29 KB

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