From 97e76ae05575a77bf71015e0b064d082d16c884c Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 13 Mar 2019 09:03:54 +0100 Subject: [PATCH] allow reverse iterators in vector::insert, erase, emplace, ... --- alib2std/src/extensions/container/vector.hpp | 210 ++++++++++++++++++ .../extensions/container/VectorTest.cpp | 17 ++ 2 files changed, 227 insertions(+) diff --git a/alib2std/src/extensions/container/vector.hpp b/alib2std/src/extensions/container/vector.hpp index cacfd39af1..2b768e9221 100644 --- a/alib2std/src/extensions/container/vector.hpp +++ b/alib2std/src/extensions/container/vector.hpp @@ -57,6 +57,31 @@ public: * Inherit operator = of the standard vector */ using std::vector< T, Alloc >::operator =; + + /** + * \brief + * The type of values iterator. + */ + using iterator = typename std::vector < T, Alloc >::iterator; + + /** + * \brief + * The type of constant values iterator. + */ + using const_iterator = typename std::vector < T, Alloc >::const_iterator; + + /** + * \brief + * The type of reverse values iterator. + */ + using reverse_iterator = typename std::vector < T, Alloc >::reverse_iterator; + + /** + * \brief + * The type of constant reverse values iterator. + */ + using const_reverse_iterator = typename std::vector < T, Alloc >::const_reverse_iterator; + #ifndef __clang__ /** @@ -190,6 +215,191 @@ public: auto beginIter = std::move ( * this ).begin ( ); return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); } + + /** + * Get original insert on the top level. + */ + using std::vector < T, Alloc >::insert; + + /** + * \brief + * Inserts the value on position given by iterator \p pos + * + * \tparam R the actual type of value stored inside the vector + * + * \param pos the position to insert at + * \param value the value to insert + * + * \return updated iterator to the newly inserted value + */ + reverse_iterator insert ( const_reverse_iterator pos, const T & value ) { + return reverse_iterator ( std::next ( insert ( pos.base ( ), value ) ) ); + } + + /** + * \brief + * Inserts the value on position given by iterator \p pos + * + * \tparam R the actual type of value stored inside the vector + * + * \param pos the position to insert at + * \param value the value to insert + * + * \return updated iterator to the newly inserted value + */ + reverse_iterator insert ( const_reverse_iterator pos, T && value ) { + return reverse_iterator ( std::next ( insert ( pos.base ( ), std::move ( value ) ) ) ); + } + + /** + * \brief + * Inserts the \p count copies of value on position given by iterator \p pos + * + * \tparam R the actual type of value stored inside the vector + * + * \param pos the position to insert at + * \param count the number of copies to insert + * \param value the value to insert + * + * \return updated iterator to the newly inserted value + */ + reverse_iterator insert ( const_reverse_iterator pos, size_t count, const T & value ) { + return reverse_iterator ( std::next ( insert ( pos.base ( ), count, value ) ) ); + } + + /** + * \brief + * Inserts the values from the given range to positions starting at given iterator \p pos + * + * \tparam InputIt the iterator type + * + * \param first the begining of the range + * \param last the end of the range + * + * \return updated iterator to the newly inserted value + */ + template < class InputIt > + reverse_iterator insert ( const_reverse_iterator pos, InputIt first, InputIt last ) { + return reverse_iterator ( std::next ( insert ( pos.base ( ), first, last ) ) ); + } + + /** + * \brief + * Inserts the values from the given initializer list to positions starting at given iterator \p pos + * + * \tparam R the types stored inside the initializer list + * + * \param pos the position to insert at + * \param ilist the initializer list + * + * \return updated iterator to the newly inserted value + */ + reverse_iterator insert ( const_reverse_iterator pos, std::initializer_list < T > ilist ) { + return reverse_iterator ( std::next ( insert ( pos.base ( ), std::move ( ilist ) ) ) ); + } + + /** + * Get original emplace on the top level. + */ + using std::vector < T, Alloc >::emplace; + + /** + * \brief + * Inserts a new value to the container at position given by parameter \p pos. The new value is constructed inside the method from constructor parameters. + * + * \tparam R the actual type of value stored inside the vector + * \tparam Args ... the types of arguments of the R constructor + * + * \param pos the position to set + * \param args ... the arguments of the R constructor + * + * \return updated iterator to the newly inserted value + */ + template < class R = T, class ... Args > + reverse_iterator emplace ( const_reverse_iterator pos, Args && ... args ) { + return reverse_iterator ( std::next ( emplace ( pos.base ( ), std::forward < Args > ( args ) ... ) ) ); + } + + /** + * Get original emplace on the top level. + */ + using std::vector < T, Alloc >::erase; + + /** + * \brief + * Removes element from the container at position given by parameter \p pos + * + * \param pos the iterator pointing to the value to removed + * + * \returns updated iterator to value after the removed one + */ + iterator erase ( iterator pos ) { + return erase ( const_iterator ( pos ) ); + } + + /** + * \brief + * Removes element from the container at position given by parameter \p pos + * + * \param pos the iterator pointing to the value to removed + * + * \returns updated iterator to value after the removed one + */ + reverse_iterator erase ( reverse_iterator pos ) { + return erase ( const_reverse_iterator ( pos ) ); + } + + /** + * \brief + * Removes element from the container at position given by parameter \p pos + * + * \param pos the iterator pointing to the value to removed + * + * \returns updated iterator to value after the removed one + */ + reverse_iterator erase ( const_reverse_iterator pos ) { + return reverse_iterator ( erase ( std::next ( pos ).base ( ) ) ); + } + + /** + * \brief + * Removes elements from the container in range given parameters \p first and \p last + * + * \param first the begining of the removed range + * \param last the end of the removed range + * + * \returns updated iterator to value after the removed ones + */ + iterator erase ( iterator first, iterator last ) { + return erase ( const_iterator ( first ), const_iterator ( last ) ); + } + + /** + * \brief + * Removes elements from the container in range given parameters \p first and \p last + * + * \param first the begining of the removed range + * \param last the end of the removed range + * + * \returns updated iterator to value after the removed ones + */ + reverse_iterator erase ( reverse_iterator first, reverse_iterator last ) { + return erase ( const_reverse_iterator ( first ), const_reverse_iterator ( last ) ); + } + + /** + * \brief + * Removes elements from the container in range given parameters \p first and \p last + * + * \param first the begining of the removed range + * \param last the end of the removed range + * + * \returns updated iterator to value after the removed ones + */ + reverse_iterator erase ( const_reverse_iterator first, const_reverse_iterator last ) { + return reverse_iterator ( erase ( std::next ( first ).base ( ), std::next ( last ).base ( ) ) ); + } + }; /** diff --git a/alib2std/test-src/extensions/container/VectorTest.cpp b/alib2std/test-src/extensions/container/VectorTest.cpp index 4bfe6c3ac7..4155ca2b74 100644 --- a/alib2std/test-src/extensions/container/VectorTest.cpp +++ b/alib2std/test-src/extensions/container/VectorTest.cpp @@ -41,11 +41,28 @@ namespace { TEST_CASE ( "Vector", "[unit][std][container]" ) { SECTION ( "Properties test" ) { ext::vector<int> data = {1, 2, 3, 4}; + ext::vector<int> dataRef = {1, 2, 3, 4}; const ext::vector<int>& constData = data; + auto iter1 = data.erase ( data.begin ( ) ); + CHECK ( iter1 == data.begin ( ) ); + auto iter2 = data.erase ( data.rbegin ( ) ); + CHECK ( iter2 == data.rbegin ( ) ); + + CHECK ( data.size ( ) == 2 ); + + auto iter3 = data.insert ( data.begin ( ), 1 ); + CHECK ( iter3 == data.begin ( ) ); + auto iter4 = data.insert ( data.rbegin ( ), 4 ); + CHECK ( iter4 == data.rbegin ( ) ); + + CHECK ( data.size ( ) == 4 ); + CHECK((std::is_same<decltype(constData[0]), const int&>::value)); + CHECK ( data == dataRef ); + int moves; int copies; -- GitLab