Advertisement
Guest User

Untitled

a guest
Feb 21st, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.78 KB | None | 0 0
  1. #pragma once
  2. #include <iterator>
  3. #include <assert.h>
  4. #include <memory>
  5. #include <new>
  6. #include <type_traits>
  7.  
  8.  
  9. template <class T>
  10. class VectorSafe;
  11.  
  12. template <class T, int DIR>
  13. class VectorIter;
  14. template<class T> class Vector {
  15.  
  16.     std::allocator<T> _alloc = std::allocator<T>();
  17.     T* data_ = nullptr;
  18.     size_t size_;
  19.     size_t capacity_;
  20.  
  21. public:
  22.     using iterator = VectorIter<T, 1>;
  23.     using const_iterator = VectorIter<const T, 1>;
  24.     using reverse_iterator = VectorIter<T, -1>;
  25.     using const_reverse_iterator = VectorIter<const T, -1>;
  26.  
  27.     //basic
  28.     Vector()
  29.     {
  30.         try {
  31.             data_ = _alloc.allocate(1);
  32.  
  33.             size_ = 0;
  34.             capacity_ = 1;
  35.             Invariant();
  36.  
  37.         }
  38.         catch (std::bad_alloc& e)
  39.         {
  40.             data_ = nullptr;
  41.             size_ = 0;
  42.             capacity_ = 0;
  43.             throw;
  44.         }
  45.  
  46.     }
  47.  
  48.     ~Vector()
  49.     {
  50.         for (int i = 0; i < size_; i++)
  51.         {
  52.             data_[i].~T();
  53.         }
  54.         _alloc.deallocate(data_, capacity_);
  55.  
  56.  
  57.     }
  58.  
  59.     //copy construktor // basic
  60.     Vector(const Vector& other) :Vector(other.size() + 1, other.begin(), other.end()) {}
  61.  
  62.  
  63.     //move construktor
  64.     Vector(Vector&& other)
  65.     {
  66.         this->size_ = 0;
  67.         this->capacity_ = 0;
  68.         this->data_ = nullptr;
  69.  
  70.         *this = std::move(other);
  71.         Invariant();
  72.     }
  73.  
  74.     template<class tIter>
  75.     Vector(size_t newCapacity,
  76.         const tIter& begin,
  77.         const tIter& end)
  78.  
  79.     {
  80.         data_ = _alloc.allocate(newCapacity);
  81.         try
  82.         {
  83.             size_ = 0;
  84.             capacity_ = newCapacity;
  85.  
  86.             tIter ptrBegin = begin;
  87.             tIter ptrEnd = end;
  88.             T* ptrData = data_;
  89.  
  90.             for (ptrBegin; ptrBegin != ptrEnd; ptrBegin++)
  91.             {
  92.                 new (ptrData)  T(*ptrBegin);
  93.                 size_++;
  94.                 ptrData++;
  95.             }
  96.         }
  97.         catch (...)
  98.         {
  99.             this->~Vector();
  100.             size_ = 0;
  101.             capacity_ = 0;
  102.             throw;
  103.  
  104.         }
  105.     }
  106.  
  107.  
  108.     //basic
  109.     Vector(const char* other) : Vector(std::strlen(other), other, other + std::strlen(other)) {}
  110.  
  111.  
  112.     //basic
  113.     //kopiera värden
  114.     Vector& operator=(const Vector& other)
  115.  
  116.         Vector<T> temp(other);
  117.     swap(*this, temp);
  118.  
  119. }
  120.     }
  121.  
  122.     Vector& operator=(Vector&& other)
  123.     {
  124.  
  125.         if (this->data_ == other.data())
  126.         {
  127.             return *this;
  128.         }
  129.         else
  130.         {
  131.             this->~Vector();
  132.  
  133.             this->size_ = other.size();
  134.             this->capacity_ = other.capacity();
  135.             this->data_ = other.data();
  136.  
  137.             other.data_ = nullptr;
  138.             other.size_ = 0;
  139.             other.capacity_ = 0;
  140.  
  141.             return *this;
  142.         }
  143.     }
  144.  
  145.     T& operator[](size_t i)
  146.     {
  147.         return data_[i];
  148.  
  149.     }
  150.  
  151.     //basic
  152.     T& at(size_t i)
  153.     {
  154.         if (i <= size_ - 1)
  155.         {
  156.             return data_[i];
  157.         }
  158.         else
  159.         {
  160.             throw std::out_of_range("utanför range");
  161.         }
  162.  
  163.     }
  164.  
  165.  
  166.     //basic/
  167.     const T& operator[](size_t i) const
  168.     {
  169.         return data_[i];
  170.     }
  171.  
  172.     //basic
  173.     const T& at(size_t i) const
  174.     {
  175.  
  176.         if (i <= size_)
  177.         {
  178.             return data_[i];
  179.         }
  180.         else
  181.         {
  182.             throw std::out_of_range("hej");
  183.         }
  184.  
  185.     }
  186.  
  187.     T* data() noexcept
  188.     {
  189.         return data_;
  190.     }
  191.  
  192.     const T* data() const noexcept
  193.     {
  194.         return data_;
  195.     }
  196.  
  197.     size_t size() const noexcept
  198.     {
  199.         return size_;
  200.     }
  201.  
  202.     //basic
  203.     void reserve(size_t n)
  204.     {
  205.         if (n > this->capacity_)
  206.         {
  207.             Vector new_vec(n, data_, data_ + size_);
  208.             *this = (std::move(new_vec));
  209.         }
  210.     }
  211.  
  212.     size_t capacity() const noexcept
  213.     {
  214.         return capacity_;
  215.     }
  216.  
  217.     //basic
  218.     void shrink_to_fit()
  219.     {
  220.  
  221.         if (this->size() != this->capacity()) {
  222.  
  223.             Vector new_vec(size_, data_, data_ + size_);
  224.             *this = (std::move(new_vec));
  225.         }
  226.     }
  227.     //basic
  228.     void push_back(const T& value)
  229.     {
  230.         try {
  231.             if (this->size() + 1 <= this->capacity())
  232.             {
  233.                 new (data_ + size_)  T(value);
  234.                 this->size_++;
  235.             }
  236.             else
  237.             {
  238.                 this->reserve(capacity_ * 2);
  239.                 this->push_back(value);
  240.             }
  241.         }
  242.         catch (...)
  243.         {
  244.             data_[size_].~T();
  245.             throw;
  246.         }
  247.  
  248.     }
  249.     // value is moved into the new element.
  250.     //basic
  251.     void push_back(T&& value)
  252.     {
  253.         try {
  254.             if (this->size() + 1 <= this->capacity())
  255.             {
  256.                 new (data_ + size_)  T(std::move(value));
  257.                 this->size_++;
  258.             }
  259.             else
  260.             {
  261.                 this->reserve(capacity_ * 2);
  262.                 this->push_back(value);
  263.             }
  264.         }
  265.         catch (...)
  266.         {
  267.             data_[size_].~T();
  268.             throw;
  269.  
  270.         }
  271.     }
  272.     void resize(size_t n)
  273.     {
  274.  
  275.         if (n > size_)
  276.         {
  277.             for (size_t i = size_; i != n; ++i)
  278.             {
  279.                 this->push_back(T());
  280.             }
  281.  
  282.         }
  283.         if (n < size_)
  284.         {
  285.             for (size_t i = size_; i == n; --i)
  286.             {
  287.                 data_[i].~T();
  288.             }
  289.             size_ = n;
  290.  
  291.         }
  292.  
  293.     }
  294.  
  295.     iterator begin()
  296.     {
  297.         return iterator(data_);
  298.     }
  299.  
  300.     const_iterator begin() const
  301.     {
  302.         return const_iterator(data_);
  303.     }
  304.  
  305.     iterator end()
  306.     {
  307.         return iterator(data_ + size_);
  308.     }
  309.  
  310.     const_iterator end() const
  311.     {
  312.         return const_iterator(data_ + size_);
  313.     }
  314.  
  315.     const_iterator cbegin() const
  316.     {
  317.         return const_iterator(data_);
  318.     }
  319.  
  320.     const_iterator cend() const
  321.     {
  322.         return const_iterator(data_ + size_);
  323.     }
  324.  
  325.     reverse_iterator rbegin()
  326.     {
  327.         return reverse_iterator(data_ + size_ - 1);
  328.     }
  329.  
  330.     const_reverse_iterator rbegin() const
  331.     {
  332.         return const_reverse_iterator(data_ + size_ - 1);
  333.     }
  334.  
  335.     reverse_iterator rend()
  336.     {
  337.         return reverse_iterator(data_ - 1);
  338.     }
  339.  
  340.     const_reverse_iterator rend() const
  341.     {
  342.         return const_reverse_iterator(data_ - 1);
  343.     }
  344.  
  345.     const_reverse_iterator crbegin() const
  346.     {
  347.         return const_reverse_iterator(data_ + size_ - 1);
  348.     }
  349.  
  350.     const_reverse_iterator crend() const
  351.     {
  352.         return const_reverse_iterator(data_ - 1);
  353.     }
  354.  
  355.  
  356.     friend bool operator==(const Vector& lhs, const Vector& other)
  357.     {
  358.         if (lhs.size() != other.size()) {
  359.             return false;
  360.         }
  361.         else {
  362.             for (size_t i = 0; i < lhs.size(); i++) {
  363.                 if (lhs[i] != other[i]) {
  364.                     return false;
  365.                 }
  366.             }
  367.             return true;
  368.         }
  369.     }
  370.  
  371.     friend bool operator!=(const Vector& lhs, const Vector& other)
  372.     {
  373.  
  374.         return !(lhs == other);
  375.  
  376.     }
  377.     friend bool operator<(const Vector& lhs, const Vector& other)
  378.     {
  379.         size_t size = 0;
  380.         if (lhs.size() > other.size())
  381.         {
  382.             size = lhs.size();
  383.         }
  384.         else
  385.         {
  386.             size = other.size();
  387.         }
  388.  
  389.  
  390.         for (size_t i = 0; i < size; i++)
  391.         {
  392.             if (lhs[i] != other[i])
  393.             {
  394.                 if (lhs[i] < other[i])
  395.                 {
  396.                     return true;
  397.                 }
  398.                 else
  399.                 {
  400.                     return false;
  401.                 }
  402.             }
  403.         }
  404.         return false;
  405.  
  406.     }
  407.     friend bool operator>(const Vector& lhs, const Vector& other)
  408.     {
  409.         return!(lhs < other);
  410.     }
  411.     friend bool operator<=(const Vector& lhs, const Vector& other)
  412.     {
  413.         size_t size = 0;
  414.         if (lhs.size() > other.size())
  415.         {
  416.             size = lhs.size();
  417.         }
  418.         else
  419.         {
  420.             size = other.size();
  421.         }
  422.  
  423.         for (size_t i = 0; i < size; i++)
  424.         {
  425.             if (lhs[i] != other[i])
  426.             {
  427.                 if (lhs[i] < other[i])
  428.                 {
  429.                     return true;
  430.                 }
  431.                 else
  432.                 {
  433.                     return false;
  434.                 }
  435.             }
  436.         }
  437.         if (lhs.size() == other.size())
  438.         {
  439.             return true;
  440.         }
  441.         else
  442.         {
  443.             return false;
  444.         }
  445.     }
  446.     friend bool operator>=(const Vector& lhs, const Vector& other)
  447.     {
  448.         return!(lhs <= other);
  449.     }
  450.  
  451.  
  452.     template <class T>  void swap(Vector<T>& lhs, Vector<T>& rhs)
  453.     {
  454.         Vector<T> temp = (std::move(lhs));
  455.         lhs = (std::move(rhs));
  456.         rhs = (std::move(temp));
  457.     }
  458.  
  459.  
  460.     friend std::ostream& operator<<(std::ostream& cout, const Vector& other)
  461.     {
  462.         for (size_t i = 0; i < other.size(); ++i)
  463.             cout << other[i];
  464.         return cout;
  465.     }
  466.  
  467.     void Check() const {
  468.         assert(Invariant());
  469.     }
  470.  
  471.  
  472.     bool Invariant() const
  473.     {
  474.         assert(size_ >= 0);
  475.         assert(capacity_ >= 0);
  476.         assert(size_ <= capacity_);
  477.         return true;
  478.  
  479.     }
  480.  
  481. };
  482.  
  483. template<class T, int DIR>
  484. class VectorIter {
  485.     T* ptr;
  486.     int dir;
  487.  
  488. public:
  489.     using iterator_category = std::random_access_iterator_tag;
  490.     using value_type = T;
  491.     using difference_type = int;
  492.     using pointer = T * ;
  493.     using reference = T & ;
  494.  
  495.  
  496.     VectorIter() : ptr() {
  497.  
  498.     }
  499.  
  500.  
  501.     VectorIter(T* p)
  502.     {
  503.         ptr = p;
  504.         dir = DIR;
  505.  
  506.     }
  507.  
  508.     VectorIter(const VectorIter& other)
  509.     {
  510.         ptr = other.ptr;
  511.         dir = other.dir;
  512.  
  513.     }
  514.  
  515.     VectorIter& operator=(const VectorIter& other) {
  516.         if (this == &other)
  517.             return *this;
  518.  
  519.         ptr = other.ptr;
  520.         return *this;
  521.  
  522.     }
  523.  
  524.     T& operator*() { return *ptr; }
  525.  
  526.     T* operator->() { return ptr; }
  527.  
  528.     T& operator[](size_t i) {
  529.         if (DIR == -1)
  530.         {
  531.             return *(ptr - i);
  532.         }
  533.  
  534.         return *(ptr + i);
  535.     }
  536.  
  537.     VectorIter& operator++() {
  538.         if (DIR == -1)
  539.         {
  540.             --ptr;
  541.             return *this;
  542.         }
  543.  
  544.         ++ptr;
  545.         return *this;
  546.     }
  547.  
  548.     VectorIter& operator--()
  549.     {
  550.         if (DIR == -1)
  551.         {
  552.             ++ptr;
  553.             return *this;
  554.         }
  555.         --ptr;
  556.         return *this;
  557.     }
  558.  
  559.     VectorIter operator++(int)
  560.     {
  561.         if (DIR == -1)
  562.         {
  563.             VectorIter temp = *this;
  564.             --ptr;
  565.             return temp;
  566.         }
  567.         VectorIter temp = *this;
  568.         ++ptr;
  569.         return temp;
  570.     }
  571.  
  572.  
  573.     VectorIter operator--(int)
  574.     {
  575.         if (DIR == -1)
  576.         {
  577.             VectorIter temp = *this;
  578.             ++ptr;
  579.             return temp;
  580.         }
  581.  
  582.         VectorIter temp = *this;
  583.         --ptr;
  584.         return temp;
  585.     }
  586.  
  587.     VectorIter operator+(difference_type i) const
  588.     {
  589.         //?? (reverse)
  590.         return VectorIter(ptr + i);
  591.     }
  592.  
  593.     VectorIter operator-(difference_type i) const
  594.     {
  595.         //?? (reverse)
  596.         return VectorIter(ptr - i);
  597.     }
  598.  
  599.  
  600.     difference_type operator-(const VectorIter& other) const
  601.     {
  602.         int diff = (ptr - other.ptr);
  603.         return diff;
  604.     }
  605.  
  606.  
  607.     friend bool operator==(const VectorIter& lhs, const VectorIter& rhs)
  608.     {
  609.         if (lhs.ptr == rhs.ptr)
  610.         {
  611.             return true;
  612.         }
  613.         else
  614.         {
  615.             return false;
  616.         }
  617.     }
  618.  
  619.     friend bool operator!=(const VectorIter& lhs, const VectorIter& rhs)
  620.     {
  621.         return !(lhs.ptr == rhs.ptr);
  622.     }
  623.  
  624.     friend bool operator<(const VectorIter& lhs, const VectorIter& rhs)
  625.     {
  626.         if (lhs.dir == -1)
  627.         {
  628.             return lhs.ptr > rhs.ptr;
  629.         }
  630.  
  631.         return lhs.ptr < rhs.ptr;
  632.     }
  633.  
  634.     friend bool operator>(const VectorIter& lhs, const VectorIter& rhs)
  635.     {
  636.         if (lhs.dir == -1)
  637.         {
  638.             return lhs.ptr < rhs.ptr;
  639.         }
  640.  
  641.         return !(lhs.ptr < rhs.ptr);
  642.     }
  643.  
  644.     friend bool operator<=(const VectorIter& lhs, const VectorIter& rhs)
  645.     {
  646.         if (lhs.dir == -1)
  647.         {
  648.             return !(lhs.ptr <= rhs.ptr);
  649.         }
  650.  
  651.         return lhs.ptr <= rhs.ptr;
  652.     }
  653.  
  654.     friend bool operator>=(const VectorIter& lhs, const VectorIter& rhs)
  655.     {
  656.         if (lhs.dir == -1)
  657.         {
  658.             return lhs.ptr <= rhs.ptr;
  659.         }
  660.  
  661.         return !(lhs.ptr <= rhs.ptr);
  662.     }
  663.  
  664. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement