diff --git a/alib2std/src/extensions/array.hpp b/alib2std/src/extensions/array.hpp index 94b088f5e8c90143f1e30d548a8363105e771f1c..e8873c85a075274b34af5b08b4f2e7d0c661f8cb 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 d5f9bcfb0c787bdf9ba8953539b0ce245feff40d..4dabe6d91f686c2ea38a95cec6efb6f34230465e 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 5cd124010bee89f1e221f60b0ea11ad97cb162dc..126c887fb9db1e5be40ce8ef89241501671e3e94 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 e3bdbba3e99184e47c32f2b63e2b6d9cb7c76634..a699d3cd1ebe80c753df5ef2db98c61b35e08d84 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 0d7b768a102c0f95a2352350e0f0a13524af1738..98ba4ef17a7409851da1936828f2648fe39b56c7 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 3ee3bdae6a22e43b968c4025684c90ea26c37a75..a7826c1d87f22ee94cbf008c8241fd3faf74a0fc 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 0ab4ed7047bf0ac323a2117504e27d262ccb5546..bee421f6b4b5d3fe0354d5a3e7cc8b9325d7e9e5 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 0ed88d093040c0f3e27b7bd474f5d73b43a429a9..f1459b6715248e2f3bef7023ddaf9723fe34cdfd 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 740228d3760895e5921dd223793950156d238b46..938c4aae863300d39b6bfdd82713dec8106cb371 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 82785aca767a115ea666d465a19a198bee518165..fe53c7077365571beb6900eb796baa90c429ba6c 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 cf7a0e1f903c112f4062085996028d8045530a5c..9a164e455535e808b2b180784ab15cf81648596d 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 eefdd2541117e27ea8385ef524f87995d72d600d..8200be689b5dc0e2adca30e227a0e4c163e9c8fe 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_