Advertisement
kutuzzzov

Урок 11 эмплейсб

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