Advertisement
Guest User

Untitled

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