shushus

Спринт 8. Разработка контейнера SimpleVector. Часть вторая.

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