O_Egor

SimpleVector

Feb 9th, 2023
1,444
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.39 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <cassert>
  4. #include <initializer_list>
  5. #include <stdexcept>
  6. #include <algorithm>
  7. #include <iostream>
  8.  
  9. template <typename Type>
  10. class SimpleVector
  11. {
  12. public:
  13.  
  14.     using Iterator = Type*;
  15.     using ConstIterator = const Type*;
  16.  
  17.     SimpleVector() noexcept = default;
  18.  
  19.     // Создаёт вектор из size элементов, инициализированных значением по умолчанию
  20.     explicit SimpleVector(size_t size):SimpleVector(size, Type())
  21.     {}
  22.  
  23.     // Создаёт вектор из size элементов, инициализированных значением value
  24.     SimpleVector(size_t size, const Type& value)
  25.         :size_(size)
  26.         ,capacity_(size)
  27.     {
  28.         // Напишите тело конструктора самостоятельно
  29.         if (size)
  30.         {
  31.             simple_vector_ = new Type[size];
  32.             std::fill(begin(), end(), value);
  33.         }
  34.     }
  35.  
  36.     SimpleVector(const SimpleVector& other)
  37.         :size_(other.size_)
  38.         ,capacity_(other.capacity_)
  39.     {
  40.         Assign(other.begin(), other.end());
  41.     }
  42.  
  43.     // Создаёт вектор из std::initializer_list
  44.     SimpleVector(std::initializer_list<Type> init)
  45.         :size_(init.size())
  46.         ,capacity_(init.size())
  47.     {
  48.         // Напишите тело конструктора самостоятельно
  49.         Assign(init.begin(), init.end());
  50.     }
  51.  
  52.     ~SimpleVector()
  53.     {
  54.         delete[] simple_vector_;
  55.     }
  56.  
  57.     // Возвращает количество элементов в массиве
  58.     size_t GetSize() const noexcept
  59.     {
  60.         // Напишите тело самостоятельно
  61.         return size_;
  62.     }
  63.  
  64.     // Возвращает вместимость массива
  65.     size_t GetCapacity() const noexcept
  66.     {
  67.         // Напишите тело самостоятельно
  68.         return capacity_;
  69.     }
  70.  
  71.     // Сообщает, пустой ли массив
  72.     bool IsEmpty() const noexcept
  73.     {
  74.         return size_ == 0;
  75.     }
  76.  
  77.     // Возвращает ссылку на элемент с индексом index
  78.     Type& operator[](size_t index) noexcept
  79.     {
  80.         // Напишите тело самостоятельно
  81.         //assert(index < size_ - 1);
  82.  
  83.         return simple_vector_[index];
  84.     }
  85.  
  86.     // Возвращает константную ссылку на элемент с индексом index
  87.     const Type& operator[](size_t index) const noexcept
  88.     {
  89.         // Напишите тело самостоятельно
  90.         //assert(index < size_ - 1);
  91.  
  92.         return simple_vector_[index];
  93.     }
  94.  
  95.     // Возвращает константную ссылку на элемент с индексом index
  96.     // Выбрасывает исключение std::out_of_range, если index >= size
  97.     Type& At(size_t index)
  98.     {
  99.         // Напишите тело самостоятельно
  100.         if (index >= size_)
  101.         {
  102.             throw std::out_of_range("simple_vector subscript out of range!");
  103.         }
  104.         else
  105.         {
  106.             return simple_vector_[index];
  107.         }
  108.     }
  109.  
  110.     // Возвращает константную ссылку на элемент с индексом index
  111.     // Выбрасывает исключение std::out_of_range, если index >= size
  112.     const Type& At(size_t index) const
  113.     {
  114.         // Напишите тело самостоятельно
  115.         if (index >= size_)
  116.         {
  117.             throw std::out_of_range("simple_vector subscript out of range!");
  118.         }
  119.         else
  120.         {
  121.             return simple_vector_[index];
  122.         }
  123.     }
  124.  
  125.     // Обнуляет размер массива, не изменяя его вместимость
  126.     void Clear() noexcept
  127.     {
  128.         // Напишите тело самостоятельно
  129.         size_ = 0;
  130.     }
  131.  
  132.     // Изменяет размер массива.
  133.     // При увеличении размера новые элементы получают значение по умолчанию для типа Type
  134.     void Resize(size_t new_size)
  135.     {
  136.         if(new_size > size_)
  137.         {
  138.             if(new_size > capacity_)
  139.             {
  140.                 capacity_ = new_size;
  141.                 Type* new_simple_vector = new Type[capacity_];
  142.                 std::copy(begin(), end(), new_simple_vector);
  143.                 delete[] simple_vector_;
  144.                 simple_vector_ = new_simple_vector;
  145.             }
  146.             std::fill(simple_vector_ + size_, simple_vector_ + capacity_, Type());
  147.         }
  148.         size_ = new_size;
  149.     }
  150.  
  151.     SimpleVector& operator=(const SimpleVector& rhs)
  152.     {
  153.         if(&rhs != this)
  154.         {
  155.             auto rhs_copy = rhs;
  156.             swap(rhs_copy);
  157.         }
  158.  
  159.         return *this;
  160.     }
  161.  
  162.     void PushBack(const Type& value)
  163.     {
  164.         Insert(end(), value);
  165.     }
  166.  
  167.     Iterator Insert(ConstIterator pos, const Type& value)
  168.     {
  169.         if(capacity_ == size_)
  170.         {
  171.             capacity_ = capacity_ ? capacity_ * 2 : 1;
  172.             Type* new_simple_vector = new Type[capacity_];
  173.             Iterator new_element = std::copy(begin(), Iterator(pos), new_simple_vector);
  174.             *new_element = value;
  175.             std::copy(Iterator(pos), end(), std::next(new_element));
  176.             delete[] simple_vector_;
  177.             simple_vector_ = new_simple_vector;
  178.         }
  179.         else
  180.         {
  181.             std::copy_backward(Iterator(pos), end(), std::next(Iterator(pos)));
  182.             *(Iterator(pos)) = value;
  183.         }
  184.  
  185.         ++size_;
  186.         return Iterator(pos);
  187.     }
  188.  
  189.     void PopBack() noexcept
  190.     {
  191.         assert(size_ != 0);
  192.  
  193.         --size_;
  194.     }
  195.  
  196.     Iterator Erase(ConstIterator pos)
  197.     {
  198.         assert(size_ != 0);
  199.  
  200.         std::copy(std::next(Iterator(pos)), end(), Iterator(pos));
  201.         --size_;
  202.  
  203.         return Iterator(pos);
  204.     }
  205.  
  206.     void swap(SimpleVector& other) noexcept
  207.     {
  208.         std::swap(simple_vector_, other.simple_vector_);
  209.         std::swap(size_, other.size_);
  210.         std::swap(capacity_, other.capacity_);
  211.     }
  212.  
  213.     // Возвращает итератор на начало массива
  214.     // Для пустого массива может быть равен (или не равен) nullptr
  215.     Iterator begin() noexcept
  216.     {
  217.         // Напишите тело самостоятельно
  218.         return simple_vector_;
  219.     }
  220.  
  221.     // Возвращает итератор на элемент, следующий за последним
  222.     // Для пустого массива может быть равен (или не равен) nullptr
  223.     Iterator end() noexcept
  224.     {
  225.         // Напишите тело самостоятельно
  226.         return simple_vector_ + size_;
  227.     }
  228.  
  229.     // Возвращает константный итератор на начало массива
  230.     // Для пустого массива может быть равен (или не равен) nullptr
  231.     ConstIterator begin() const noexcept
  232.     {
  233.         // Напишите тело самостоятельно
  234.         return simple_vector_;
  235.     }
  236.  
  237.     // Возвращает итератор на элемент, следующий за последним
  238.     // Для пустого массива может быть равен (или не равен) nullptr
  239.     ConstIterator end() const noexcept
  240.     {
  241.         // Напишите тело самостоятельно
  242.         return simple_vector_ + size_;
  243.     }
  244.  
  245.     // Возвращает константный итератор на начало массива
  246.     // Для пустого массива может быть равен (или не равен) nullptr
  247.     ConstIterator cbegin() const noexcept
  248.     {
  249.         // Напишите тело самостоятельно
  250.         return begin();
  251.     }
  252.  
  253.     // Возвращает итератор на элемент, следующий за последним
  254.     // Для пустого массива может быть равен (или не равен) nullptr
  255.     ConstIterator cend() const noexcept
  256.     {
  257.         // Напишите тело самостоятельно
  258.         return end();
  259.     }
  260.  
  261. private:
  262.  
  263.     template <typename InputIterator>
  264.     void Assign(InputIterator range_begin, InputIterator range_end)
  265.     {
  266.         simple_vector_ = new Type[size_];
  267.         std::copy(range_begin, range_end, begin());
  268.     }
  269.  
  270.     Type* simple_vector_ = nullptr;
  271.     size_t size_ = 0u;
  272.     size_t capacity_ = 0u;
  273.  
  274. };
  275.  
  276. template <typename Type>
  277. inline bool operator==(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs)
  278. {
  279.    
  280.     return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  281. }
  282.  
  283. template <typename Type>
  284. inline bool operator!=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs)
  285. {
  286.     return !(lhs == rhs);
  287. }
  288.  
  289. template <typename Type>
  290. inline bool operator<(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs)
  291. {
  292.     return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  293. }
  294.  
  295. template <typename Type>
  296. inline bool operator<=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs)
  297. {
  298.     return !(rhs < lhs);
  299. }
  300.  
  301. template <typename Type>
  302. inline bool operator>(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs)
  303. {
  304.     return rhs < lhs;
  305. }
  306.  
  307. template <typename Type>
  308. inline bool operator>=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs)
  309. {
  310.     return !(lhs < rhs);
  311. }
  312.  
  313. inline void Test1() {
  314.     // Инициализация конструктором по умолчанию
  315.     {
  316.         SimpleVector<int> v;
  317.         assert(v.GetSize() == 0u);
  318.         assert(v.IsEmpty());
  319.         assert(v.GetCapacity() == 0u);
  320.     }
  321.  
  322.     // Инициализация вектора указанного размера
  323.     {
  324.         SimpleVector<int> v(5);
  325.         assert(v.GetSize() == 5u);
  326.         assert(v.GetCapacity() == 5u);
  327.         assert(!v.IsEmpty());
  328.         for (size_t i = 0; i < v.GetSize(); ++i) {
  329.             assert(v[i] == 0);
  330.         }
  331.     }
  332.  
  333.     // Инициализация вектора, заполненного заданным значением
  334.     {
  335.         SimpleVector<int> v(3, 42);
  336.         assert(v.GetSize() == 3);
  337.         assert(v.GetCapacity() == 3);
  338.         for (size_t i = 0; i < v.GetSize(); ++i) {
  339.             assert(v[i] == 42);
  340.         }
  341.     }
  342.  
  343.     // Инициализация вектора при помощи initializer_list
  344.     {
  345.         SimpleVector<int> v{ 1, 2, 3 };
  346.         assert(v.GetSize() == 3);
  347.         assert(v.GetCapacity() == 3);
  348.         assert(v[2] == 3);
  349.     }
  350.  
  351.     // Доступ к элементам при помощи At
  352.     {
  353.         SimpleVector<int> v(3);
  354.         assert(&v.At(2) == &v[2]);
  355.         try {
  356.             v.At(3);
  357.             assert(false);  // Ожидается выбрасывание исключения
  358.         }
  359.         catch (const std::out_of_range&) {
  360.         }
  361.         catch (...) {
  362.             assert(false);  // Не ожидается исключение, отличное от out_of_range
  363.         }
  364.     }
  365.  
  366.     // Очистка вектора
  367.     {
  368.         SimpleVector<int> v(10);
  369.         const size_t old_capacity = v.GetCapacity();
  370.         v.Clear();
  371.         assert(v.GetSize() == 0);
  372.         assert(v.GetCapacity() == old_capacity);
  373.     }
  374.  
  375.     // Изменение размера
  376.     {
  377.         SimpleVector<int> v(3);
  378.         v[2] = 17;
  379.         v.Resize(7);
  380.         assert(v.GetSize() == 7);
  381.         assert(v.GetCapacity() >= v.GetSize());
  382.         assert(v[2] == 17);
  383.         assert(v[3] == 0);
  384.     }
  385.     {
  386.         SimpleVector<int> v(3);
  387.         v[0] = 42;
  388.         v[1] = 55;
  389.         const size_t old_capacity = v.GetCapacity();
  390.         v.Resize(2);
  391.         assert(v.GetSize() == 2);
  392.         assert(v.GetCapacity() == old_capacity);
  393.         assert(v[0] == 42);
  394.         assert(v[1] == 55);
  395.     }
  396.     {
  397.         const size_t old_size = 3;
  398.         SimpleVector<int> v(3);
  399.         v.Resize(old_size + 5);
  400.         v[3] = 42;
  401.         v.Resize(old_size);
  402.         v.Resize(old_size + 2);
  403.         assert(v[3] == 0);
  404.     }
  405.  
  406.     // Итерирование по SimpleVector
  407.     {
  408.         // Пустой вектор
  409.         {
  410.             SimpleVector<int> v;
  411.             assert(v.begin() == nullptr);
  412.             assert(v.end() == nullptr);
  413.         }
  414.  
  415.         // Непустой вектор
  416.         {
  417.             SimpleVector<int> v(10, 42);
  418.             assert(v.begin());
  419.             assert(*v.begin() == 42);
  420.             assert(v.end() == v.begin() + v.GetSize());
  421.         }
  422.     }
  423. }
  424.  
  425. inline void Test2() {
  426.     // PushBack
  427.     {
  428.         SimpleVector<int> v(1);
  429.         v.PushBack(42);
  430.         assert(v.GetSize() == 2);
  431.         assert(v.GetCapacity() >= v.GetSize());
  432.         assert(v[0] == 0);
  433.         assert(v[1] == 42);
  434.     }
  435.  
  436.     // Если хватает места, PushBack не увеличивает Capacity
  437.     {
  438.         SimpleVector<int> v(2);
  439.         v.Resize(1);
  440.         const size_t old_capacity = v.GetCapacity();
  441.         v.PushBack(123);
  442.         assert(v.GetSize() == 2);
  443.         assert(v.GetCapacity() == old_capacity);
  444.     }
  445.  
  446.     // PopBack
  447.     {
  448.         SimpleVector<int> v{ 0, 1, 2, 3 };
  449.         const size_t old_capacity = v.GetCapacity();
  450.         const auto old_begin = v.begin();
  451.         v.PopBack();
  452.         assert(v.GetCapacity() == old_capacity);
  453.         assert(v.begin() == old_begin);
  454.         assert((v == SimpleVector<int>{0, 1, 2}));
  455.     }
  456.  
  457.     // Конструктор копирования
  458.     {
  459.         SimpleVector<int> numbers{ 1, 2 };
  460.         auto numbers_copy(numbers);
  461.         assert(&numbers_copy[0] != &numbers[0]);
  462.         assert(numbers_copy.GetSize() == numbers.GetSize());
  463.         for (size_t i = 0; i < numbers.GetSize(); ++i) {
  464.             assert(numbers_copy[i] == numbers[i]);
  465.             assert(&numbers_copy[i] != &numbers[i]);
  466.         }
  467.     }
  468.  
  469.     // Сравнение
  470.     {
  471.         assert((SimpleVector{ 1, 2, 3 } == SimpleVector{ 1, 2, 3 }));
  472.         assert((SimpleVector{ 1, 2, 3 } != SimpleVector{ 1, 2, 2 }));
  473.  
  474.         assert((SimpleVector{ 1, 2, 3 } < SimpleVector{ 1, 2, 3, 1 }));
  475.         assert((SimpleVector{ 1, 2, 3 } > SimpleVector{ 1, 2, 2, 1 }));
  476.  
  477.         assert((SimpleVector{ 1, 2, 3 } >= SimpleVector{ 1, 2, 3 }));
  478.         assert((SimpleVector{ 1, 2, 4 } >= SimpleVector{ 1, 2, 3 }));
  479.         assert((SimpleVector{ 1, 2, 3 } <= SimpleVector{ 1, 2, 3 }));
  480.         assert((SimpleVector{ 1, 2, 3 } <= SimpleVector{ 1, 2, 4 }));
  481.     }
  482.  
  483.     // Обмен значений векторов
  484.     {
  485.         SimpleVector<int> v1{ 42, 666 };
  486.         SimpleVector<int> v2;
  487.         v2.PushBack(0);
  488.         v2.PushBack(1);
  489.         v2.PushBack(2);
  490.         const int* const begin1 = &v1[0];
  491.         const int* const begin2 = &v2[0];
  492.  
  493.         const size_t capacity1 = v1.GetCapacity();
  494.         const size_t capacity2 = v2.GetCapacity();
  495.  
  496.         const size_t size1 = v1.GetSize();
  497.         const size_t size2 = v2.GetSize();
  498.  
  499.         static_assert(noexcept(v1.swap(v2)));
  500.         v1.swap(v2);
  501.         assert(&v2[0] == begin1);
  502.         assert(&v1[0] == begin2);
  503.         assert(v1.GetSize() == size2);
  504.         assert(v2.GetSize() == size1);
  505.         assert(v1.GetCapacity() == capacity2);
  506.         assert(v2.GetCapacity() == capacity1);
  507.     }
  508.  
  509.     // Присваивание
  510.     {
  511.         SimpleVector<int> src_vector{ 1, 2, 3, 4 };
  512.         SimpleVector<int> dst_vector{ 1, 2, 3, 4, 5, 6 };
  513.         dst_vector = src_vector;
  514.         assert(dst_vector == src_vector);
  515.     }
  516.  
  517.     // Вставка элементов
  518.     {
  519.         SimpleVector<int> v{ 1, 2, 3, 4 };
  520.         v.Insert(v.begin() + 2, 42);
  521.         assert((v == SimpleVector<int>{1, 2, 42, 3, 4}));
  522.     }
  523.  
  524.     // Удаление элементов
  525.     {
  526.         SimpleVector<int> v{ 1, 2, 3, 4 };
  527.         v.Erase(v.cbegin() + 2);
  528.         assert((v == SimpleVector<int>{1, 2, 4}));
  529.     }
  530. }
  531.  
  532. int main()
  533. {
  534.     Test1();
  535.     Test2();
  536.     SimpleVector<int> sv;
  537.     for(int i = 0; i < 10; ++i)
  538.     {
  539.         sv.PushBack(i);
  540.     }
  541.     //Тут выводит 1 (True), а в 18 тесте не проходит это решение :-/
  542.     std::cout << (sv.Insert(sv.end(), 10) == sv.end() - 1) << '\n';
  543.  
  544.     std::cout << *(sv.end() - 1);
  545.  
  546. }
Advertisement
Add Comment
Please, Sign In to add comment