TrickmanOff

Vector

Oct 16th, 2020 (edited)
2,110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.89 KB | None | 0 0
  1. #include <cstddef>
  2. #include <memory>
  3. #include <utility>
  4.  
  5. template <typename T>
  6. class RawMemory {
  7. public:
  8.     T* buf = nullptr;
  9.     size_t cp = 0;
  10.  
  11.     static T* Allocate(size_t n) {
  12.         return static_cast<T*>((operator new(sizeof(T) * n)));
  13.     }
  14.  
  15.     static void Deallocate(T* buf) {
  16.         operator delete(buf);
  17.     }
  18.  
  19.     RawMemory() = default;
  20.  
  21.     RawMemory(size_t n) {
  22.         buf = Allocate(n);
  23.         cp = n;
  24.     }
  25.  
  26.     RawMemory(const RawMemory&) = delete;
  27.  
  28.     RawMemory(RawMemory&& other) noexcept {
  29.         Swap(other);
  30.     }
  31.  
  32.     RawMemory& operator=(const RawMemory&) = delete;
  33.  
  34.     RawMemory& operator=(RawMemory&& other) noexcept {
  35.         Swap(other);
  36.         return *this;
  37.     }
  38.  
  39.     ~RawMemory() {
  40.         Deallocate(buf);
  41.     }
  42.  
  43.     void Swap(RawMemory<T>& other) noexcept {
  44.         std::swap(buf, other.buf);
  45.         std::swap(cp, other.cp);
  46.     }
  47.  
  48.     T& operator[](const size_t index) {
  49.         return buf[index];
  50.     }
  51.  
  52.     const T& operator[](const size_t index) const {
  53.         return buf[index];
  54.     }
  55.  
  56.     T* operator+(size_t add) {
  57.         return buf + add;
  58.     }
  59.  
  60.     const T* operator+(size_t add) const {
  61.         return buf + add;
  62.     }
  63. };
  64.  
  65. template <typename T>
  66. class Vector {
  67. private:
  68.     RawMemory<T> data;
  69.     size_t sz = 0;
  70.  
  71. public:
  72.     Vector() = default;
  73.     Vector(size_t);
  74.     Vector(const Vector&);
  75.     Vector(Vector&&) noexcept;
  76.  
  77.     ~Vector();
  78.  
  79.     Vector& operator=(const Vector&);
  80.     Vector& operator=(Vector&&) noexcept;
  81.  
  82.     T& operator[](size_t index);
  83.     const T& operator[](size_t index) const;
  84.  
  85.     void Reserve(size_t);
  86.     void Resize(size_t);
  87.  
  88.     void PushBack(const T&);
  89.     void PushBack(T&&);
  90.  
  91.     void PopBack();
  92.  
  93.     void Clear();
  94.  
  95.     void Swap(Vector&) noexcept;
  96.  
  97.     size_t Size() const noexcept ;
  98.     size_t Capacity() const noexcept;
  99.  
  100.     template <typename ... Args>
  101.     T& EmplaceBack(Args&& ...);
  102. };
  103.  
  104. template<typename T>
  105. Vector<T>::Vector(size_t n): data(n) {
  106.     std::uninitialized_default_construct_n(data.buf, n);
  107.     sz = n;
  108. }
  109.  
  110. template<typename T>
  111. Vector<T>::Vector(const Vector& other): data(other.sz) {
  112.     std::uninitialized_copy_n(other.data.buf, other.sz, data.buf);
  113.     sz = other.sz;
  114. }
  115.  
  116. template<typename T>
  117. Vector<T>::Vector(Vector&& other) noexcept {
  118.     Swap(other);
  119. }
  120.  
  121.  
  122. template <typename T>
  123. Vector<T>::~Vector<T>() {
  124.     std::destroy_n(data.buf, sz);
  125. }
  126.  
  127. template<typename T>
  128. Vector<T>& Vector<T>::operator=(const Vector& other) {
  129.     if (other.sz > data.cp) {
  130.         Vector tmp(other);
  131.         Swap(tmp);
  132.     } else {
  133.         for (size_t i = 0; i < std::min(sz, other.sz); ++i) {
  134.             data[i] = other[i];
  135.         }
  136.         if (sz < other.sz) {
  137.             std::uninitialized_copy_n(other.data + sz, other.sz - sz, data + sz);
  138.         } else if (sz > other.sz) {
  139.             std::destroy_n(data + other.sz, sz - other.sz);
  140.         }
  141.     }
  142.     sz = other.sz;
  143.     return *this;
  144. }
  145.  
  146. template<typename T>
  147. Vector<T>& Vector<T>::operator=(Vector&& other) noexcept {
  148.     Swap(other);
  149.     return *this;
  150. }
  151.  
  152. template<typename T>
  153. T& Vector<T>::operator[](size_t index) {
  154.     return data[index];
  155. }
  156.  
  157. template<typename T>
  158. const T& Vector<T>::operator[](size_t index) const {
  159.     return data[index];
  160. }
  161.  
  162. template <typename T>
  163. void Vector<T>::Reserve(size_t n) {
  164.     if (n > data.cp) {
  165.         RawMemory<T> data2(n);
  166.         std::uninitialized_move_n(data.buf, sz, data2.buf);
  167.         std::destroy_n(data.buf, sz);
  168.         data.Swap(data2);
  169.     }
  170. }
  171.  
  172. template<typename T>
  173. void Vector<T>::Resize(size_t n) {
  174.     Reserve(n);
  175.  
  176.     if (n < sz) {
  177.         std::destroy_n(data + sz, sz - n);
  178.     } else if (n > sz) {
  179.         std::uninitialized_default_construct_n(data + sz, n - sz);
  180.     }
  181.     sz = n;
  182. }
  183.  
  184. template<typename T>
  185. void Vector<T>::PushBack(const T& elem) {
  186.     if (sz == data.cp) {
  187.         Reserve(sz == 0 ? 1 : 2 * sz);
  188.     }
  189.     new (data + sz) T(elem);
  190.     ++sz;
  191. }
  192.  
  193. template<typename T>
  194. void Vector<T>::PushBack(T&& elem) {
  195.     if (sz == data.cp) {
  196.         Reserve(sz == 0 ? 1 : 2 * sz);
  197.     }
  198.     new (data + sz) T(std::move(elem));
  199.     ++sz;
  200. }
  201.  
  202. template<typename T>
  203. void Vector<T>::PopBack() {
  204.     std::destroy_at(data + sz - 1);
  205. }
  206.  
  207. template <typename T>
  208. void Vector<T>::Clear() {
  209.     std::destroy_n(data.buf, sz);
  210.     sz = 0;
  211. }
  212.  
  213. template<typename T>
  214. void Vector<T>::Swap(Vector& other) noexcept {
  215.     data.Swap(other.data);
  216.     std::swap(sz, other.sz);
  217. }
  218.  
  219. template<typename T>
  220. size_t Vector<T>::Size() const noexcept {
  221.     return sz;
  222. }
  223.  
  224. template<typename T>
  225. size_t Vector<T>::Capacity() const noexcept {
  226.     return data.cp;
  227. }
  228.  
  229. template<typename T>
  230. template<typename... Args>
  231. T& Vector<T>::EmplaceBack(Args&& ... args) {
  232.     if (sz == data.cp) {
  233.         Reserve(sz == 0 ? 1 : 2 * sz);
  234.     }
  235.     new (data + sz) T(std::forward<Args>(args)...);
  236.     ++sz;
  237.     return data[sz-1];
  238. }
  239.  
  240.  
  241.  
Advertisement
Add Comment
Please, Sign In to add comment