diff --git a/src/list.hh b/src/list.hh index 2a846ae..367e319 100644 --- a/src/list.hh +++ b/src/list.hh @@ -15,8 +15,6 @@ public: class reverse_iterator; class const_iterator; class const_reverse_iterator; - // using const_iterator = const iterator; - // using const_reverse_iterator = const reverse_iterator; private: // data structure /////////////////////////////////////////////////////////// diff --git a/src/test.cc b/src/test.cc index 0833581..8beff48 100644 --- a/src/test.cc +++ b/src/test.cc @@ -1,42 +1,84 @@ #include "list.hh" #include "vector.hh" +#include +#include +#include #include -using phundrak::list; -using phundrak::vector; -using std::cout; +using namespace std; -int main(void) { +int main() { - cout << "\n\nTest vecteur\n"; + // vector test_vec = {'C', 'a', 'r', 't', 'i', 'e', 'r'}; - vector testvec{'C', 'a', 'r', 't', 'i', 'e', 'r'}; + // for (auto c : test_vec) + // cout << c << " "; + // cout << std::endl; - for (size_t i = 0; i < testvec.size(); ++i) { - cout << testvec[i] << " "; + // for (size_t i = 0; i < test_vec.size(); ++i) + // cout << test_vec.at(i) << " "; + // cout << std::endl; + + // for (size_t i = 0; i < test_vec.size(); ++i) + // cout << test_vec[i] << " "; + // cout << std::endl; + + // std::for_each(std::begin(test_vec), std::end(test_vec), + // [](auto elem) { cout << elem << " "; }); + // cout << std::endl; + + // cout << "The front() of test_vec is : " << test_vec.front() << std::endl; + // cout << "The back() of test_vec is : " << test_vec.back() << std::endl; + + // for (size_t i = 0; i < test_vec.size(); ++i) + // cout << test_vec.data()[i] << " "; + // cout << std::endl; + + // for (auto itr{test_vec.cbegin()}; itr != test_vec.cend(); ++itr) + // cout << *itr << " "; + // cout << std::endl; + + // for (auto itr{test_vec.rbegin()}; itr != test_vec.rend(); ++itr) + // cout << *itr << " "; + // cout << std::endl; + + // cout << "Is the vector test_vec empty? " << (test_vec.empty() ? "yes" : + // "no") + // << std::endl; + // cout << "Size of test_vec: " << test_vec.size() << std::endl; + // cout << "Capacity of test_vec: " << test_vec.capacity() << std::endl; + // test_vec.shrink_to_fit(); + // cout << "Capacity of test_vec after shrink_to_fit(): " << + // test_vec.capacity() + // << std::endl; + + // cout << "test_vec.clear();" << std::endl; + // // test_vec.clear(); + // cout << "Is the vector test_vec empty? " << (test_vec.empty() ? "yes" : + // "no") + // << std::endl; + // cout << "Size of test_vec: " << test_vec.size() << std::endl; + // cout << "Capacity of test_vec: " << test_vec.capacity() << std::endl; + + // phundrak::vector myvector = {10, 20, 30}; + // myvector.emplace(myvector.cbegin(), 100); + // for (auto elem : myvector) + // cout << elem << std::endl; + + srand((unsigned)time(0)); + + phundrak::vector vector1 = {1, 4, 7}; + + for (int i = 0; i < 1000; ++i) { + int to_input = rand() % 10; + auto it = vector1.cbegin(); + for (; *it < to_input; ++it) + ; + vector1.insert(it, to_input); } - cout << std::endl; - cout << "\n\nTest list\n"; - - list test{'C', 'a', 'r', 't', 'i', 'e', 'r'}; - - for (auto c : test) - cout << c << " "; - - cout << "\n"; - - list test_unique{1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, - 4, 1, 1, 5, 1, 2, 1, 1, 3, 3, 3}; - printf("Elements before unique():\n"); - for (const auto &elem : test_unique) - cout << elem << " "; - - cout << "\n"; - test_unique.unique(); - for (const auto &elem : test_unique) - cout << elem << " "; - cout << "\n"; + for(int elem : vector1) + cout << elem << "\n"; return 0; } diff --git a/src/vector.hh b/src/vector.hh index c7af21b..355fc4d 100644 --- a/src/vector.hh +++ b/src/vector.hh @@ -8,9 +8,16 @@ namespace phundrak { using size_type = std::size_t; +using difference_type = std::ptrdiff_t; template > class vector { +public: + class iterator; + class const_iterator; + class reverse_iterator; + class const_reverse_iterator; + private: void double_capacity() { if (data_) { @@ -127,7 +134,10 @@ public: // Destructor /////////////////////////////////////////////////////////////// - virtual ~vector() noexcept { delete[] data_; } + virtual ~vector() noexcept { + if (data_) + delete[] data_; + } // Copy assignment operator ///////////////////////////////////////////////// @@ -251,11 +261,57 @@ public: // Iterators // ///////////////////////////////////////////////////////////////////////////// - // TODO: iterator functions + // begin //////////////////////////////////////////////////////////////////// - // Capacity /////////////////////////////////////////////////////////////// + iterator begin() noexcept { return iterator{data_}; } + const_iterator begin() const noexcept { return const_iterator{data_}; } - bool empty() const noexcept { return (data_ == nullptr) ? true : false; } + const_iterator cbegin() const noexcept { return const_iterator{data_}; } + + // end ////////////////////////////////////////////////////////////////////// + + iterator end() noexcept { return iterator{&data_[size_]}; } + const_iterator end() const noexcept { return const_iterator{&data_[size_]}; } + + const_iterator cend() const noexcept { return const_iterator{&data_[size_]}; } + + // rbegin /////////////////////////////////////////////////////////////////// + + reverse_iterator rbegin() noexcept { + return reverse_iterator{&data_[size_ - 1]}; + } + const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator{data_[size_ - 1]}; + } + + const_reverse_iterator crbegin() const noexcept { + return const_reverse_iterator{&data_[size_ - 1]}; + } + + // rend ///////////////////////////////////////////////////////////////////// + + reverse_iterator rend() noexcept { + reverse_iterator ret{data_}; + ++ret; + return ret; + } + const_reverse_iterator rend() const noexcept { + const_reverse_iterator ret{data_}; + ++ret; + return ret; + } + + const_reverse_iterator crend() const noexcept { + const_reverse_iterator ret{data_}; + ++ret; + return ret; + } + + ///////////////////////////////////////////////////////////////////////////// + // Capacity // + ///////////////////////////////////////////////////////////////////////////// + + bool empty() const noexcept { return (size_ == 0) ? true : false; } size_t size() const noexcept { return size_; } @@ -275,7 +331,11 @@ public: delete[] olddata; } - // Modifiers ////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// + // Modifiers // + ///////////////////////////////////////////////////////////////////////////// + + // clear //////////////////////////////////////////////////////////////////// void clear() noexcept { delete[] data_; @@ -283,9 +343,86 @@ public: size_ = 0; } - // insert: can't do iterators :( - // emplace: can't do iterators :( - // erase: can't do iterators :( + // insert /////////////////////////////////////////////////////////////////// + + iterator insert(const_iterator pos, const T &value) { + if (size_ == capacity_) + double_capacity(); + ++size_; + T prev = value; + auto end = cend(); + for (; pos != end; ++pos) { + T temp = *pos; + *pos = prev; + prev = temp; + } + return pos; + } + + iterator insert(const_iterator pos, T &&value) { + if (size_ == capacity_) + double_capacity(); + ++size_; + T prev = std::move(value); + iterator ret = pos; + auto end = cend(); + for (; pos != end; ++pos) { + T temp = std::move(*pos); + *pos = std::move(prev); + prev = std::move(temp); + } + return ++ret; + } + + iterator insert(const_iterator pos, size_type count, const T &value) { + for (size_type i = 0; i < count; ++i, ++pos) { + insert(pos, value); + } + } + + template ::value, + InputIT> * = nullptr> + iterator insert(const_iterator pos, InputIT first, InputIT last) { + for (; first != last; ++first) { + insert(pos, *first); + } + } + + iterator insert(const_iterator pos, std::initializer_list ilist) { + for (const T elem : ilist) { + insert(pos, elem); + ++pos; + } + } + + // emplace ////////////////////////////////////////////////////////////////// + + template + iterator emplace(const_iterator pos, Args &&... args) { + if (size_ == capacity_) + double_capacity(); + auto ptr1 = rbegin(); + ++ptr1; + auto ptr2 = rbegin(); + printf("ptr1 : %d\nptr2: %d\n", *ptr1, *ptr2); + for (; ptr2 != pos; ++ptr2, ++ptr1) + std::swap(*ptr2, *ptr1); + std::swap(*ptr2, *ptr1); + *ptr1 = T(std::forward(args)...); + + // *pos = T(std::forward(args)...); + ++size_; + return pos; + } + + // erase //////////////////////////////////////////////////////////////////// + + iterator erase(const_iterator pos) {} + + iterator erase(const_iterator first, const_iterator last) {} + + // push_back //////////////////////////////////////////////////////////////// void push_back(const T &value) { ++size_; @@ -299,13 +436,17 @@ public: data_[size_ - 1] = std::move(value); } - // emplace_back: don't know how to use std::allocator_traits + // emplace_back ///////////////////////////////////////////////////////////// + + // pop_back ///////////////////////////////////////////////////////////////// void pop_back() { if (size_ > 0) --size_; } + // resize /////////////////////////////////////////////////////////////////// + void resize(size_t count, T value = T()) { if (count < size_) size_ = count; @@ -315,6 +456,8 @@ public: push_back(value); } + // swap ///////////////////////////////////////////////////////////////////// + void swap(vector &other) { std::swap(capacity_, other.capacity_); std::swap(size_, other.size_); @@ -335,23 +478,26 @@ public: T *it; public: + using iterator_category = std::forward_iterator_tag; + iterator() : it{nullptr} {} explicit iterator(T *point) : it{point} {} iterator(const iterator &other) : it{other.it} {} + explicit iterator(const_iterator &other) : it{other.it} {} iterator(iterator &&other) { std::swap(it, other.it); } iterator &operator=(T *point) { - it = point; + *it = *point; return *this; } iterator &operator=(const iterator &other) { - it = other.it; + *it = *other.it; return *this; } iterator &operator=(iterator &&other) { - std::swap(it, other.it); + std::swap(*it, *other.it); return *this; } @@ -371,6 +517,12 @@ public: return t; } + iterator &operator+(int i) { + for (; i > 0; --i) + ++it; + return *this; + } + iterator &operator--() { // --i --it; return *this; @@ -384,6 +536,12 @@ public: return t; } + iterator &operator-(int i) { + for (; i > 0; --i) + --it; + return *this; + } + bool operator==(T *point) { return point == it; } bool operator==(const iterator &other) { return other.it == it; } bool operator==(iterator &&other) { return other.it == it; } @@ -399,6 +557,8 @@ public: class const_iterator : public iterator { public: + using iterator_category = std::forward_iterator_tag; + const_iterator() : iterator() {} explicit const_iterator(T *point) : iterator{point} {} explicit const_iterator(const iterator &other) : iterator{other} {} @@ -406,7 +566,7 @@ public: explicit const_iterator(iterator &&other) : iterator{std::move(other)} {} const_iterator(const_iterator &&other) : iterator{std::move(other)} {} - const T &operator*() { return this->it; } + const T &operator*() const { return *this->it; } }; class reverse_iterator : public iterator { @@ -417,25 +577,24 @@ public: reverse_iterator(reverse_iterator &&other) : iterator(std::move(other)) {} reverse_iterator &operator++() { - ++this->it; + --this->it; return *this; } reverse_iterator operator++(int) { reverse_iterator t{*this}; - ++this->it; - ; + --this->it; return t; } reverse_iterator &operator--() { - --this->it; + ++this->it; return *this; } reverse_iterator operator--(int) { reverse_iterator t{*this}; - --this->it; + ++this->it; return t; } @@ -452,7 +611,8 @@ public: : reverse_iterator{other} {} explicit const_reverse_iterator(reverse_iterator &&other) : reverse_iterator{other} {} - virtual ~const_reverse_iterator() { ~reverse_iterator(); } + const T &operator*() const { return *this->it; } + virtual ~const_reverse_iterator() { this->~reverse_iterator(); } }; protected: