diff --git a/tstl/include/iterator.hpp b/tstl/include/iterator.hpp index 879be0cc..89bd9f75 100644 --- a/tstl/include/iterator.hpp +++ b/tstl/include/iterator.hpp @@ -21,6 +21,44 @@ size_t distance(Iterator it, Iterator end){ return end - it; } +template< typename Iterator> +struct reverse_iterator { + using iterator_type = Iterator; + using value_type = typename std::iterator_traits::value_type; + using difference_type = typename std::iterator_traits::difference_type; + using pointer = typename std::iterator_traits::pointer; + using reference = typename std::iterator_traits::reference; + + reverse_iterator(Iterator it) : it(it) { + //Nothing else + } + + reference operator*(){ + return *it; + } + + reverse_iterator& operator++(){ + --it; + return *this; + } + + reverse_iterator& operator--(){ + ++it; + return *this; + } + + bool operator==(const reverse_iterator& rhs){ + return it == rhs.it; + } + + bool operator!=(const reverse_iterator& rhs){ + return it != rhs.it; + } + +private: + iterator_type it; +}; + template< typename Container > struct back_insert_iterator { using container_type = Container; diff --git a/tstl/include/type_traits.hpp b/tstl/include/type_traits.hpp index 8eb757e4..364d7a2c 100644 --- a/tstl/include/type_traits.hpp +++ b/tstl/include/type_traits.hpp @@ -15,12 +15,18 @@ namespace std { template struct iterator_traits { - using value_type = typename T::value_type; + using value_type = typename T::value_type; + using reference = typename T::reference; + using pointer = typename T::pointer; + using difference_type = typename T::difference_type; }; template struct iterator_traits { - using value_type = T; + using value_type = T; + using reference = T&; + using pointer = T*; + using difference_type = size_t; }; template diff --git a/tstl/include/vector.hpp b/tstl/include/vector.hpp index 121825df..f6448649 100644 --- a/tstl/include/vector.hpp +++ b/tstl/include/vector.hpp @@ -21,11 +21,14 @@ namespace std { template class vector { public: - typedef T value_type; - typedef value_type* pointer_type; - typedef size_t size_type; - typedef value_type* iterator; - typedef const value_type* const_iterator; + typedef T value_type; + typedef value_type* pointer_type; + typedef size_t size_type; + typedef value_type* iterator; + typedef const value_type* const_iterator; + + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; private: T* data; @@ -258,6 +261,24 @@ public: return const_iterator(&data[_size]); } + //Iterators + + reverse_iterator rbegin(){ + return iterator(&data[_size] - 1); + } + + constexpr const_reverse_iterator rbegin() const { + return const_iterator(&data[_size - 1]); + } + + reverse_iterator rend(){ + return reverse_iterator(&data[-1]); + } + + constexpr const_reverse_iterator rend() const { + return const_reverse_iterator(&data[-1]); + } + // Relational operators bool operator==(const vector& rhs) const { diff --git a/tstl/test_suite/vector.cpp b/tstl/test_suite/vector.cpp index 38edb201..6aeb0124 100644 --- a/tstl/test_suite/vector.cpp +++ b/tstl/test_suite/vector.cpp @@ -108,6 +108,39 @@ void test_push_front(){ check(*a.begin() == 99); } +void test_reverse_iterator(){ + std::vector a{1, 0, 0, 2, 3, 4}; + + auto it = a.rbegin(); + auto end = a.rend(); + + check(it != end, "Invalid reverse iterator"); + check(*it == 4, "Invalid reverse iterator"); + + ++it; + check(it != end, "Invalid reverse iterator"); + check(*it == 3, "Invalid reverse iterator"); + + ++it; + check(it != end, "Invalid reverse iterator"); + check(*it == 2, "Invalid reverse iterator"); + + ++it; + check(it != end, "Invalid reverse iterator"); + check(*it == 0, "Invalid reverse iterator"); + + ++it; + check(it != end, "Invalid reverse iterator"); + check(*it == 0, "Invalid reverse iterator"); + + ++it; + check(it != end, "Invalid reverse iterator"); + check(*it == 1, "Invalid reverse iterator"); + + ++it; + check(it == end, "Invalid reverse iterator"); +} + } //end of anonymous namespace void vector_tests(){ @@ -117,4 +150,5 @@ void vector_tests(){ test_erase_remove(); test_erase_remove_if(); test_push_front(); + test_reverse_iterator(); }