123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- #pragma once
- #include <util/generic/array_ref.h>
- #include <util/generic/noncopyable.h>
- #include <util/generic/utility.h>
- #include <util/system/yassert.h>
- #include <stdlib.h>
- template <typename T, class A = std::allocator<T>>
- class TVectorSwaps : TNonCopyable {
- private:
- T* Start;
- T* Finish;
- T* EndOfStorage;
- void StateCheck() {
- Y_ASSERT(Start <= Finish);
- Y_ASSERT(Finish <= EndOfStorage);
- }
- public:
- typedef T* iterator;
- typedef const T* const_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- TVectorSwaps()
- : Start()
- , Finish()
- , EndOfStorage()
- {
- }
- ~TVectorSwaps() {
- for (size_t i = 0; i < size(); ++i) {
- Start[i].~T();
- }
- free(Start);
- }
- operator TArrayRef<const T>() const {
- return MakeArrayRef(data(), size());
- }
- operator TArrayRef<T>() {
- return MakeArrayRef(data(), size());
- }
- size_t capacity() const {
- return EndOfStorage - Start;
- }
- size_t size() const {
- return Finish - Start;
- }
- bool empty() const {
- return size() == 0;
- }
- T* data() {
- return Start;
- }
- const T* data() const {
- return Start;
- }
- T& operator[](size_t index) {
- Y_ASSERT(index < size());
- return Start[index];
- }
- const T& operator[](size_t index) const {
- Y_ASSERT(index < size());
- return Start[index];
- }
- iterator begin() {
- return Start;
- }
- iterator end() {
- return Finish;
- }
- const_iterator begin() const {
- return Start;
- }
- const_iterator end() const {
- return Finish;
- }
- reverse_iterator rbegin() {
- return reverse_iterator(end());
- }
- reverse_iterator rend() {
- return reverse_iterator(begin());
- }
- const_reverse_iterator rbegin() const {
- return reverse_iterator(end());
- }
- const_reverse_iterator rend() const {
- return reverse_iterator(begin());
- }
- void swap(TVectorSwaps<T>& that) {
- DoSwap(Start, that.Start);
- DoSwap(Finish, that.Finish);
- DoSwap(EndOfStorage, that.EndOfStorage);
- }
- void reserve(size_t n) {
- if (n <= capacity()) {
- return;
- }
- size_t newCapacity = FastClp2(n);
- TVectorSwaps<T> tmp;
- tmp.Start = (T*)malloc(sizeof(T) * newCapacity);
- Y_ABORT_UNLESS(!!tmp.Start);
- tmp.EndOfStorage = tmp.Start + newCapacity;
- for (size_t i = 0; i < size(); ++i) {
- // TODO: catch exceptions
- new (tmp.Start + i) T();
- DoSwap(Start[i], tmp.Start[i]);
- }
- tmp.Finish = tmp.Start + size();
- swap(tmp);
- StateCheck();
- }
- void clear() {
- TVectorSwaps<T> tmp;
- swap(tmp);
- }
- template <class TIterator>
- void insert(iterator pos, TIterator b, TIterator e) {
- Y_ABORT_UNLESS(pos == end(), "TODO: only insert at the end is implemented");
- size_t count = e - b;
- reserve(size() + count);
- TIterator next = b;
- for (size_t i = 0; i < count; ++i) {
- new (Start + size() + i) T();
- DoSwap(Start[size() + i], *next);
- ++next;
- }
- Finish += count;
- StateCheck();
- }
- void push_back(T& elem) {
- insert(end(), &elem, &elem + 1);
- }
- };
|