vector_swaps.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #pragma once
  2. #include <util/generic/array_ref.h>
  3. #include <util/generic/noncopyable.h>
  4. #include <util/generic/utility.h>
  5. #include <util/system/yassert.h>
  6. #include <stdlib.h>
  7. template <typename T, class A = std::allocator<T>>
  8. class TVectorSwaps : TNonCopyable {
  9. private:
  10. T* Start;
  11. T* Finish;
  12. T* EndOfStorage;
  13. void StateCheck() {
  14. Y_ASSERT(Start <= Finish);
  15. Y_ASSERT(Finish <= EndOfStorage);
  16. }
  17. public:
  18. typedef T* iterator;
  19. typedef const T* const_iterator;
  20. typedef std::reverse_iterator<iterator> reverse_iterator;
  21. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  22. TVectorSwaps()
  23. : Start()
  24. , Finish()
  25. , EndOfStorage()
  26. {
  27. }
  28. ~TVectorSwaps() {
  29. for (size_t i = 0; i < size(); ++i) {
  30. Start[i].~T();
  31. }
  32. free(Start);
  33. }
  34. operator TArrayRef<const T>() const {
  35. return MakeArrayRef(data(), size());
  36. }
  37. operator TArrayRef<T>() {
  38. return MakeArrayRef(data(), size());
  39. }
  40. size_t capacity() const {
  41. return EndOfStorage - Start;
  42. }
  43. size_t size() const {
  44. return Finish - Start;
  45. }
  46. bool empty() const {
  47. return size() == 0;
  48. }
  49. T* data() {
  50. return Start;
  51. }
  52. const T* data() const {
  53. return Start;
  54. }
  55. T& operator[](size_t index) {
  56. Y_ASSERT(index < size());
  57. return Start[index];
  58. }
  59. const T& operator[](size_t index) const {
  60. Y_ASSERT(index < size());
  61. return Start[index];
  62. }
  63. iterator begin() {
  64. return Start;
  65. }
  66. iterator end() {
  67. return Finish;
  68. }
  69. const_iterator begin() const {
  70. return Start;
  71. }
  72. const_iterator end() const {
  73. return Finish;
  74. }
  75. reverse_iterator rbegin() {
  76. return reverse_iterator(end());
  77. }
  78. reverse_iterator rend() {
  79. return reverse_iterator(begin());
  80. }
  81. const_reverse_iterator rbegin() const {
  82. return reverse_iterator(end());
  83. }
  84. const_reverse_iterator rend() const {
  85. return reverse_iterator(begin());
  86. }
  87. void swap(TVectorSwaps<T>& that) {
  88. DoSwap(Start, that.Start);
  89. DoSwap(Finish, that.Finish);
  90. DoSwap(EndOfStorage, that.EndOfStorage);
  91. }
  92. void reserve(size_t n) {
  93. if (n <= capacity()) {
  94. return;
  95. }
  96. size_t newCapacity = FastClp2(n);
  97. TVectorSwaps<T> tmp;
  98. tmp.Start = (T*)malloc(sizeof(T) * newCapacity);
  99. Y_ABORT_UNLESS(!!tmp.Start);
  100. tmp.EndOfStorage = tmp.Start + newCapacity;
  101. for (size_t i = 0; i < size(); ++i) {
  102. // TODO: catch exceptions
  103. new (tmp.Start + i) T();
  104. DoSwap(Start[i], tmp.Start[i]);
  105. }
  106. tmp.Finish = tmp.Start + size();
  107. swap(tmp);
  108. StateCheck();
  109. }
  110. void clear() {
  111. TVectorSwaps<T> tmp;
  112. swap(tmp);
  113. }
  114. template <class TIterator>
  115. void insert(iterator pos, TIterator b, TIterator e) {
  116. Y_ABORT_UNLESS(pos == end(), "TODO: only insert at the end is implemented");
  117. size_t count = e - b;
  118. reserve(size() + count);
  119. TIterator next = b;
  120. for (size_t i = 0; i < count; ++i) {
  121. new (Start + size() + i) T();
  122. DoSwap(Start[size() + i], *next);
  123. ++next;
  124. }
  125. Finish += count;
  126. StateCheck();
  127. }
  128. void push_back(T& elem) {
  129. insert(end(), &elem, &elem + 1);
  130. }
  131. };