TrickmanOff

vec2

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