From 90048ad3cc4bd8ce777672149a0c69eb9c8115e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Thu, 2 Nov 2017 14:23:19 +0100 Subject: [PATCH] Arrays - C++-style iterators --- include/ebcl/Arrays.hh | 77 ++++ include/ebcl/Utilities.hh | 61 +++ include/ebcl/inline/Arrays.hh | 483 ++++++++++++++++++++ tests/arrays-iter.cc | 822 ++++++++++++++++++++++++++++++++++ tests/list.mk | 1 + 5 files changed, 1444 insertions(+) create mode 100644 tests/arrays-iter.cc diff --git a/include/ebcl/Arrays.hh b/include/ebcl/Arrays.hh index 1d381f9..0c5c524 100644 --- a/include/ebcl/Arrays.hh +++ b/include/ebcl/Arrays.hh @@ -22,6 +22,62 @@ class T_Array final return std::max< uint32_t >( 1 , 4096 / sizeof( T ) ); } + template< ptrdiff_t Direction > + class T_Iterator_ final : public std::iterator< + std::random_access_iterator_tag , T > + { + private: + T_Array< T >* array_; + ptrdiff_t pos_; + + public: + T_Iterator_( T_Array< T >& array , + const ptrdiff_t pos ) noexcept; + + M_ITER_CONS_DEF( T_Iterator_ ); + M_ITER_CONS_COPY( T_Iterator_ ); + M_ITER_SWAP( T_Iterator_ , T_Array ); + M_ITER_CMP_ALL( T_Iterator_ ); + M_ITER_DEREF_RANDOM( T& , T* ); + M_ITER_OPS_RANDOM( T_Iterator_ ); + + bool valid( ) const noexcept; + T_Array< T >* target( ) const noexcept; + ptrdiff_t pos( ) const noexcept; + }; + using T_Iterator = T_Iterator_< 1 >; + using T_ReverseIterator = T_Iterator_< -1 >; + + template< ptrdiff_t Direction > + class T_ConstIterator_ : public std::iterator< + std::random_access_iterator_tag , T > + { + private: + T_Array< T > const* array_; + ptrdiff_t pos_; + + public: + T_ConstIterator_( T_Array< T > const& array , + const ptrdiff_t pos ) noexcept; + + T_ConstIterator_( typename T_Array< T >::T_Iterator const& iterator ) noexcept; + T_ConstIterator_& operator =( + typename T_Array< T >::T_Iterator const& iterator ) noexcept; + + M_ITER_CONS_DEF( T_ConstIterator_ ); + M_ITER_CONS_COPY( T_ConstIterator_ ); + M_ITER_SWAP( T_ConstIterator_ , T_Array ); + M_ITER_CMP_ALL( T_ConstIterator_ ); + M_ITER_DEREF_RANDOM( T const& , T const* ); + M_ITER_OPS_RANDOM( T_ConstIterator_ ); + + bool valid( ) const noexcept; + T_Array< T >* target( ) const noexcept; + ptrdiff_t pos( ) const noexcept; + }; + using T_ConstIterator = T_ConstIterator_< 1 >; + using T_ConstReverseIterator = T_ConstIterator_< -1 >; + private: typedef T_Array< T > MyType_; @@ -121,6 +177,27 @@ class T_Array final MyType_ moveRange( uint32_t first , uint32_t last = UINT32_MAX ) noexcept; + + // --------------------------------------------------------------------- + // Iterators for C++ for loops + + T_ConstIterator begin( ) const noexcept; + T_ConstIterator end( ) const noexcept; + + T_ConstReverseIterator rbegin( ) const noexcept; + T_ConstReverseIterator rend( ) const noexcept; + + T_ConstIterator cbegin( ) const noexcept; + T_ConstIterator cend( ) const noexcept; + + T_ConstReverseIterator crbegin( ) const noexcept; + T_ConstReverseIterator crend( ) const noexcept; + + T_Iterator begin( ) noexcept; + T_Iterator end( ) noexcept; + + T_ReverseIterator rbegin( ) noexcept; + T_ReverseIterator rend( ) noexcept; }; // Instantiate some common types directly diff --git a/include/ebcl/Utilities.hh b/include/ebcl/Utilities.hh index 54c497a..7234056 100644 --- a/include/ebcl/Utilities.hh +++ b/include/ebcl/Utilities.hh @@ -234,6 +234,67 @@ template< typename T > #define M_DEFINE_SWAP( Type ) \ void swap( Type& lhs , Type& rhs ) noexcept +/*----------------------------------------------------------------------------*/ +/* Helper macros for iterator declarations */ + +// Default constructor (forward, bidir, random) +#define M_ITER_CONS_DEF( NAME ) \ + NAME( ) noexcept + +// Copy constructor/assignment (all types) +#define M_ITER_CONS_COPY( NAME ) \ + NAME( NAME const& other ) noexcept; \ + NAME& operator =( NAME const& other ) noexcept + +// Move constructor (not necessary) +#define M_ITER_CONS_MOVE( NAME ) \ + NAME( NAME&& other ) noexcept; \ + NAME& operator =( NAME&& other ) noexcept + +// Swap (all types) +#define M_ITER_SWAP( NAME , CONTAINER ) \ + template< typename SwapType_ > \ + friend void swap( typename CONTAINER< SwapType_ >::NAME& lhs , \ + typename CONTAINER< SwapType_ >::NAME& rhs \ + ) noexcept + +// Equality/inequality (all types) +#define M_ITER_CMP_EQ( NAME ) \ + bool operator ==( NAME const& other ) const noexcept; \ + bool operator !=( NAME const& other ) const noexcept + +// Equality/inequality (all types) +#define M_ITER_CMP_ALL( NAME ) \ + M_ITER_CMP_EQ( NAME ); \ + bool operator >( NAME const& other ) const noexcept; \ + bool operator >=( NAME const& other ) const noexcept; \ + bool operator <( NAME const& other ) const noexcept; \ + bool operator <=( NAME const& other ) const noexcept + +// Dereference +#define M_ITER_DEREF( REF , PTR ) \ + REF operator* ( ) const noexcept; \ + PTR operator-> ( ) const noexcept +#define M_ITER_DEREF_RANDOM( REF , PTR ) \ + M_ITER_DEREF( REF , PTR ); \ + REF operator[] ( const ptrdiff_t offset ) const noexcept + +// Operations (increment, etc) +#define M_ITER_OPS_FWD( NAME ) \ + NAME& operator++ ( ) noexcept; \ + NAME operator++ (int) noexcept +#define M_ITER_OPS_BIDIR( NAME ) \ + M_ITER_OPS_FWD( NAME ); \ + NAME& operator-- ( ) noexcept; \ + NAME operator-- (int) noexcept +#define M_ITER_OPS_RANDOM( NAME ) \ + M_ITER_OPS_BIDIR( NAME ); \ + NAME operator +( const ptrdiff_t value ) const noexcept; \ + NAME operator -( const ptrdiff_t value ) const noexcept; \ + ptrdiff_t operator -( NAME const& other ) const noexcept; \ + NAME& operator +=( const ptrdiff_t value ) noexcept; \ + NAME& operator -=( const ptrdiff_t value ) noexcept + /*= ENDIAN DETECTION =========================================================*/ /* diff --git a/include/ebcl/inline/Arrays.hh b/include/ebcl/inline/Arrays.hh index 11a57b4..ea1bb86 100644 --- a/include/ebcl/inline/Arrays.hh +++ b/include/ebcl/inline/Arrays.hh @@ -463,6 +463,489 @@ inline T_Array< T > T_Array< T >::moveRange( return output; } +/*----------------------------------------------------------------------------*/ + +#define M_ITER_( NAME ) typename T_Array< T >::T_ ##NAME + +template< typename T > +inline M_ITER_( ConstIterator ) T_Array< T >::begin( ) const noexcept +{ + return T_ConstIterator( *this , 0 ); +} + +template< typename T > +inline M_ITER_( ConstIterator ) T_Array< T >::end( ) const noexcept +{ + return T_ConstIterator( *this , size_ ); +} + +template< typename T > +inline M_ITER_( Iterator ) T_Array< T >::begin( ) noexcept +{ + return T_Iterator( *this , 0 ); +} + +template< typename T > +inline M_ITER_( Iterator ) T_Array< T >::end( ) noexcept +{ + return T_Iterator( *this , size_ ); +} + +template< typename T > +inline M_ITER_( ConstReverseIterator ) T_Array< T >::rbegin( ) const noexcept +{ + return T_ConstReverseIterator( *this , 0 ); +} + +template< typename T > +inline M_ITER_( ConstReverseIterator ) T_Array< T >::rend( ) const noexcept +{ + return T_ConstReverseIterator( *this , size_ ); +} + +template< typename T > +inline M_ITER_( ReverseIterator ) T_Array< T >::rbegin( ) noexcept +{ + return T_ReverseIterator( *this , size_ - 1 ); +} + +template< typename T > +inline M_ITER_( ReverseIterator ) T_Array< T >::rend( ) noexcept +{ + return T_ReverseIterator( *this , -1 ); +} + +template< typename T > +inline M_ITER_( ConstIterator ) T_Array< T >::cbegin( ) const noexcept +{ + return T_ConstIterator( *this , 0 ); +} + +template< typename T > +inline M_ITER_( ConstIterator ) T_Array< T >::cend( ) const noexcept +{ + return T_ConstIterator( *this , size_ ); +} + +template< typename T > +inline M_ITER_( ConstReverseIterator ) T_Array< T >::crbegin( ) const noexcept +{ + return T_ConstReverseIterator( *this , 0 ); +} + +template< typename T > +inline M_ITER_( ConstReverseIterator ) T_Array< T >::crend( ) const noexcept +{ + return T_ConstReverseIterator( *this , size_ ); +} + +#undef M_ITER_ + + +/*= T_Array::T_Iterator_ =====================================================*/ + +#define M_HDR_ template< typename T > template< ptrdiff_t D > +#define M_CNAME_ T_Array< T >::T_Iterator_< D > +#define M_CNAME_T_ typename T_Array< T >::template T_Iterator_< D > + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline M_CNAME_::T_Iterator_( + T_Array< T >& array , + const ptrdiff_t pos ) noexcept + : array_( &array ) , pos_( pos ) +{ } + +M_HDR_ inline M_CNAME_::T_Iterator_( ) noexcept + : array_( nullptr ) , pos_( 0 ) +{ } + +M_HDR_ inline M_CNAME_::T_Iterator_( + T_Iterator_ const& other ) noexcept + : array_( other.array_ ) , pos_( other.pos_ ) +{ } + +M_HDR_ inline M_CNAME_T_& M_CNAME_::operator=( + T_Iterator_ const& other ) noexcept +{ + array_ = other.array_; + pos_ = other.pos_; + return *this; +} + +/*----------------------------------------------------------------------------*/ + +template< typename T , ptrdiff_t D> +inline void swap( + M_CNAME_T_& lhs , + M_CNAME_T_& rhs ) noexcept +{ + std::swap( lhs.array_ , rhs.array_ ); + std::swap( lhs.pos_ , rhs.pos_ ); +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline bool M_CNAME_::operator==( + T_Iterator_ const& other ) const noexcept +{ + return array_ == other.array_ && pos_ == other.pos_; +} + +M_HDR_ inline bool M_CNAME_::operator!=( + T_Iterator_ const& other ) const noexcept +{ + return array_ != other.array_ || pos_ != other.pos_; +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline bool M_CNAME_::operator <( + T_Iterator_ const& other ) const noexcept +{ + return array_ == other.array_ && pos_ < other.pos_; +} + +M_HDR_ inline bool M_CNAME_::operator<=( + T_Iterator_ const& other ) const noexcept +{ + return array_ == other.array_ && pos_ <= other.pos_; +} + +M_HDR_ inline bool M_CNAME_::operator >( + T_Iterator_ const& other ) const noexcept +{ + return array_ == other.array_ && pos_ > other.pos_; +} + +M_HDR_ inline bool M_CNAME_::operator>=( + T_Iterator_ const& other ) const noexcept +{ + return array_ == other.array_ && pos_ >= other.pos_; +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline T& M_CNAME_::operator*( ) const noexcept +{ + assert( valid( ) ); + return (*array_)[ pos_ ]; +} + +M_HDR_ inline T* M_CNAME_::operator->( ) const noexcept +{ + assert( valid( ) ); + return &((*array_)[ pos_ ]); +} + +M_HDR_ inline T& M_CNAME_::operator[]( + const ptrdiff_t pos ) const noexcept +{ + const auto idx( pos + pos_ ); + assert( array_ && idx >= 0 && idx < array_->size( ) ); + return (*array_)[ idx ]; +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline M_CNAME_T_& M_CNAME_::operator++ () noexcept +{ + assert( valid( ) ); + pos_ += D; + return *this; +} + +M_HDR_ inline M_CNAME_T_ M_CNAME_::operator++ (int) noexcept +{ + assert( valid( ) ); + auto copy( *this ); + pos_ += D; + return copy; +} + +M_HDR_ inline M_CNAME_T_& M_CNAME_::operator-- () noexcept +{ + assert( valid( ) ); + pos_ -= D; + return *this; +} + +M_HDR_ inline M_CNAME_T_ M_CNAME_::operator-- (int) noexcept +{ + assert( valid( ) ); + auto copy( *this ); + pos_ -= D; + return copy; +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline M_CNAME_T_ M_CNAME_::operator +( + const ptrdiff_t value ) const noexcept +{ + auto copy( *this ); + copy += value; + return copy; +} + +M_HDR_ inline M_CNAME_T_ M_CNAME_::operator -( + const ptrdiff_t value ) const noexcept +{ + auto copy( *this ); + copy -= value; + return copy; +} + +M_HDR_ inline ptrdiff_t M_CNAME_::operator -( + M_CNAME_T_ const& other ) const noexcept +{ + assert( array_ && array_ == other.array_ ); + return pos_ - other.pos_; +} + +M_HDR_ inline M_CNAME_T_& M_CNAME_::operator +=( + const ptrdiff_t value ) noexcept +{ + assert( valid( ) ); + pos_ = std::min( ptrdiff_t( array_->size( ) ) , + std::max( ptrdiff_t( -1 ) , pos_ + value * D ) ); + return *this; +} + +M_HDR_ inline M_CNAME_T_& M_CNAME_::operator -=( + const ptrdiff_t value ) noexcept +{ + assert( valid( ) ); + pos_ = std::min( ptrdiff_t( array_->size( ) ) , + std::max( ptrdiff_t( -1 ) , pos_ - value * D ) ); + return *this; +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline bool M_CNAME_::valid( ) const noexcept +{ + return array_ && pos_ >= 0 && pos_ < array_->size( ); +} + +M_HDR_ inline T_Array< T >* M_CNAME_::target( ) const noexcept +{ + return array_; +} + +M_HDR_ inline ptrdiff_t M_CNAME_::pos( ) const noexcept +{ + return pos_; +} + +/*----------------------------------------------------------------------------*/ + +#undef M_HDR_ +#undef M_CNAME_ +#undef M_CNAME_T_ + + +/*= T_Array::T_ConstIterator_ ================================================*/ + +#define M_HDR_ template< typename T > template< ptrdiff_t D > +#define M_CNAME_ T_Array< T >::T_ConstIterator_< D > +#define M_CNAME_T_ typename T_Array< T >::template T_ConstIterator_< D > + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline M_CNAME_::T_ConstIterator_( + T_Array< T > const& array , + const ptrdiff_t pos ) noexcept + : array_( &array ) , pos_( pos ) +{ } + +M_HDR_ inline M_CNAME_::T_ConstIterator_( ) noexcept + : array_( nullptr ) , pos_( 0 ) +{ } + +M_HDR_ inline M_CNAME_::T_ConstIterator_( + T_ConstIterator_ const& other ) noexcept + : array_( other.array_ ) , pos_( other.pos_ ) +{ } + +M_HDR_ inline M_CNAME_T_& M_CNAME_::operator=( + T_ConstIterator_ const& other ) noexcept +{ + array_ = other.array_; + pos_ = other.pos_; + return *this; +} + +/*----------------------------------------------------------------------------*/ + +template< typename T , ptrdiff_t D> +inline void swap( + M_CNAME_T_& lhs , + M_CNAME_T_& rhs ) noexcept +{ + std::swap( lhs.array_ , rhs.array_ ); + std::swap( lhs.pos_ , rhs.pos_ ); +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline bool M_CNAME_::operator==( + T_ConstIterator_ const& other ) const noexcept +{ + return array_ == other.array_ && pos_ == other.pos_; +} + +M_HDR_ inline bool M_CNAME_::operator!=( + T_ConstIterator_ const& other ) const noexcept +{ + return array_ != other.array_ || pos_ != other.pos_; +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline bool M_CNAME_::operator <( + T_ConstIterator_ const& other ) const noexcept +{ + return array_ == other.array_ && pos_ < other.pos_; +} + +M_HDR_ inline bool M_CNAME_::operator<=( + T_ConstIterator_ const& other ) const noexcept +{ + return array_ == other.array_ && pos_ <= other.pos_; +} + +M_HDR_ inline bool M_CNAME_::operator >( + T_ConstIterator_ const& other ) const noexcept +{ + return array_ == other.array_ && pos_ > other.pos_; +} + +M_HDR_ inline bool M_CNAME_::operator>=( + T_ConstIterator_ const& other ) const noexcept +{ + return array_ == other.array_ && pos_ >= other.pos_; +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline T const& M_CNAME_::operator*( ) const noexcept +{ + assert( valid( ) ); + return (*array_)[ pos_ ]; +} + +M_HDR_ inline T const* M_CNAME_::operator->( ) const noexcept +{ + assert( valid( ) ); + return &((*array_)[ pos_ ]); +} + +M_HDR_ inline T const& M_CNAME_::operator[]( + const ptrdiff_t pos ) const noexcept +{ + const auto idx( pos + pos_ ); + assert( array_ && idx >= 0 && idx < array_->size( ) ); + return (*array_)[ idx ]; +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline M_CNAME_T_& M_CNAME_::operator++ () noexcept +{ + assert( valid( ) ); + pos_ += D; + return *this; +} + +M_HDR_ inline M_CNAME_T_ M_CNAME_::operator++ (int) noexcept +{ + assert( valid( ) ); + auto copy( *this ); + pos_ += D; + return copy; +} + +M_HDR_ inline M_CNAME_T_& M_CNAME_::operator-- () noexcept +{ + assert( valid( ) ); + pos_ -= D; + return *this; +} + +M_HDR_ inline M_CNAME_T_ M_CNAME_::operator-- (int) noexcept +{ + assert( valid( ) ); + auto copy( *this ); + pos_ -= D; + return copy; +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline M_CNAME_T_ M_CNAME_::operator +( + const ptrdiff_t value ) const noexcept +{ + auto copy( *this ); + copy += value; + return copy; +} + +M_HDR_ inline M_CNAME_T_ M_CNAME_::operator -( + const ptrdiff_t value ) const noexcept +{ + auto copy( *this ); + copy -= value; + return copy; +} + +M_HDR_ inline ptrdiff_t M_CNAME_::operator -( + M_CNAME_T_ const& other ) const noexcept +{ + assert( array_ && array_ == other.array_ ); + return pos_ - other.pos_; +} + +M_HDR_ inline M_CNAME_T_& M_CNAME_::operator +=( + const ptrdiff_t value ) noexcept +{ + assert( valid( ) ); + pos_ = std::min( ptrdiff_t( array_->size( ) ) , + std::max( ptrdiff_t( -1 ) , pos_ + value * D ) ); + return *this; +} + +M_HDR_ inline M_CNAME_T_& M_CNAME_::operator -=( + const ptrdiff_t value ) noexcept +{ + assert( valid( ) ); + pos_ = std::min( ptrdiff_t( array_->size( ) ) , + std::max( ptrdiff_t( -1 ) , pos_ - value * D ) ); + return *this; +} + +/*----------------------------------------------------------------------------*/ + +M_HDR_ inline bool M_CNAME_::valid( ) const noexcept +{ + return array_ && pos_ >= 0 && pos_ < array_->size( ); +} + +M_HDR_ inline T_Array< T >* M_CNAME_::target( ) const noexcept +{ + return array_; +} + +M_HDR_ inline ptrdiff_t M_CNAME_::pos( ) const noexcept +{ + return pos_; +} + +/*----------------------------------------------------------------------------*/ + +#undef M_HDR_ +#undef M_CNAME_ +#undef M_CNAME_T_ /*= T_StaticArray ============================================================*/ diff --git a/tests/arrays-iter.cc b/tests/arrays-iter.cc new file mode 100644 index 0000000..aa97e36 --- /dev/null +++ b/tests/arrays-iter.cc @@ -0,0 +1,822 @@ +#include +#include +using namespace ebcl; + + +class ArraysIterTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( ArraysIterTest ); + CPPUNIT_TEST( testConstructDefault ); + CPPUNIT_TEST( testConstructFromArray ); + CPPUNIT_TEST( testCopyCons ); + CPPUNIT_TEST( testCopyAss ); + CPPUNIT_TEST( testSwap ); + + CPPUNIT_TEST( testArrayIterator ); + CPPUNIT_TEST( testArrayReverse ); + + CPPUNIT_TEST( testDerefStar ); + CPPUNIT_TEST( testDerefArrow ); + CPPUNIT_TEST( testDerefOffset ); + + CPPUNIT_TEST( testCmpEq ); + CPPUNIT_TEST( testCmpNe ); + CPPUNIT_TEST( testCmpLt ); + CPPUNIT_TEST( testCmpLe ); + CPPUNIT_TEST( testCmpGt ); + CPPUNIT_TEST( testCmpGe ); + + CPPUNIT_TEST( testPreIncrement ); + CPPUNIT_TEST( testPostIncrement ); + CPPUNIT_TEST( testPreDecrement ); + CPPUNIT_TEST( testPostDecrement ); + + CPPUNIT_TEST( testPreIncrementReverse ); + CPPUNIT_TEST( testPostIncrementReverse ); + CPPUNIT_TEST( testPreDecrementReverse ); + CPPUNIT_TEST( testPostDecrementReverse ); + + CPPUNIT_TEST( testAddTo ); + CPPUNIT_TEST( testAddToReverse ); + CPPUNIT_TEST( testSubTo ); + CPPUNIT_TEST( testSubToReverse ); + + CPPUNIT_TEST( testAdd ); + CPPUNIT_TEST( testAddReverse ); + CPPUNIT_TEST( testSub ); + CPPUNIT_TEST( testSubReverse ); + CPPUNIT_TEST( testDifference ); + CPPUNIT_TEST_SUITE_END( ); + + public: + void testConstructDefault( ); + void testConstructFromArray( ); + void testCopyCons( ); + void testCopyAss( ); + void testSwap( ); + + void testArrayIterator( ); + void testArrayReverse( ); + + void testDerefStar( ); + void testDerefArrow( ); + void testDerefOffset( ); + + void testCmpEq( ); + void testCmpNe( ); + void testCmpLt( ); + void testCmpLe( ); + void testCmpGt( ); + void testCmpGe( ); + + void testPreIncrement( ); + void testPostIncrement( ); + void testPreDecrement( ); + void testPostDecrement( ); + + void testPreIncrementReverse( ); + void testPostIncrementReverse( ); + void testPreDecrementReverse( ); + void testPostDecrementReverse( ); + + void testAddTo( ); + void testAddToReverse( ); + void testSubTo( ); + void testSubToReverse( ); + + void testAdd( ); + void testAddReverse( ); + void testSub( ); + void testSubReverse( ); + void testDifference( ); +}; +CPPUNIT_TEST_SUITE_REGISTRATION( ArraysIterTest ); + +using T_Test_ = T_Array< int >; + +/*----------------------------------------------------------------------------*/ + +void ArraysIterTest::testConstructDefault( ) +{ + T_Test_::T_Iterator iter; + CPPUNIT_ASSERT( !iter.valid( ) ); +} + +void ArraysIterTest::testConstructFromArray( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_Iterator iter( x , 1 ); + CPPUNIT_ASSERT( iter.valid( ) ); + CPPUNIT_ASSERT( iter.target( ) == &x ); + CPPUNIT_ASSERT( iter.pos( ) == 1 ); +} + +void ArraysIterTest::testCopyCons( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_Iterator iter( x , 1 ); + T_Test_::T_Iterator iter2( iter ); + iter = {}; + + CPPUNIT_ASSERT( iter2.valid( ) ); + CPPUNIT_ASSERT( iter2.target( ) == &x ); + CPPUNIT_ASSERT( iter2.pos( ) == 1 ); +} + +void ArraysIterTest::testCopyAss( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_Iterator iter( x , 1 ); + T_Test_::T_Iterator iter2; + iter2 = iter; + iter = {}; + + CPPUNIT_ASSERT( iter2.valid( ) ); + CPPUNIT_ASSERT( iter2.target( ) == &x ); + CPPUNIT_ASSERT( iter2.pos( ) == 1 ); +} + +void ArraysIterTest::testSwap( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_Iterator iter( x , 1 ); + T_Test_::T_Iterator iter2; + swap( iter , iter2 ); + + CPPUNIT_ASSERT( !iter.valid( ) ); + CPPUNIT_ASSERT( iter.target( ) == nullptr ); + CPPUNIT_ASSERT( iter.pos( ) == 0 ); + + CPPUNIT_ASSERT( iter2.valid( ) ); + CPPUNIT_ASSERT( iter2.target( ) == &x ); + CPPUNIT_ASSERT( iter2.pos( ) == 1 ); +} + +/*----------------------------------------------------------------------------*/ + +void ArraysIterTest::testArrayIterator( ) +{ + T_Test_ x; + x.add( 1 ); + + T_Test_::T_Iterator it1( x.begin( ) ); + T_Test_::T_Iterator it2( x.end( ) ); + + CPPUNIT_ASSERT( &x == it1.target( ) ); + CPPUNIT_ASSERT( &x == it2.target( ) ); + + CPPUNIT_ASSERT( 0 == it1.pos( ) ); + CPPUNIT_ASSERT( x.size( ) == it2.pos( ) ); +} + +void ArraysIterTest::testArrayReverse( ) +{ + T_Test_ x; + x.add( 1 ); + + T_Test_::T_ReverseIterator it1( x.rbegin( ) ); + T_Test_::T_ReverseIterator it2( x.rend( ) ); + + CPPUNIT_ASSERT( &x == it1.target( ) ); + CPPUNIT_ASSERT( &x == it2.target( ) ); + + CPPUNIT_ASSERT( x.size( ) - 1 == it1.pos( ) ); + CPPUNIT_ASSERT( -1 == it2.pos( ) ); +} + +/*----------------------------------------------------------------------------*/ + +void ArraysIterTest::testDerefStar( ) +{ + T_Test_ x; + x.add( 1 ); + + T_Test_::T_Iterator it( x , 0 ); + CPPUNIT_ASSERT_EQUAL( 1 , *it ); +} + +void ArraysIterTest::testDerefArrow( ) +{ + struct T_Obj_ { + int x; + T_Obj_( int x ) : x( x ) { } + int value( ) const noexcept { return x; } + }; + using T_Test_ = T_Array< T_Obj_ >; + + T_Test_ t; + t.add( 42 ); + + T_Test_::T_Iterator it( t , 0 ); + CPPUNIT_ASSERT_EQUAL( 42 , it->value( ) ); +} + +void ArraysIterTest::testDerefOffset( ) +{ + T_Test_ x; + x.add( 0 ); + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_Iterator it( x , 1 ); + CPPUNIT_ASSERT_EQUAL( 0 , it[ -1 ] ); + CPPUNIT_ASSERT_EQUAL( 1 , it[ 0 ] ); + CPPUNIT_ASSERT_EQUAL( 2 , it[ 1 ] ); +} + +/*----------------------------------------------------------------------------*/ + +void ArraysIterTest::testCmpEq( ) +{ + T_Test_ x , x2; + x.add( 1 ); + x.add( 2 ); + x2.add( 3 ); + + T_Test_::T_Iterator iter1( x , 0 ) , + iter2( x , 0 ) , + iter3 , + iter4( x , 1 ) , + iter5 , + iter6( x2 , 0 ); + + CPPUNIT_ASSERT( iter1 == iter1 ); + CPPUNIT_ASSERT( iter1 == iter2 ); + CPPUNIT_ASSERT( !( iter1 == iter3 ) ); + CPPUNIT_ASSERT( !( iter1 == iter4 ) ); + CPPUNIT_ASSERT( !( iter1 == iter5 ) ); + CPPUNIT_ASSERT( !( iter1 == iter6 ) ); + + CPPUNIT_ASSERT( iter2 == iter1 ); + CPPUNIT_ASSERT( iter2 == iter2 ); + CPPUNIT_ASSERT( !( iter2 == iter3 ) ); + CPPUNIT_ASSERT( !( iter2 == iter4 ) ); + CPPUNIT_ASSERT( !( iter2 == iter5 ) ); + CPPUNIT_ASSERT( !( iter2 == iter6 ) ); + + CPPUNIT_ASSERT( !( iter3 == iter1 ) ); + CPPUNIT_ASSERT( !( iter3 == iter2 ) ); + CPPUNIT_ASSERT( iter3 == iter3 ); + CPPUNIT_ASSERT( !( iter3 == iter4 ) ); + CPPUNIT_ASSERT( iter3 == iter5 ); + CPPUNIT_ASSERT( !( iter3 == iter6 ) ); + + CPPUNIT_ASSERT( !( iter4 == iter1 ) ); + CPPUNIT_ASSERT( !( iter4 == iter2 ) ); + CPPUNIT_ASSERT( !( iter4 == iter3 ) ); + CPPUNIT_ASSERT( iter4 == iter4 ); + CPPUNIT_ASSERT( !( iter4 == iter5 ) ); + CPPUNIT_ASSERT( !( iter4 == iter6 ) ); + + CPPUNIT_ASSERT( !( iter5 == iter1 ) ); + CPPUNIT_ASSERT( !( iter5 == iter2 ) ); + CPPUNIT_ASSERT( iter5 == iter3 ); + CPPUNIT_ASSERT( !( iter5 == iter4 ) ); + CPPUNIT_ASSERT( iter5 == iter5 ); + CPPUNIT_ASSERT( !( iter5 == iter6 ) ); + + CPPUNIT_ASSERT( !( iter6 == iter1 ) ); + CPPUNIT_ASSERT( !( iter6 == iter2 ) ); + CPPUNIT_ASSERT( !( iter6 == iter3 ) ); + CPPUNIT_ASSERT( !( iter6 == iter4 ) ); + CPPUNIT_ASSERT( !( iter6 == iter5 ) ); + CPPUNIT_ASSERT( iter6 == iter6 ); +} + +void ArraysIterTest::testCmpNe( ) +{ + T_Test_ x , x2; + x.add( 1 ); + x.add( 2 ); + x2.add( 3 ); + + T_Test_::T_Iterator iter1( x , 0 ) , + iter2( x , 0 ) , + iter3 , + iter4( x , 1 ) , + iter5 , + iter6( x2 , 0 ); + + CPPUNIT_ASSERT( !( iter1 != iter1 ) ); + CPPUNIT_ASSERT( !( iter1 != iter2 ) ); + CPPUNIT_ASSERT( iter1 != iter3 ); + CPPUNIT_ASSERT( iter1 != iter4 ); + CPPUNIT_ASSERT( iter1 != iter5 ); + CPPUNIT_ASSERT( iter1 != iter6 ); + + CPPUNIT_ASSERT( !( iter2 != iter1 ) ); + CPPUNIT_ASSERT( !( iter2 != iter2 ) ); + CPPUNIT_ASSERT( iter2 != iter3 ); + CPPUNIT_ASSERT( iter2 != iter4 ); + CPPUNIT_ASSERT( iter2 != iter5 ); + CPPUNIT_ASSERT( iter2 != iter6 ); + + CPPUNIT_ASSERT( iter3 != iter1 ); + CPPUNIT_ASSERT( iter3 != iter2 ); + CPPUNIT_ASSERT( !( iter3 != iter3 ) ); + CPPUNIT_ASSERT( iter3 != iter4 ); + CPPUNIT_ASSERT( !( iter3 != iter5 ) ); + CPPUNIT_ASSERT( iter3 != iter6 ); + + CPPUNIT_ASSERT( iter4 != iter1 ); + CPPUNIT_ASSERT( iter4 != iter2 ); + CPPUNIT_ASSERT( iter4 != iter3 ); + CPPUNIT_ASSERT( !( iter4 != iter4 ) ); + CPPUNIT_ASSERT( iter4 != iter5 ); + CPPUNIT_ASSERT( iter4 != iter6 ); + + CPPUNIT_ASSERT( iter5 != iter1 ); + CPPUNIT_ASSERT( iter5 != iter2 ); + CPPUNIT_ASSERT( !( iter5 != iter3 ) ); + CPPUNIT_ASSERT( iter5 != iter4 ); + CPPUNIT_ASSERT( !( iter5 != iter5 ) ); + CPPUNIT_ASSERT( iter5 != iter6 ); + + CPPUNIT_ASSERT( iter6 != iter1 ); + CPPUNIT_ASSERT( iter6 != iter2 ); + CPPUNIT_ASSERT( iter6 != iter3 ); + CPPUNIT_ASSERT( iter6 != iter4 ); + CPPUNIT_ASSERT( iter6 != iter5 ); + CPPUNIT_ASSERT( !( iter6 != iter6 ) ); +} + +void ArraysIterTest::testCmpLt( ) +{ + T_Test_ x , x2; + x.add( 1 ); + x.add( 2 ); + x2.add( 3 ); + + T_Test_::T_Iterator iter1( x , 0 ) , + iter2( x , 0 ) , + iter3 , + iter4( x , 1 ) , + iter5 , + iter6( x2 , 0 ); + + CPPUNIT_ASSERT( !( iter1 < iter1 ) ); + CPPUNIT_ASSERT( !( iter1 < iter2 ) ); + CPPUNIT_ASSERT( !( iter1 < iter3 ) ); + CPPUNIT_ASSERT( iter1 < iter4 ); + CPPUNIT_ASSERT( !( iter1 < iter5 ) ); + CPPUNIT_ASSERT( !( iter1 < iter6 ) ); + + CPPUNIT_ASSERT( !( iter2 < iter1 ) ); + CPPUNIT_ASSERT( !( iter2 < iter2 ) ); + CPPUNIT_ASSERT( !( iter2 < iter3 ) ); + CPPUNIT_ASSERT( iter2 < iter4 ); + CPPUNIT_ASSERT( !( iter2 < iter5 ) ); + CPPUNIT_ASSERT( !( iter2 < iter6 ) ); + + CPPUNIT_ASSERT( !( iter3 < iter1 ) ); + CPPUNIT_ASSERT( !( iter3 < iter2 ) ); + CPPUNIT_ASSERT( !( iter3 < iter3 ) ); + CPPUNIT_ASSERT( !( iter3 < iter4 ) ); + CPPUNIT_ASSERT( !( iter3 < iter5 ) ); + CPPUNIT_ASSERT( !( iter3 < iter6 ) ); + + CPPUNIT_ASSERT( !( iter4 < iter1 ) ); + CPPUNIT_ASSERT( !( iter4 < iter2 ) ); + CPPUNIT_ASSERT( !( iter4 < iter3 ) ); + CPPUNIT_ASSERT( !( iter4 < iter4 ) ); + CPPUNIT_ASSERT( !( iter4 < iter5 ) ); + CPPUNIT_ASSERT( !( iter4 < iter6 ) ); + + CPPUNIT_ASSERT( !( iter5 < iter1 ) ); + CPPUNIT_ASSERT( !( iter5 < iter2 ) ); + CPPUNIT_ASSERT( !( iter5 < iter3 ) ); + CPPUNIT_ASSERT( !( iter5 < iter4 ) ); + CPPUNIT_ASSERT( !( iter5 < iter5 ) ); + CPPUNIT_ASSERT( !( iter5 < iter6 ) ); + + CPPUNIT_ASSERT( !( iter6 < iter1 ) ); + CPPUNIT_ASSERT( !( iter6 < iter2 ) ); + CPPUNIT_ASSERT( !( iter6 < iter3 ) ); + CPPUNIT_ASSERT( !( iter6 < iter4 ) ); + CPPUNIT_ASSERT( !( iter6 < iter5 ) ); + CPPUNIT_ASSERT( !( iter6 < iter6 ) ); +} + +void ArraysIterTest::testCmpLe( ) +{ + T_Test_ x , x2; + x.add( 1 ); + x.add( 2 ); + x2.add( 3 ); + + T_Test_::T_Iterator iter1( x , 0 ) , + iter2( x , 0 ) , + iter3 , + iter4( x , 1 ) , + iter5 , + iter6( x2 , 0 ); + + CPPUNIT_ASSERT( iter1 <= iter1 ); + CPPUNIT_ASSERT( iter1 <= iter2 ); + CPPUNIT_ASSERT( !( iter1 <= iter3 ) ); + CPPUNIT_ASSERT( iter1 <= iter4 ); + CPPUNIT_ASSERT( !( iter1 <= iter5 ) ); + CPPUNIT_ASSERT( !( iter1 <= iter6 ) ); + + CPPUNIT_ASSERT( iter2 <= iter1 ); + CPPUNIT_ASSERT( iter2 <= iter2 ); + CPPUNIT_ASSERT( !( iter2 <= iter3 ) ); + CPPUNIT_ASSERT( iter2 <= iter4 ); + CPPUNIT_ASSERT( !( iter2 <= iter5 ) ); + CPPUNIT_ASSERT( !( iter2 <= iter6 ) ); + + CPPUNIT_ASSERT( !( iter3 <= iter1 ) ); + CPPUNIT_ASSERT( !( iter3 <= iter2 ) ); + CPPUNIT_ASSERT( iter3 <= iter3 ); + CPPUNIT_ASSERT( !( iter3 <= iter4 ) ); + CPPUNIT_ASSERT( iter3 <= iter5 ); + CPPUNIT_ASSERT( !( iter3 <= iter6 ) ); + + CPPUNIT_ASSERT( !( iter4 <= iter1 ) ); + CPPUNIT_ASSERT( !( iter4 <= iter2 ) ); + CPPUNIT_ASSERT( !( iter4 <= iter3 ) ); + CPPUNIT_ASSERT( iter4 <= iter4 ); + CPPUNIT_ASSERT( !( iter4 <= iter5 ) ); + CPPUNIT_ASSERT( !( iter4 <= iter6 ) ); + + CPPUNIT_ASSERT( !( iter5 <= iter1 ) ); + CPPUNIT_ASSERT( !( iter5 <= iter2 ) ); + CPPUNIT_ASSERT( iter5 <= iter3 ); + CPPUNIT_ASSERT( !( iter5 <= iter4 ) ); + CPPUNIT_ASSERT( iter5 <= iter5 ); + CPPUNIT_ASSERT( !( iter5 <= iter6 ) ); + + CPPUNIT_ASSERT( !( iter6 <= iter1 ) ); + CPPUNIT_ASSERT( !( iter6 <= iter2 ) ); + CPPUNIT_ASSERT( !( iter6 <= iter3 ) ); + CPPUNIT_ASSERT( !( iter6 <= iter4 ) ); + CPPUNIT_ASSERT( !( iter6 <= iter5 ) ); + CPPUNIT_ASSERT( iter6 <= iter6 ); +} + +void ArraysIterTest::testCmpGt( ) +{ + T_Test_ x , x2; + x.add( 1 ); + x.add( 2 ); + x2.add( 3 ); + + T_Test_::T_Iterator iter1( x , 0 ) , + iter2( x , 0 ) , + iter3 , + iter4( x , 1 ) , + iter5 , + iter6( x2 , 0 ); + + CPPUNIT_ASSERT( !( iter1 > iter1 ) ); + CPPUNIT_ASSERT( !( iter1 > iter2 ) ); + CPPUNIT_ASSERT( !( iter1 > iter3 ) ); + CPPUNIT_ASSERT( !( iter1 > iter4 ) ); + CPPUNIT_ASSERT( !( iter1 > iter5 ) ); + CPPUNIT_ASSERT( !( iter1 > iter6 ) ); + + CPPUNIT_ASSERT( !( iter2 > iter1 ) ); + CPPUNIT_ASSERT( !( iter2 > iter2 ) ); + CPPUNIT_ASSERT( !( iter2 > iter3 ) ); + CPPUNIT_ASSERT( !( iter2 > iter4 ) ); + CPPUNIT_ASSERT( !( iter2 > iter5 ) ); + CPPUNIT_ASSERT( !( iter2 > iter6 ) ); + + CPPUNIT_ASSERT( !( iter3 > iter1 ) ); + CPPUNIT_ASSERT( !( iter3 > iter2 ) ); + CPPUNIT_ASSERT( !( iter3 > iter3 ) ); + CPPUNIT_ASSERT( !( iter3 > iter4 ) ); + CPPUNIT_ASSERT( !( iter3 > iter5 ) ); + CPPUNIT_ASSERT( !( iter3 > iter6 ) ); + + CPPUNIT_ASSERT( iter4 > iter1 ); + CPPUNIT_ASSERT( iter4 > iter2 ); + CPPUNIT_ASSERT( !( iter4 > iter3 ) ); + CPPUNIT_ASSERT( !( iter4 > iter4 ) ); + CPPUNIT_ASSERT( !( iter4 > iter5 ) ); + CPPUNIT_ASSERT( !( iter4 > iter6 ) ); + + CPPUNIT_ASSERT( !( iter5 > iter1 ) ); + CPPUNIT_ASSERT( !( iter5 > iter2 ) ); + CPPUNIT_ASSERT( !( iter5 > iter3 ) ); + CPPUNIT_ASSERT( !( iter5 > iter4 ) ); + CPPUNIT_ASSERT( !( iter5 > iter5 ) ); + CPPUNIT_ASSERT( !( iter5 > iter6 ) ); + + CPPUNIT_ASSERT( !( iter6 > iter1 ) ); + CPPUNIT_ASSERT( !( iter6 > iter2 ) ); + CPPUNIT_ASSERT( !( iter6 > iter3 ) ); + CPPUNIT_ASSERT( !( iter6 > iter4 ) ); + CPPUNIT_ASSERT( !( iter6 > iter5 ) ); + CPPUNIT_ASSERT( !( iter6 > iter6 ) ); +} + +void ArraysIterTest::testCmpGe( ) +{ + T_Test_ x , x2; + x.add( 1 ); + x.add( 2 ); + x2.add( 3 ); + + T_Test_::T_Iterator iter1( x , 0 ) , + iter2( x , 0 ) , + iter3 , + iter4( x , 1 ) , + iter5 , + iter6( x2 , 0 ); + + CPPUNIT_ASSERT( iter1 >= iter1 ); + CPPUNIT_ASSERT( iter1 >= iter2 ); + CPPUNIT_ASSERT( !( iter1 >= iter3 ) ); + CPPUNIT_ASSERT( !( iter1 >= iter4 ) ); + CPPUNIT_ASSERT( !( iter1 >= iter5 ) ); + CPPUNIT_ASSERT( !( iter1 >= iter6 ) ); + + CPPUNIT_ASSERT( iter2 >= iter1 ); + CPPUNIT_ASSERT( iter2 >= iter2 ); + CPPUNIT_ASSERT( !( iter2 >= iter3 ) ); + CPPUNIT_ASSERT( !( iter2 >= iter4 ) ); + CPPUNIT_ASSERT( !( iter2 >= iter5 ) ); + CPPUNIT_ASSERT( !( iter2 >= iter6 ) ); + + CPPUNIT_ASSERT( !( iter3 >= iter1 ) ); + CPPUNIT_ASSERT( !( iter3 >= iter2 ) ); + CPPUNIT_ASSERT( iter3 >= iter3 ); + CPPUNIT_ASSERT( !( iter3 >= iter4 ) ); + CPPUNIT_ASSERT( iter3 >= iter5 ); + CPPUNIT_ASSERT( !( iter3 >= iter6 ) ); + + CPPUNIT_ASSERT( iter4 >= iter1 ); + CPPUNIT_ASSERT( iter4 >= iter2 ); + CPPUNIT_ASSERT( !( iter4 >= iter3 ) ); + CPPUNIT_ASSERT( iter4 >= iter4 ); + CPPUNIT_ASSERT( !( iter4 >= iter5 ) ); + CPPUNIT_ASSERT( !( iter4 >= iter6 ) ); + + CPPUNIT_ASSERT( !( iter5 >= iter1 ) ); + CPPUNIT_ASSERT( !( iter5 >= iter2 ) ); + CPPUNIT_ASSERT( iter5 >= iter3 ); + CPPUNIT_ASSERT( !( iter5 >= iter4 ) ); + CPPUNIT_ASSERT( iter5 >= iter5 ); + CPPUNIT_ASSERT( !( iter5 >= iter6 ) ); + + CPPUNIT_ASSERT( !( iter6 >= iter1 ) ); + CPPUNIT_ASSERT( !( iter6 >= iter2 ) ); + CPPUNIT_ASSERT( !( iter6 >= iter3 ) ); + CPPUNIT_ASSERT( !( iter6 >= iter4 ) ); + CPPUNIT_ASSERT( !( iter6 >= iter5 ) ); + CPPUNIT_ASSERT( iter6 >= iter6 ); +} + +/*----------------------------------------------------------------------------*/ + +void ArraysIterTest::testPreIncrement( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_Iterator iter1( x , 0 ); + T_Test_::T_Iterator iter2( ++iter1 ); + + CPPUNIT_ASSERT( iter1.pos( ) == 1 ); + CPPUNIT_ASSERT( iter2.pos( ) == 1 ); +} + +void ArraysIterTest::testPostIncrement( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_Iterator iter1( x , 0 ); + T_Test_::T_Iterator iter2( iter1++ ); + + CPPUNIT_ASSERT( iter1.pos( ) == 1 ); + CPPUNIT_ASSERT( iter2.pos( ) == 0 ); +} + +void ArraysIterTest::testPreDecrement( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_Iterator iter1( x , 1 ); + T_Test_::T_Iterator iter2( --iter1 ); + + CPPUNIT_ASSERT( iter1.pos( ) == 0 ); + CPPUNIT_ASSERT( iter2.pos( ) == 0 ); +} + +void ArraysIterTest::testPostDecrement( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_Iterator iter1( x , 1 ); + T_Test_::T_Iterator iter2( iter1-- ); + + CPPUNIT_ASSERT( iter1.pos( ) == 0 ); + CPPUNIT_ASSERT( iter2.pos( ) == 1 ); +} + +/*----------------------------------------------------------------------------*/ + +void ArraysIterTest::testPreIncrementReverse( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_ReverseIterator iter1( x , 1 ); + T_Test_::T_ReverseIterator iter2( ++iter1 ); + + CPPUNIT_ASSERT( iter1.pos( ) == 0 ); + CPPUNIT_ASSERT( iter2.pos( ) == 0 ); +} + +void ArraysIterTest::testPostIncrementReverse( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_ReverseIterator iter1( x , 1 ); + T_Test_::T_ReverseIterator iter2( iter1++ ); + + CPPUNIT_ASSERT( iter1.pos( ) == 0 ); + CPPUNIT_ASSERT( iter2.pos( ) == 1 ); +} + +void ArraysIterTest::testPreDecrementReverse( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_ReverseIterator iter1( x , 0 ); + T_Test_::T_ReverseIterator iter2( --iter1 ); + + CPPUNIT_ASSERT( iter1.pos( ) == 1 ); + CPPUNIT_ASSERT( iter2.pos( ) == 1 ); +} + +void ArraysIterTest::testPostDecrementReverse( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + + T_Test_::T_ReverseIterator iter1( x , 0 ); + T_Test_::T_ReverseIterator iter2( iter1-- ); + + CPPUNIT_ASSERT( iter1.pos( ) == 1 ); + CPPUNIT_ASSERT( iter2.pos( ) == 0 ); +} + +/*----------------------------------------------------------------------------*/ + +void ArraysIterTest::testAddTo( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + x.add( 3 ); + + T_Test_::T_Iterator it( x , 0 ); + it += 2; + CPPUNIT_ASSERT( it.pos( ) == 2 ); + it += 2; + CPPUNIT_ASSERT( it.pos( ) == 3 ); +} + +void ArraysIterTest::testAddToReverse( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + x.add( 3 ); + + T_Test_::T_ReverseIterator it( x.rbegin( ) ); + it += 2; + CPPUNIT_ASSERT( it.pos( ) == 0 ); + it += 2; + CPPUNIT_ASSERT( it.pos( ) == -1 ); +} + +void ArraysIterTest::testSubTo( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + x.add( 3 ); + + T_Test_::T_Iterator it( x , x.size( ) - 1 ); + it -= 2; + CPPUNIT_ASSERT( it.pos( ) == 0 ); + it -= 2; + CPPUNIT_ASSERT( it.pos( ) == -1 ); +} + +void ArraysIterTest::testSubToReverse( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + x.add( 3 ); + + T_Test_::T_ReverseIterator it( x , 0 ); + it -= 2; + CPPUNIT_ASSERT( it.pos( ) == 2 ); + it -= 2; + CPPUNIT_ASSERT( it.pos( ) == 3 ); +} + +/*----------------------------------------------------------------------------*/ + +void ArraysIterTest::testAdd( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + x.add( 3 ); + + T_Test_::T_Iterator it( x , 0 ); + auto it2( it + 4 ); + CPPUNIT_ASSERT( it.pos( ) == 0 ); + CPPUNIT_ASSERT( it2.target( ) == &x ); + CPPUNIT_ASSERT( it2.pos( ) == 3 ); + CPPUNIT_ASSERT( it2 == x.end( ) ); +} + +void ArraysIterTest::testAddReverse( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + x.add( 3 ); + + T_Test_::T_ReverseIterator it( x.rbegin( ) ); + auto it2( it + 4 ); + CPPUNIT_ASSERT( it.pos( ) == 2 ); + CPPUNIT_ASSERT( it2.target( ) == &x ); + CPPUNIT_ASSERT( it2.pos( ) == -1 ); + CPPUNIT_ASSERT( it2 == x.rend( ) ); +} + +void ArraysIterTest::testSub( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + x.add( 3 ); + + T_Test_::T_Iterator it( x , x.size( ) - 1 ); + auto it2( it - 4 ); + CPPUNIT_ASSERT( it.pos( ) == 2 ); + CPPUNIT_ASSERT( it2.target( ) == &x ); + CPPUNIT_ASSERT( it2.pos( ) == -1 ); +} + +void ArraysIterTest::testSubReverse( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + x.add( 3 ); + + T_Test_::T_ReverseIterator it( x , 0 ); + auto it2( it - 4 ); + CPPUNIT_ASSERT( it.pos( ) == 0 ); + CPPUNIT_ASSERT( it2.target( ) == &x ); + CPPUNIT_ASSERT( it2.pos( ) == 3 ); +} + +void ArraysIterTest::testDifference( ) +{ + T_Test_ x; + x.add( 1 ); + x.add( 2 ); + x.add( 3 ); + + T_Test_::T_Iterator it( x.begin( ) ); + T_Test_::T_Iterator it2( x.end( ) ); + const auto diff1( it2 - it ); + CPPUNIT_ASSERT( diff1 == x.size( ) ); + const auto diff2( it - it2 ); + CPPUNIT_ASSERT( -diff2 == x.size( ) ); +} diff --git a/tests/list.mk b/tests/list.mk index e6ddbc5..53fc34b 100644 --- a/tests/list.mk +++ b/tests/list.mk @@ -7,6 +7,7 @@ TESTS = \ ptr-weak \ arrays-basic \ arrays-objects \ + arrays-iter \ arrays-static-basic \ arrays-static-objects \ arrays-auto \