From 0da7bfd5fb386d0613f21f2fee5aa8641bbd8832 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 13 Mar 2019 09:05:11 +0100 Subject: [PATCH] reverse iterator in ptr_vector::insert, ... and ptr_array::set, ... --- .../src/extensions/container/ptr_array.hpp | 36 ++ .../src/extensions/container/ptr_vector.hpp | 447 +++++++++++++++++- .../extensions/container/PtrVectorTest.cpp | 5 + 3 files changed, 484 insertions(+), 4 deletions(-) diff --git a/alib2std/src/extensions/container/ptr_array.hpp b/alib2std/src/extensions/container/ptr_array.hpp index f2f901f4c0..60402c3005 100644 --- a/alib2std/src/extensions/container/ptr_array.hpp +++ b/alib2std/src/extensions/container/ptr_array.hpp @@ -551,6 +551,25 @@ public: return dereferencer ( m_data.begin ( ) + dist ); } + /** + * \brief + * Setter of value in the array on position specified by iterator specified by \p pos. The value is cloned from the \p value. + * + * \param pos the iterator specifying position to set + * \param value the value to place at given position + * + * \return iterator to the set value + */ + template < class R > + iterator set ( const_reverse_iterator pos, R && value ) { + size_type dist = std::distance ( crbegin ( ), pos ); + + // If the set value and value at position pos are same instances first clone, then delete + delete std::exchange ( m_data.at ( m_data.size ( ) - dist - 1 ), ext::clone ( std::forward < R > ( value ) ) ); + + return dereferencer ( m_data.rbegin ( ) + dist ); + } + /** * \brief * Setter of internaly constructed value into the array on position specified by iterator specified by \p pos. The value is constructed from paramter pack. @@ -568,6 +587,23 @@ public: return set ( pos, R ( std::forward < Args > ( args ) ... ) ); } + /** + * \brief + * Setter of internaly constructed value into the array on position specified by iterator specified by \p pos. The value is constructed from paramter pack. + * + * \tparam R the actual type of constructed value + * \tparam Args ... types of value constructor parameters + * + * \param pos the iterator specifying position to set + * \param args ... value constructor parameters + * + * \return iterator to the set value + */ + template < class R, class ... Args > + iterator emplace_set ( const_reverse_iterator pos, Args && ... args ) { + return set ( pos, R ( std::forward < Args > ( args ) ... ) ); + } + /** * Swaps two instances of pointer array * diff --git a/alib2std/src/extensions/container/ptr_vector.hpp b/alib2std/src/extensions/container/ptr_vector.hpp index 3a1f1bf573..f096aa61e3 100644 --- a/alib2std/src/extensions/container/ptr_vector.hpp +++ b/alib2std/src/extensions/container/ptr_vector.hpp @@ -24,7 +24,6 @@ #ifndef __PTR_VECTOR_HPP_ #define __PTR_VECTOR_HPP_ -#include <vector> #include <ostream> #include <sstream> #include <string> @@ -33,6 +32,7 @@ #include <extensions/allocFix.hpp> #include <extensions/range.hpp> #include <extensions/clone.hpp> +#include <extensions/container/vector.hpp> namespace ext { @@ -49,7 +49,7 @@ class ptr_vector { * \brief * The vector of pointers to stored values */ - std::vector < T * > m_data; + ext::vector < T * > m_data; public: /** @@ -622,6 +622,22 @@ public: m_data.clear ( ); } + /** + * \brief + * Changes 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 set + * \param value the value to place to that position + * + * \return updated iterator to the changed location + */ + template < class R > + iterator set ( iterator pos, R && value ) { + return set ( const_iterator ( pos ), std::forward < R > ( value ) ); + } + /** * \brief * Changes the value on position given by iterator \p pos @@ -643,6 +659,60 @@ public: return dereferencer ( m_data.begin ( ) + dist ); } + /** + * \brief + * Changes 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 set + * \param value the value to place to that position + * + * \return updated iterator to the changed location + */ + template < class R > + reverse_iterator set ( reverse_iterator pos, R && value ) { + return set ( const_reverse_iterator ( pos ), std::forward < R > ( value ) ); + } + + /** + * \brief + * Changes 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 set + * \param value the value to place to that position + * + * \return updated iterator to the changed location + */ + template < class R > + reverse_iterator set ( const_reverse_iterator pos, R && value ) { + size_type dist = std::distance ( crbegin ( ), pos ); + + // If the set value and value at position pos are same instances first clone, then delete + delete std::exchange ( m_data.at ( m_data.size ( ) - dist - 1 ), ext::clone ( std::forward < R > ( value ) ) ); + + return dereferencer ( m_data.rbegin ( ) + dist ); + } + + /** + * \brief + * Changes the value on position given by iterator \p pos + * + * \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 changed location + */ + template < class R = T, class ... Args > + iterator emplace_set ( iterator pos, Args && ... args ) { + return emplace_set ( const_iterator ( pos ), std::forward < Args > ( args ) ... ); + } + /** * \brief * Changes the value on position given by iterator \p pos @@ -660,6 +730,56 @@ public: return set ( pos, R ( std::forward < Args > ( args ) ... ) ); } + /** + * \brief + * Changes the value on position given by iterator \p pos + * + * \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 changed location + */ + template < class R = T, class ... Args > + reverse_iterator emplace_set ( reverse_iterator pos, Args && ... args ) { + return emplace_set ( const_reverse_iterator ( pos ), std::forward < Args > ( args ) ... ); + } + + /** + * \brief + * Changes the value on position given by iterator \p pos + * + * \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 changed location + */ + template < class R = T, class ... Args > + reverse_iterator emplace_set ( const_reverse_iterator pos, Args && ... args ) { + return set ( pos, R ( std::forward < Args > ( args ) ... ) ); + } + + /** + * \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 + */ + template < class R > + iterator insert ( iterator pos, R && value ) { + return insert ( const_insert ( pos ), std::forward < R > ( value ) ); + } + /** * \brief * Inserts the value on position given by iterator \p pos @@ -676,6 +796,55 @@ public: return dereferencer ( m_data.insert ( pos.base ( ), ext::clone ( std::forward < R > ( 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 + */ + template < class R > + reverse_iterator insert ( reverse_iterator pos, R && value ) { + return insert ( const_reverse_iterator ( pos ), std::forward < R > ( 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 + */ + template < class R > + reverse_iterator insert ( const_reverse_iterator pos, R && value ) { + return dereferencer ( m_data.insert ( pos.base ( ), ext::clone ( std::forward < R > ( 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 + */ + template < class R > + iterator insert ( iterator pos, size_type count, const R & value ) { + return insert ( const_iterator ( pos ), count, value ); + } + /** * \brief * Inserts the \p count copies of value on position given by iterator \p pos @@ -697,6 +866,60 @@ public: return res; } + /** + * \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 + */ + template < class R > + reverse_iterator insert ( reverse_iterator pos, size_type count, const R & value ) { + return insert ( const_reverse_iterator ( pos ), count, 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 + */ + template < class R > + reverse_iterator insert ( const_reverse_iterator pos, size_type count, const R & value ) { + reverse_iterator res = dereferencer ( m_data.insert ( pos, count, NULL ) ); + for ( size_type i = 0; i < count; ++ i ) { + * ( std::next ( res.base ( ) ).base ( ) + i ) = ext::clone ( value ); + } + return res; + } + + /** + * \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 > + iterator insert ( iterator pos, InputIt first, InputIt last ) { + return insert ( const_iterator ( pos ), first, last ); + } + /** * \brief * Inserts the values from the given range to positions starting at given iterator \p pos @@ -719,6 +942,60 @@ public: return res; } + /** + * \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 ( reverse_iterator pos, InputIt first, InputIt last ) { + return insert ( const_reverse_iterator ( pos ), first, last ); + } + + /** + * \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 ) { + size_type size = std::distance ( first, last ); + reverse_iterator res = dereferencer ( m_data.insert ( pos, size, NULL ) ); + + for ( size_type i = 0; i < size; ++ first, ++ i ) + * ( std::next ( res.base ( ) ).base ( ) + i ) = ext::clone ( * first ); + + return res; + } + + /** + * \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 + */ + template < class R > + iterator insert ( iterator pos, std::initializer_list < R > ilist ) { + return insert ( const_iterator ( pos ), std::move ( ilist ) ); + } + /** * \brief * Inserts the values from the given initializer list to positions starting at given iterator \p pos @@ -735,6 +1012,55 @@ public: return insert ( pos, ilist.begin ( ), ilist.end ( ) ); } + /** + * \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 + */ + template < class R > + reverse_iterator insert ( reverse_iterator pos, std::initializer_list < R > ilist ) { + return insert ( const_reverse_iterator ( pos ), std::move ( ilist ) ); + } + + /** + * \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 + */ + template < class R > + reverse_iterator insert ( const_reverse_iterator pos, std::initializer_list < R > ilist ) { + return insert ( pos, ilist.begin ( ), ilist.end ( ) ); + } + + /** + * \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 > + iterator emplace ( iterator pos, Args && ... args ) { + return emplace ( const_iterator ( pos ), std::forward < Args > ( args ) ... ); + } + /** * \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. @@ -752,6 +1078,52 @@ public: return insert ( pos, R ( std::forward < Args > ( args ) ... ) ); } + /** + * \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 ( reverse_iterator pos, Args && ... args ) { + return emplace ( const_reverse_iterator ( pos ), std::forward < Args > ( args ) ... ); + } + + /** + * \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 insert ( pos, R ( std::forward < Args > ( args ) ... ) ); + } + + /** + * \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 @@ -761,10 +1133,48 @@ public: * \returns updated iterator to value after the removed one */ iterator erase ( const_iterator pos ) { - delete * pos.base ( ); + delete std::addressof ( * pos ); + return dereferencer ( m_data.erase ( pos.base ( ) ) ); + } + + /** + * \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 ) { + delete std::addressof ( * pos ); return dereferencer ( m_data.erase ( 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 @@ -776,7 +1186,36 @@ public: */ iterator erase ( const_iterator first, const_iterator last ) { for ( const_iterator first_copy = first; first_copy != last; ++ first_copy ) { - delete * first_copy.base ( ); + delete std::addressof ( * first_copy ); + } + return dereferencer ( m_data.erase ( first.base ( ), last.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 + */ + 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 ) { + for ( const_reverse_iterator first_copy = first; first_copy != last; ++ first_copy ) { + delete std::addressof ( * first_copy ); } return dereferencer ( m_data.erase ( first.base ( ), last.base ( ) ) ); } diff --git a/alib2std/test-src/extensions/container/PtrVectorTest.cpp b/alib2std/test-src/extensions/container/PtrVectorTest.cpp index 4977595164..448c52e698 100644 --- a/alib2std/test-src/extensions/container/PtrVectorTest.cpp +++ b/alib2std/test-src/extensions/container/PtrVectorTest.cpp @@ -117,6 +117,11 @@ TEST_CASE ( "PtrVector", "[unit][std][container]" ) { CHECK ( data [ 1 ] == 2 ); CHECK ( data [ 2 ] == 2 ); CHECK ( data [ 3 ] == 3 ); + + auto iter1 = data.erase ( data.rbegin ( ) ); + CHECK ( iter1 == data.rbegin ( ) ); + auto iter2 = data.insert ( data.rbegin ( ), 2 ); + CHECK ( iter2 == data.rbegin ( ) ); } SECTION ( "Test Polymorphism" ) { -- GitLab