From bdd1700332fafe4dff2e5d664a937d36a0ac20d7 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 30 Aug 2018 21:32:26 +0200 Subject: [PATCH] range enabled ext containers --- alib2std/src/extensions/array.hpp | 37 +++++++++ alib2std/src/extensions/deque.hpp | 48 +++++++++++ alib2std/src/extensions/forward_list.hpp | 48 +++++++++++ alib2std/src/extensions/linear_set.hpp | 48 +++++++++++ alib2std/src/extensions/list.hpp | 48 +++++++++++ alib2std/src/extensions/map.hpp | 48 +++++++++++ alib2std/src/extensions/ptr_array.hpp | 66 +++++++++++++-- alib2std/src/extensions/ptr_vector.hpp | 81 +++++++++++++++++-- alib2std/src/extensions/set.hpp | 48 +++++++++++ alib2std/src/extensions/unordered_map.hpp | 47 +++++++++++ .../test-src/extensions/PtrVectorTest.cpp | 20 +++++ alib2std/test-src/extensions/PtrVectorTest.h | 35 ++++++++ 12 files changed, 562 insertions(+), 12 deletions(-) diff --git a/alib2std/src/extensions/array.hpp b/alib2std/src/extensions/array.hpp index 94b088f5e8..e8873c85a0 100644 --- a/alib2std/src/extensions/array.hpp +++ b/alib2std/src/extensions/array.hpp @@ -32,6 +32,7 @@ #include <string> #include "compare.hpp" +#include "range.hpp" namespace ext { @@ -152,6 +153,42 @@ public: auto end ( ) && { return make_move_iterator ( this->end ( ) ); } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) const & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of move begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) && { + auto endIter = std::move ( * this ).end ( ); + auto beginIter = std::move ( * this ).begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } }; /** diff --git a/alib2std/src/extensions/deque.hpp b/alib2std/src/extensions/deque.hpp index d5f9bcfb0c..4dabe6d91f 100644 --- a/alib2std/src/extensions/deque.hpp +++ b/alib2std/src/extensions/deque.hpp @@ -31,6 +31,7 @@ #include "compare.hpp" #include "allocFix.hpp" +#include "range.hpp" namespace ext { @@ -83,6 +84,17 @@ public: deque & operator = ( const deque & other ) = default; #endif + /** + * Constructor from range of values. + * + * \tparam Iterator the type of range iterator + * + * \param range the source range + */ + template < class Iterator > + deque ( const ext::iterator_range < Iterator > & range ) : deque ( range.begin ( ), range.end ( ) ) { + } + /** * \brief * Inherited behavior of begin for non-const instance. @@ -142,6 +154,42 @@ public: auto end ( ) && { return make_move_iterator ( this->end ( ) ); } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) const & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of move begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) && { + auto endIter = std::move ( * this ).end ( ); + auto beginIter = std::move ( * this ).begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } }; /** diff --git a/alib2std/src/extensions/forward_list.hpp b/alib2std/src/extensions/forward_list.hpp index 5cd124010b..126c887fb9 100644 --- a/alib2std/src/extensions/forward_list.hpp +++ b/alib2std/src/extensions/forward_list.hpp @@ -31,6 +31,7 @@ #include "compare.hpp" #include "allocFix.hpp" +#include "range.hpp" namespace ext { @@ -83,6 +84,17 @@ public: forward_list & operator = ( const forward_list & other ) = default; #endif + /** + * Constructor from range of values. + * + * \tparam Iterator the type of range iterator + * + * \param range the source range + */ + template < class Iterator > + forward_list ( const ext::iterator_range < Iterator > & range ) : forward_list ( range.begin ( ), range.end ( ) ) { + } + /** * \brief * Inherited behavior of begin for non-const instance. @@ -142,6 +154,42 @@ public: auto end ( ) && { return make_move_iterator ( this->end ( ) ); } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) const & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of move begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) && { + auto endIter = std::move ( * this ).end ( ); + auto beginIter = std::move ( * this ).begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } }; /** diff --git a/alib2std/src/extensions/linear_set.hpp b/alib2std/src/extensions/linear_set.hpp index e3bdbba3e9..a699d3cd1e 100644 --- a/alib2std/src/extensions/linear_set.hpp +++ b/alib2std/src/extensions/linear_set.hpp @@ -32,6 +32,7 @@ #include "vector.hpp" #include "compare.hpp" #include "iterator.hpp" +#include "range.hpp" namespace ext { @@ -140,6 +141,17 @@ public: sort_unique ( ); } + /** + * Constructor from range of values. + * + * \tparam Iterator the type of range iterator + * + * \param range the source range + */ + template < class Iterator > + linear_set ( const ext::iterator_range < Iterator > & range ) : linear_set ( range.begin ( ), range.end ( ) ) { + } + /** * \brief * Copy constructor. @@ -277,6 +289,42 @@ public: return m_data.cend ( ); } + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) const & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of move begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) && { + auto endIter = std::move ( * this ).end ( ); + auto beginIter = std::move ( * this ).begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + /** * \brief * Removes all values from the conainer,. diff --git a/alib2std/src/extensions/list.hpp b/alib2std/src/extensions/list.hpp index 0d7b768a10..98ba4ef17a 100644 --- a/alib2std/src/extensions/list.hpp +++ b/alib2std/src/extensions/list.hpp @@ -31,6 +31,7 @@ #include "compare.hpp" #include "allocFix.hpp" +#include "range.hpp" namespace ext { @@ -83,6 +84,17 @@ public: list & operator = ( const list & other ) = default; #endif + /** + * Constructor from range of values. + * + * \tparam Iterator the type of range iterator + * + * \param range the source range + */ + template < class Iterator > + list ( const ext::iterator_range < Iterator > & range ) : list ( range.begin ( ), range.end ( ) ) { + } + /** * \brief * Inherited behavior of begin for non-const instance. @@ -142,6 +154,42 @@ public: auto end ( ) && { return make_move_iterator ( this->end ( ) ); } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) const & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of move begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) && { + auto endIter = std::move ( * this ).end ( ); + auto beginIter = std::move ( * this ).begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } }; /** diff --git a/alib2std/src/extensions/map.hpp b/alib2std/src/extensions/map.hpp index 3ee3bdae6a..a7826c1d87 100644 --- a/alib2std/src/extensions/map.hpp +++ b/alib2std/src/extensions/map.hpp @@ -34,6 +34,7 @@ #include "pair.hpp" #include "allocFix.hpp" #include "iterator.hpp" +#include "range.hpp" namespace ext { @@ -87,6 +88,17 @@ public: */ map & operator = ( const map & other ) = default; #endif + /** + * Constructor from range of values. + * + * \tparam Iterator the type of range iterator + * + * \param range the source range + */ + template < class Iterator > + map ( const ext::iterator_range < Iterator > & range ) : map ( range.begin ( ), range.end ( ) ) { + } + /** * \brief * The iterator type is inheried. @@ -236,6 +248,42 @@ public: auto end ( ) && { return make_map_move_iterator < T, R > ( this->end ( ) ); } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) const & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of move begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) && { + auto endIter = std::move ( * this ).end ( ); + auto beginIter = std::move ( * this ).begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } }; /** diff --git a/alib2std/src/extensions/ptr_array.hpp b/alib2std/src/extensions/ptr_array.hpp index 0ab4ed7047..bee421f6b4 100644 --- a/alib2std/src/extensions/ptr_array.hpp +++ b/alib2std/src/extensions/ptr_array.hpp @@ -30,7 +30,7 @@ #include "array.hpp" #include "compare.hpp" -#include "iterator.hpp" +#include "range.hpp" #include "clone.hpp" namespace ext { @@ -331,7 +331,7 @@ public: * * \return iterator to the begining */ - iterator begin ( ) noexcept { + iterator begin ( ) & noexcept { return dereferencer ( m_data.begin ( ) ); } @@ -341,10 +341,20 @@ public: * * \return iterator to the begining */ - const_iterator begin ( ) const noexcept { + const_iterator begin ( ) const & noexcept { return dereferencer ( m_data.begin ( ) ); } + /** + * \brief + * Move iterator to the begining of the values range in the array. + * + * \return iterator to the begining + */ + auto begin ( ) && noexcept { + return make_move_iterator ( this->end ( ) ); + } + /** * \brief * Iterator to the begining of the values range in the array. @@ -361,7 +371,7 @@ public: * * \return iterator to the end */ - iterator end ( ) noexcept { + iterator end ( ) & noexcept { return dereferencer ( m_data.end ( ) ); } @@ -371,10 +381,20 @@ public: * * \return iterator to the end */ - const_iterator end ( ) const noexcept { + const_iterator end ( ) const & noexcept { return dereferencer ( m_data.end ( ) ); } + /** + * \brief + * Move iterator to the begining of the values range in the array. + * + * \return iterator to the begining + */ + auto end ( ) && noexcept { + return make_move_iterator ( this->end ( ) ); + } + /** * \brief * Iterator one past the last element of the values range in the array. @@ -445,6 +465,42 @@ public: return dereferencer ( m_data.crend ( ) ); } + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) const & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of move begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) && { + auto endIter = std::move ( * this ).end ( ); + auto beginIter = std::move ( * this ).begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + /** * \brief * Array emptines test. diff --git a/alib2std/src/extensions/ptr_vector.hpp b/alib2std/src/extensions/ptr_vector.hpp index 0ed88d0930..f1459b6715 100644 --- a/alib2std/src/extensions/ptr_vector.hpp +++ b/alib2std/src/extensions/ptr_vector.hpp @@ -31,7 +31,7 @@ #include "compare.hpp" #include "allocFix.hpp" -#include "iterator.hpp" +#include "range.hpp" #include "clone.hpp" namespace ext { @@ -165,6 +165,17 @@ public: insert ( cbegin ( ), first, last ); } + /** + * Constructor from range of values. + * + * \tparam Iterator the type of range iterator + * + * \param range the source range + */ + template < class Iterator > + ptr_vector ( const ext::iterator_range < Iterator > & range ) : ptr_vector ( range.begin ( ), range.end ( ) ) { + } + /** * \brief * Constructor of the vector of size given by \p count and filled with values from \p value. @@ -372,20 +383,30 @@ public: * * \return iterator to the begining */ - iterator begin ( ) noexcept { + iterator begin ( ) & noexcept { return dereferencer ( m_data.begin ( ) ); } /** * \brief - * Iterator to the begining of the values range in the vector. + * Const iterator to the begining of the values range in the vector. * * \return iterator to the begining */ - const_iterator begin ( ) const noexcept { + const_iterator begin ( ) const & noexcept { return dereferencer ( m_data.begin ( ) ); } + /** + * \brief + * Move iterator to the begining of the values range in the vector. + * + * \return move iterator to the begining + */ + auto begin ( ) && noexcept { + return make_move_iterator ( this->begin ( ) ); + } + /** * \brief * Iterator to the begining of the values range in the vector. @@ -402,20 +423,30 @@ public: * * \return iterator to the end */ - iterator end ( ) noexcept { + iterator end ( ) & noexcept { return dereferencer ( m_data.end ( ) ); } /** * \brief - * Iterator one past the last element of the values range in the vector. + * Const iterator one past the last element of the values range in the vector. * * \return iterator to the end */ - const_iterator end ( ) const noexcept { + const_iterator end ( ) const & noexcept { return dereferencer ( m_data.end ( ) ); } + /** + * \brief + * Move iterator to the begining of the values range in the vector. + * + * \return iterator to the begining + */ + auto end ( ) && noexcept { + return make_move_iterator ( this->end ( ) ); + } + /** * \brief * Iterator one past the last element of the values range in the vector. @@ -486,6 +517,42 @@ public: return dereferencer ( m_data.crend ( ) ); } + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) const & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of move begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) && { + auto endIter = std::move ( * this ).end ( ); + auto beginIter = std::move ( * this ).begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + /** * \brief * Array emptines test. diff --git a/alib2std/src/extensions/set.hpp b/alib2std/src/extensions/set.hpp index 740228d376..938c4aae86 100644 --- a/alib2std/src/extensions/set.hpp +++ b/alib2std/src/extensions/set.hpp @@ -32,6 +32,7 @@ #include "compare.hpp" #include "allocFix.hpp" #include "iterator.hpp" +#include "range.hpp" namespace ext { @@ -83,6 +84,17 @@ public: */ set & operator = ( const set & other ) = default; #endif + /** + * Constructor from range of values. + * + * \tparam Iterator the type of range iterator + * + * \param range the source range + */ + template < class Iterator > + set ( const ext::iterator_range < Iterator > & range ) : set ( range.begin ( ), range.end ( ) ) { + } + /** * \brief * Inherited behavior of begin for non-const instance. @@ -142,6 +154,42 @@ public: auto end ( ) && { return make_set_move_iterator ( this->end ( ) ); } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) const & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of move begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) && { + auto endIter = std::move ( * this ).end ( ); + auto beginIter = std::move ( * this ).begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } }; /** diff --git a/alib2std/src/extensions/unordered_map.hpp b/alib2std/src/extensions/unordered_map.hpp index 82785aca76..fe53c70773 100644 --- a/alib2std/src/extensions/unordered_map.hpp +++ b/alib2std/src/extensions/unordered_map.hpp @@ -32,6 +32,7 @@ #include "compare.hpp" #include "allocFix.hpp" #include "iterator.hpp" +#include "range.hpp" namespace ext { @@ -86,6 +87,16 @@ public: */ unordered_map & operator = ( const unordered_map & other ) = default; #endif + /** + * Constructor from range of values. + * + * \tparam Iterator the type of range iterator + * + * \param range the source range + */ + template < class Iterator > + unordered_map ( const ext::iterator_range < Iterator > & range ) : unordered_map ( range.begin ( ), range.end ( ) ) { + } /** * \brief @@ -236,6 +247,42 @@ public: auto end ( ) && { return make_map_move_iterator < T, R > ( this->end ( ) ); } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of non-const begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) const & { + auto endIter = end ( ); + auto beginIter = begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } + + /** + * \brief + * Make range of move begin to end iterators. + * + * \return full range over container values + */ + auto range ( ) && { + auto endIter = std::move ( * this ).end ( ); + auto beginIter = std::move ( * this ).begin ( ); + return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter ); + } }; /** diff --git a/alib2std/test-src/extensions/PtrVectorTest.cpp b/alib2std/test-src/extensions/PtrVectorTest.cpp index cf7a0e1f90..9a164e4555 100644 --- a/alib2std/test-src/extensions/PtrVectorTest.cpp +++ b/alib2std/test-src/extensions/PtrVectorTest.cpp @@ -77,3 +77,23 @@ void PtrVectorTest::testPolymorph() { data2.erase ( ext::dereferencer ( ext::unique ( data2.begin ( ).base ( ), data2.end ( ).base ( ), [ ] ( const Base * a, const Base * b ) { return * a == * b; } ) ), data2.end ( ) ); } + +void PtrVectorTest::testRange ( ) { + ext::ptr_vector < int > data { 1, 2, 3, 4 }; + ext::ptr_vector < int > data2 ( data.range ( ) ); + + CPPUNIT_ASSERT ( data == data2 ); + + int moves; + int copies; + + ext::ptr_vector < Moveable > vec; + vec.push_back ( Moveable ( moves, copies ) ); + vec.push_back ( Moveable ( moves, copies ) ); + vec.push_back ( Moveable ( moves, copies ) ); + vec.push_back ( Moveable ( moves, copies ) ); + + ext::ptr_vector < Moveable > vec2 ( ext::range ( std::move ( vec ) ) ); + + CPPUNIT_ASSERT ( copies == 0 ); +} diff --git a/alib2std/test-src/extensions/PtrVectorTest.h b/alib2std/test-src/extensions/PtrVectorTest.h index eefdd25411..8200be689b 100644 --- a/alib2std/test-src/extensions/PtrVectorTest.h +++ b/alib2std/test-src/extensions/PtrVectorTest.h @@ -9,6 +9,7 @@ class PtrVectorTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE( PtrVectorTest ); CPPUNIT_TEST( testProperties ); CPPUNIT_TEST( testPolymorph ); + CPPUNIT_TEST( testRange ); CPPUNIT_TEST_SUITE_END(); enum class Type { @@ -62,12 +63,46 @@ class PtrVectorTest : public CppUnit::TestFixture } }; +class Moveable { + int& m_moves; + int& m_copies; + +public: + Moveable(int& moves, int& copies) : m_moves(moves), m_copies(copies) { + m_moves = 0; + m_copies = 0; + } + + Moveable(const Moveable& src) : m_moves(src.m_moves), m_copies(src.m_copies) { + m_copies++; + } + + Moveable(Moveable&& src) : m_moves(src.m_moves), m_copies(src.m_copies) { + m_moves++; + } + + Moveable & operator = ( const Moveable & ) { + m_copies ++; + return * this; + } + + Moveable & operator = ( Moveable && ) { + m_moves ++; + return * this; + } + + bool operator<(const Moveable&) const { + return false; + } +}; + public: void setUp(); void tearDown(); void testProperties(); void testPolymorph(); + void testRange(); }; #endif // PTR_VECTOR_TEST_H_ -- GitLab