Advertisement
Guest User

Untitled

a guest
Mar 28th, 2020
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.61 KB | None | 0 0
  1. #ifndef _VECTOR_
  2. #define _VECTOR_
  3. #include<cmath>
  4. using u16 = unsigned int;
  5. template<class T>
  6. void swap(T&a,T&b){
  7.     T c(std::move(a));
  8.     a = std::move(b);
  9.     b = std::move(c);
  10. }
  11. template<class T, size_t N>
  12. void swap(T(&a)[N], T(&b)[N]) {
  13.     for (size_t i = 0; i < N; ++i)
  14.     {
  15.         swap(a[i], b[i]);
  16.     }
  17. }
  18. template<class T>
  19. struct ItemWrapper {
  20.     T* data() { return reinterpret_cast<T*>(buffer); }
  21.     const T* data()const { return reinterpret_cast<const T*>(buffer); }
  22. private:
  23.     char buffer[sizeof(T)];
  24. };
  25. template<class T>
  26. class Vector {
  27.     ItemWrapper<T>* memory;
  28.     u16 length;
  29.     u16 allocated;
  30.     void check_index(const u16 index) const {
  31.         if (length == 0) {
  32.             std::cerr << "Error: cannot erase/insert at position different than 0/get/set when there are no elements\n"; std::exit(1);
  33.         }
  34.         if (index > length - 1)
  35.         {
  36.             std::cerr << "Error: invalid index, index should be less than the number of elements!\n"; std::exit(1);
  37.         }
  38.     }
  39.     void move_right_by_one(const u16 index) {
  40.         if (length >= allocated) {
  41.             this->reserve(allocated * 2);
  42.         }
  43.         length++;
  44.         for (u16 itr = index; itr < length - 1; ++itr) {
  45.             const auto src = memory[itr].data();
  46.             const auto dst = memory[itr + 1].data();
  47.             new(reinterpret_cast<void*>(dst))T(std::move(*src));
  48.         }
  49.     }
  50. public:
  51.     Vector() :length(0), allocated(0) {
  52.         this->reserve(1);
  53.     }
  54.     Vector(const u16 new_capacity) :length(0), allocated(0) {
  55.         float power = log2(new_capacity);
  56.         if (int(power) != power)
  57.             power++;
  58.         this->reserve(pow(2, power));
  59.     }
  60.     ~Vector() {
  61.         delete[]memory;
  62.         length = 0;
  63.         allocated = 0;
  64.         memory = nullptr;
  65.     }
  66.     T* begin() { return memory->data(); }
  67.     int count() const{ return length; }
  68.     T* end() { return (memory + length)->data(); }
  69.     T back() {
  70.         if (length > 0)
  71.             return (*this)[length - 1];
  72.         else return T();
  73.     }
  74.     T front() {
  75.         if (length > 0)
  76.             return (*this)[0];
  77.         else return T();
  78.     }
  79.     //Vector<T>& operator=(const Vector<T>&object) {}
  80.     //Vector(const Vector<T>& object){}
  81.     bool empty()const {
  82.         return (length == 0);
  83.     }
  84.     u16 capacity()const {
  85.         return allocated;
  86.     }
  87.     void pop_back() {
  88.         if (length == 0)return;
  89.         const auto last_element = memory[--length].data();
  90.         last_element->~T();
  91.         if (2 * length == allocated) {
  92.             allocated /= 2;
  93.             this->reserve(allocated);
  94.         }
  95.     }
  96.     //copy construct new item
  97.     void push_back(const T& value) {
  98.         if (length >= allocated) { //in case big bad voodoo
  99.             this->reserve(allocated * 2);
  100.         }
  101.         const auto dst = memory[length++].data();
  102.         new(reinterpret_cast<void*>(dst))T(value);
  103.     }
  104.     //move construct new item
  105.     void push_back(const T&& value) {
  106.         if (length >= allocated) { //in case big bad voodoo
  107.             this->reserve(allocated * 2);
  108.         }
  109.         const auto dst = memory[length++].data();
  110.         new(reinterpret_cast<void*>(dst))T(std::move(value));
  111.     }
  112.     void reserve(const u16 newCapacity) {
  113.         if (newCapacity <= allocated)return;//the call to reserve is redundant
  114.         const auto old_memory = memory;
  115.         memory = new ItemWrapper<T>[newCapacity]; //allocation of memory
  116.         allocated = newCapacity; //assign allocated
  117.         for (u16 index = 0; index < length; ++index) {
  118.             const auto src = old_memory[index].data();
  119.             const auto dst = memory[index].data();
  120.             new(reinterpret_cast<void*>(dst))T(std::move(*src)); //force move constructor
  121.             src->~T(); //being sure the the old data is manually destroyed
  122.         }
  123.         if (old_memory) delete[]old_memory; // deallocating the old memory;
  124.     }
  125.     void clear() {
  126.         if (length > 0) {
  127.             delete[]memory;
  128.             length = 0;
  129.             allocated = 0;
  130.             this->reserve(1);
  131.         }
  132.     }
  133.     void insert(const u16 index, const T& value) {
  134.         if (index == 0 && length == 0) {
  135.             (*this)->push_back(value);
  136.         }
  137.         check_index(index);
  138.         move_right_by_one(index);
  139.         const auto dst = memory[index].data();
  140.         new(reinterpret_cast<void*>(dst))T(value);
  141.     }
  142.     void insert(const u16 index, const T&& value) {
  143.         if (index == 0 && length == 0) {
  144.             (*this)->push_back(value);
  145.         }
  146.         check_index(index);
  147.         move_right_by_one(index);
  148.         const auto dst = memory[index].data();
  149.         new(reinterpret_cast<void*>(dst))T(std::move(value));
  150.     }
  151.     void erase(const u16 index) {
  152.         check_index(index);
  153.         for (u16 itr = index; itr < length - 1; ++itr) {
  154.             const auto dst = memory[itr].data();
  155.             const auto src = memory[itr + 1].data();
  156.             new(reinterpret_cast<void*>(dst))T(std::move(*src));
  157.         }
  158.         this->pop_back();
  159.     }
  160.     void erase(const u16 start_point, const u16 end_point) {
  161.         check_index(start_point);
  162.         check_index(end_point);
  163.         if (start_point > end_point) {
  164.             std::cerr << "start_point must be lower or equal to end_point!";
  165.             std::exit(1);
  166.         }
  167.         if (start_point == end_point) {
  168.             this->erase(start_point);
  169.         }
  170.         const u16 step = end_point - start_point;
  171.         for (u16 itr = start_point; itr < length - step; ++itr) {
  172.             const auto dst = memory[itr].data();
  173.             const auto src = memory[itr + step].data();
  174.             new(reinterpret_cast<void*>(dst))T(std::move(*src));
  175.         }
  176.         for (u16 itr = 0; itr < step; ++itr) {
  177.             this->pop_back();
  178.         }
  179.     }
  180.     T& get(const u16 index) {
  181.         check_index(index);
  182.         return (*this)[index];
  183.     }
  184.     const T& get(const u16 index)const {
  185.         check_index(index);
  186.         return (*this)[index];
  187.     }
  188.     void set(const u16 index, const T& value) {
  189.         check_index(index);
  190.         const auto dst = memory[index].data();
  191.         new(reinterpret_cast<void*>(dst))T(value);
  192.     }
  193.     void set(const u16 index, const T&& value) {
  194.         check_index(index);
  195.         const auto dst = memory[index].data();
  196.         new(reinterpret_cast<void*>(dst))T(std::move(value));
  197.     }
  198.     T& operator[](const u16 index) {
  199.         check_index(index);
  200.         return *((memory + index)->data());
  201.     }
  202.     const T& operator[](const u16 index)const {
  203.         check_index(index);
  204.         return *((memory + index)->data());
  205.     }
  206.     template<class MYCALLBACK>
  207.     void sort(MYCALLBACK callback=nullptr) {
  208.         for (u16 i = 0; i < length - 1; ++i) {
  209.             for (u16 j = i+1; j < length; ++j) {
  210.                 if (callback != nullptr) {
  211.                     if (callback(this->get(i), this->get(j))) {
  212.                     swap(memory[i], memory[j]);
  213.                     }
  214.                 }
  215.                 else {
  216.                     if (this->get(i) > this->get(j)) {
  217.                         swap(memory[i], memory[j]);
  218.                     }
  219.                 }
  220.             }
  221.         }
  222.     }
  223.     void sort() {
  224.         typedef bool (*empty)(const T&, const T&);
  225.         //sort<bool(*)(const T&, const T&);
  226.         sort <empty> (nullptr);
  227.     }
  228.     template<class MYCALLBACK>
  229.     int firstIndexOf(const T& object2,MYCALLBACK callback = nullptr) {
  230.         for (u16 i = 0; i < length; ++i) {
  231.             if (callback != nullptr) {
  232.                 if (callback(this->get(i), object2)) {
  233.                     return i;
  234.                 }
  235.             }
  236.             else {
  237.                 if (this->get(i) == object2) {
  238.                     return i;
  239.                 }
  240.             }
  241.         }
  242.         return -1;
  243.     }
  244.     int firstIndexOf() {
  245.         typedef bool (*empty)(const T&, const T&);
  246.         firstIndexOf<empty>(nullptr);
  247.     }
  248. };
  249. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement