Advertisement
RobertDeMilo

SV1

Dec 16th, 2023
451
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.65 KB | None | 0 0
  1. main
  2.  
  3. #include "simple_vector.h"
  4.  
  5. // Tests
  6. #include "tests.h"
  7.  
  8. int main() {
  9.     Test1();
  10.     return 0;
  11. }
  12. #########################################################################################
  13. simple_vector.h
  14.  
  15. #pragma once
  16.  
  17. #include <cassert>
  18. #include <initializer_list>
  19. #include "array_ptr.h"
  20.  
  21. template <typename Type>
  22. class SimpleVector
  23. {
  24. public:
  25.     using Iterator = Type*;
  26.     using ConstIterator = const Type*;
  27.  
  28.  
  29.     //По умолчанию.Создаёт пустой вектор с нулевой вместимостью.Не выделяет динамическую память и не выбрасывает исключений.
  30.     SimpleVector() noexcept = default;
  31.  
  32.     // Создаёт вектор из size элементов, инициализированных значением по умолчанию
  33.     // Параметризованный конструктор, создающий вектор заданного размера.
  34.     // Элементы вектора инициализированы значением по умолчанию для типа Type.
  35.     // Вектор должен иметь одинаковые размер и вместимость.Если размер нулевой, динамическая память для его
  36.     // элементов выделяться не должна.
  37.     explicit SimpleVector(size_t size_) :SimpleVector(size_, Type()) {
  38.         // Напишите тело конструктора самостоятельно
  39.     }
  40.  
  41.     // Создаёт вектор из size элементов, инициализированных значением value
  42.     SimpleVector(size_t size, const Type& value) :ptr_(size) {
  43.         // Напишите тело конструктора самостоятельно
  44.        
  45.         std::fill(ptr_.Get(), ptr_.Get() + size, value);
  46.         size_ = size,
  47.         capacity_ = size;
  48.     }
  49.  
  50.     ~SimpleVector()
  51.     {
  52.      
  53.     }
  54.  
  55.      //Создаёт вектор из std::initializer_list
  56.     SimpleVector(std::initializer_list<Type> init) :ptr_(init.size())
  57.     {
  58.         // Напишите тело конструктора самостоятельно
  59.         std::copy(init.begin(), init.end(), begin());
  60.         size_ = init.size();
  61.         capacity_ = size_;
  62.     }
  63.  
  64.     // Возвращает количество элементов в массиве
  65.     size_t GetSize() const noexcept {
  66.         // Напишите тело самостоятельно
  67.         return size_;
  68.     }
  69.  
  70.     // Возвращает вместимость массива
  71.     size_t GetCapacity() const noexcept {
  72.         // Напишите тело самостоятельно
  73.         return capacity_;
  74.     }
  75.  
  76.     // Сообщает, пустой ли массив
  77.     bool IsEmpty() const noexcept {
  78.         if (size_ == 0)
  79.         {
  80.             return true;
  81.         }
  82.         return false;
  83.        
  84.     }
  85.  
  86.     // Возвращает ссылку на элемент с индексом index
  87.     Type& operator[](size_t index) noexcept {
  88.         // Напишите тело самостоятельно
  89.         return ptr_.Get()[index];
  90.     }
  91.  
  92.     // Возвращает константную ссылку на элемент с индексом index
  93.     const Type& operator[](size_t index) const noexcept {
  94.         // Напишите тело самостоятельно
  95.         return ptr_.Get()[index];
  96.     }
  97.  
  98.     // Возвращает константную ссылку на элемент с индексом index
  99.     // Выбрасывает исключение std::out_of_range, если index >= size
  100.     Type& At(size_t index) {
  101.         // Напишите тело самостоятельно
  102.  
  103.         if (index >= size_)
  104.         {
  105.             throw std::out_of_range("out");
  106.         }
  107.         return ptr_.Get()[index];
  108.     }
  109.  
  110.     // Возвращает константную ссылку на элемент с индексом index
  111.     // Выбрасывает исключение std::out_of_range, если index >= size
  112.     const Type& At(size_t index) const {
  113.         // Напишите тело самостоятельно
  114.         if (index >= size_)
  115.         {
  116.             throw std::out_of_range("out");
  117.         }
  118.         return ptr_.Get()[index];
  119.     }
  120.  
  121.     // Обнуляет размер массива, не изменяя его вместимость
  122.     void Clear() noexcept {
  123.         // Напишите тело самостоятельно
  124.         size_ = 0;
  125.     }
  126.  
  127.     // Изменяет размер массива.
  128.     // При увеличении размера новые элементы получают значение по умолчанию для типа Type
  129.    
  130.     /* В методе Resize отдельно обработайте три ситуации : новый размер меньше или равен текущему,
  131.  
  132.          новый размер не превышает его вместимости,
  133.  
  134.          новый размер превышает текущую вместимость вектора.
  135.  
  136.               Если при изменении размера массива новый размер вектора превышает его текущую вместимость,
  137.               создайте новый массив с нужной вместимостью,
  138.  
  139.               скопируйте в него прежнее содержимое и
  140.               заполните остальные элементы значением по умолчанию.
  141.  
  142.               Затем старый массив можно удалить и
  143.               использовать копию.После этого не забудьте обновить размер и вместимость вектора.
  144.               Если при увеличении размера массива новый размер вектора не превышает его вместимость,
  145.               заполните добавленные элементы значением по умолчанию для типа Type.
  146.               При уменьшении размера вектора просто уменьшите его размер.*/
  147.    
  148.     void Resize(size_t new_size) {
  149.         // Напишите тело самостоятельно
  150.         if (new_size <= size_ && new_size < capacity_)
  151.         {
  152.             size_ = new_size;
  153.         }
  154.         else if (new_size > size_ && new_size < capacity_)
  155.         {
  156.             //std::fill(begin() + size_ - 1, begin() + size_ + new_size, Type());
  157.             std::fill(begin() + size_, begin() + new_size,  Type());
  158.             size_ = new_size;
  159.         }
  160.         else
  161.         {
  162.             ArrayPtr<Type> temp_(2 * new_size);//???? 2* new_size???
  163.             auto it = std::copy(begin(), end(), temp_.Get());
  164.            
  165.             std::fill(it, temp_.Get() + new_size, Type());
  166.            // void swap(ArrayPtr & other) noexcept
  167.             temp_.swap(ptr_);
  168.          
  169.             size_ = new_size;
  170.             capacity_ = std::max(2 * capacity_, new_size);
  171.         }
  172.     }
  173.  
  174.     // Возвращает итератор на начало массива
  175.     // Для пустого массива может быть равен (или не равен) nullptr
  176.     Iterator begin() noexcept {
  177.         // Напишите тело самостоятельно
  178.         return ptr_.Get();
  179.     }
  180.  
  181.     // Возвращает итератор на элемент, следующий за последним
  182.     // Для пустого массива может быть равен (или не равен) nullptr
  183.     Iterator end() noexcept {
  184.         // Напишите тело самостоятельно
  185.         return ptr_.Get() + size_;
  186.     }
  187.  
  188.     // Возвращает константный итератор на начало массива
  189.     // Для пустого массива может быть равен (или не равен) nullptr
  190.     ConstIterator begin() const noexcept {
  191.         // Напишите тело самостоятельно
  192.         return ptr_.Get();
  193.     }
  194.  
  195.     // Возвращает итератор на элемент, следующий за последним
  196.     // Для пустого массива может быть равен (или не равен) nullptr
  197.     ConstIterator end() const noexcept {
  198.         // Напишите тело самостоятельно
  199.         return ptr_.Get() + size_;
  200.     }
  201.  
  202.     /* Возвращает константный итератор на начало массива
  203.      Для пустого массива может быть равен (или не равен) nullptr*/
  204.     ConstIterator cbegin() const noexcept {
  205.      /*    Напишите тело самостоятельно*/
  206.         return ptr_.Get();
  207.  
  208.     }
  209.  
  210.      /*Возвращает итератор на элемент, следующий за последним
  211.      Для пустого массива может быть равен (или не равен) nullptr*/
  212.     ConstIterator cend() const noexcept {
  213.        /*  Напишите тело самостоятельно*/
  214.         return ptr_.Get() + size_;
  215.     }
  216.  
  217.     private:
  218.         ArrayPtr<Type> ptr_;
  219.         size_t size_ = 0;
  220.         size_t capacity_ = 0;
  221. };
  222.  
  223. #########################################################################################
  224. array_ptr.h
  225.  
  226. #pragma once
  227.  
  228. #include <iostream>
  229. #include <algorithm>
  230. #include <cassert>
  231. #include <cstdlib>
  232.  
  233. template <typename Type>
  234. class ArrayPtr {
  235. public:
  236.     // Инициализирует ArrayPtr нулевым указателем
  237.     ArrayPtr() = default;
  238.  
  239.     // Создаёт в куче массив из size элементов типа Type.
  240.     // Если size == 0, поле raw_ptr_ должно быть равно nullptr
  241.     explicit ArrayPtr(size_t size) {
  242.         // Реализуйте конструктор самостоятельно
  243.         if (size == 0)
  244.         {
  245.             // raw_ptr_ == nullptr;
  246.         }
  247.         else
  248.         {
  249.             raw_ptr_ = new Type[size];
  250.         }
  251.     }
  252.  
  253.     // Конструктор из сырого указателя, хранящего адрес массива в куче либо nullptr
  254.     explicit ArrayPtr(Type* raw_ptr) noexcept {
  255.         // Реализуйте конструктор самостоятельно
  256.         raw_ptr_ = raw_ptr;
  257.     }
  258.  
  259.     // Запрещаем копирование
  260.     ArrayPtr(const ArrayPtr&) = delete;
  261.  
  262.     ~ArrayPtr() {
  263.         // Напишите деструктор самостоятельно
  264.         delete[] raw_ptr_;
  265.     }
  266.  
  267.     // Запрещаем присваивание
  268.     ArrayPtr& operator=(const ArrayPtr&) = delete;
  269.  
  270.     // Прекращает владением массивом в памяти, возвращает значение адреса массива
  271.     // После вызова метода указатель на массив должен обнулиться
  272.     [[nodiscard]] Type* Release() noexcept {
  273.         // Заглушка. Реализуйте метод самостоятельно
  274.         auto temp = raw_ptr_;
  275.         //delete[] raw_ptr_;
  276.         raw_ptr_ = nullptr;
  277.         return temp;
  278.     }
  279.  
  280.     // Возвращает ссылку на элемент массива с индексом index
  281.     Type& operator[](size_t index) noexcept {
  282.         // Реализуйте операцию самостоятельно
  283.         return raw_ptr_[index];
  284.     }
  285.  
  286.     // Возвращает константную ссылку на элемент массива с индексом index
  287.     const Type& operator[](size_t index) const noexcept {
  288.         // Реализуйте операцию самостоятельно
  289.         return raw_ptr_[index];
  290.     }
  291.  
  292.     // Возвращает true, если указатель ненулевой, и false в противном случае
  293.     explicit operator bool() const {
  294.         // Заглушка. Реализуйте операцию самостоятельно
  295.  
  296.         if (raw_ptr_ == nullptr)
  297.         {
  298.             return false;
  299.         }
  300.         return true;
  301.     }
  302.  
  303.     // Возвращает значение сырого указателя, хранящего адрес начала массива
  304.     Type* Get() const noexcept {
  305.         // Заглушка. Реализуйте метод самостоятельно
  306.         return raw_ptr_;
  307.     }
  308.  
  309.     // Обменивается значениям указателя на массив с объектом other
  310.     void swap(ArrayPtr& other) noexcept
  311.     {
  312.         // Реализуйте метод самостоятельно
  313.         std::swap(raw_ptr_, other.raw_ptr_);
  314.     }
  315.  
  316. private:
  317.     Type* raw_ptr_ = nullptr;
  318. };
  319.  
  320. #########################################################################################
  321. tests.h
  322.  
  323. #pragma once
  324. #include <cassert>
  325. #include <stdexcept>
  326.  
  327. // У функции, объявленной со спецификатором inline, может быть несколько
  328. // идентичных определений в разных единицах трансляции.
  329. // Обычно inline помечают функции, чьё тело находится в заголовочном файле,
  330. // чтобы при подключении этого файла из разных единиц трансляции не возникало ошибок компоновки
  331. inline void Test1() {
  332.     // Инициализация конструктором по умолчанию
  333.     {
  334.         SimpleVector<int> v;
  335.         assert(v.GetSize() == 0u);
  336.         assert(v.IsEmpty());
  337.         assert(v.GetCapacity() == 0u);
  338.     }
  339.  
  340.     // Инициализация вектора указанного размера
  341.     {
  342.         SimpleVector<int> v(5);
  343.         assert(v.GetSize() == 5u);
  344.         assert(v.GetCapacity() == 5u);
  345.         assert(!v.IsEmpty());
  346.         for (size_t i = 0; i < v.GetSize(); ++i) {
  347.             assert(v[i] == 0);
  348.         }
  349.     }
  350.  
  351.     // Инициализация вектора, заполненного заданным значением
  352.     {
  353.         SimpleVector<int> v(3, 42);
  354.         assert(v.GetSize() == 3);
  355.         assert(v.GetCapacity() == 3);
  356.         for (size_t i = 0; i < v.GetSize(); ++i) {
  357.             assert(v[i] == 42);
  358.         }
  359.     }
  360.  
  361.     // Инициализация вектора при помощи initializer_list
  362.     {
  363.         SimpleVector<int> v{1, 2, 3};
  364.         assert(v.GetSize() == 3);
  365.         assert(v.GetCapacity() == 3);
  366.         assert(v[2] == 3);
  367.     }
  368.  
  369.     // Доступ к элементам при помощи At
  370.     {
  371.         SimpleVector<int> v(3);
  372.         assert(&v.At(2) == &v[2]);
  373.         try {
  374.             v.At(3);
  375.             assert(false);  // Ожидается выбрасывание исключения
  376.         } catch (const std::out_of_range&) {
  377.         } catch (...) {
  378.             assert(false);  // Не ожидается исключение, отличное от out_of_range
  379.         }
  380.     }
  381.  
  382.     // Очистка вектора
  383.     {
  384.         SimpleVector<int> v(10);
  385.         const size_t old_capacity = v.GetCapacity();
  386.         v.Clear();
  387.         assert(v.GetSize() == 0);
  388.         assert(v.GetCapacity() == old_capacity);
  389.     }
  390.  
  391.     // Изменение размера
  392.     {
  393.         SimpleVector<int> v(3);
  394.         v[2] = 17;
  395.         v.Resize(7);
  396.         assert(v.GetSize() == 7);
  397.         assert(v.GetCapacity() >= v.GetSize());
  398.         assert(v[2] == 17);
  399.         assert(v[3] == 0);
  400.     }
  401.     {
  402.         SimpleVector<int> v(3);
  403.         v[0] = 42;
  404.         v[1] = 55;
  405.         const size_t old_capacity = v.GetCapacity();
  406.         v.Resize(2);
  407.         assert(v.GetSize() == 2);
  408.         assert(v.GetCapacity() == old_capacity);
  409.         assert(v[0] == 42);
  410.         assert(v[1] == 55);
  411.     }
  412.     {
  413.         const size_t old_size = 3;
  414.         SimpleVector<int> v(3);
  415.         v.Resize(old_size + 5);
  416.         v[3] = 42;
  417.         v.Resize(old_size);
  418.         v.Resize(old_size + 2);
  419.         assert(v[3] == 0);
  420.     }
  421.  
  422.     // Итерирование по SimpleVector
  423.     {
  424.         // Пустой вектор
  425.         {
  426.             SimpleVector<int> v;
  427.             assert(v.begin() == nullptr);
  428.             assert(v.end() == nullptr);
  429.         }
  430.  
  431.         // Непустой вектор
  432.         {
  433.             SimpleVector<int> v(10, 42);
  434.             assert(v.begin());
  435.             assert(*v.begin() == 42);
  436.             assert(v.end() == v.begin() + v.GetSize());
  437.         }
  438.     }
  439. }
  440.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement