Advertisement
Guest User

Untitled

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