Skip to content

Commit

Permalink
Adding TransformView::Iterator test
Browse files Browse the repository at this point in the history
  • Loading branch information
whaeck committed Nov 7, 2023
1 parent 5015b1a commit 416d056
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 0 deletions.
1 change: 1 addition & 0 deletions cmake/unit_testing.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ add_subdirectory( src/tools/concepts/IsIterator/test )

add_subdirectory( src/tools/ranges/IteratorView/test )
add_subdirectory( src/tools/ranges/TransformView/test )
add_subdirectory( src/tools/ranges/TransformView/Iterator/test )
add_subdirectory( src/tools/ranges/make_view/test )
add_subdirectory( src/tools/ranges/make_transform_view/test )
36 changes: 36 additions & 0 deletions src/tools/ranges/TransformView/Iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,29 @@ class Iterator {

constexpr reference operator[]( difference_type i ) const {

static_assert(
concepts::IsRandomAccessIterator< Iterator >::value == true,
"the at() method can only be made available for random access iterators" );

return this->transform_( this->iter_[i] );
}

constexpr Iterator& operator+=( difference_type i ) {

static_assert(
concepts::IsRandomAccessIterator< Iterator >::value == true,
"the at() method can only be made available for random access iterators" );

this->iter_ += i;
return *this;
}

constexpr Iterator& operator-=( difference_type i ) {

static_assert(
concepts::IsRandomAccessIterator< Iterator >::value == true,
"the at() method can only be made available for random access iterators" );

this->iter_ -= i;
return *this;
}
Expand All @@ -62,33 +74,57 @@ class Iterator {

constexpr Iterator& operator--( void ) {

static_assert(
concepts::IsBidirectionalIterator< Iterator >::value == true,
"the at() method can only be made available for bidirectional iterators" );

--this->iter_;
return *this;
}

constexpr Iterator operator--( int ) {

static_assert(
concepts::IsBidirectionalIterator< Iterator >::value == true,
"the at() method can only be made available for bidirectional iterators" );

return Iterator( this->iter_--, this->transform_ );
}

friend constexpr Iterator operator+( difference_type i, Iterator iter ) {

static_assert(
concepts::IsRandomAccessIterator< Iterator >::value == true,
"the at() method can only be made available for random access iterators" );

return Iterator( iter.iter_ + i, iter.transform_ );
}

friend constexpr Iterator operator+( Iterator iter, difference_type i ) {

static_assert(
concepts::IsRandomAccessIterator< Iterator >::value == true,
"the at() method can only be made available for random access iterators" );

return Iterator( iter.iter_ + i, iter.transform_ );
}

friend constexpr Iterator operator-( Iterator iter, difference_type i ) {

static_assert(
concepts::IsRandomAccessIterator< Iterator >::value == true,
"the at() method can only be made available for random access iterators" );

return Iterator( iter.iter_ - i, iter.transform_ );
}

friend constexpr difference_type operator-( const Iterator& left,
const Iterator& right ) {

static_assert(
concepts::IsRandomAccessIterator< Iterator >::value == true,
"the at() method can only be made available for random access iterators" );

return left.iter_ - right.iter_;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_cpp_test( ranges.TransformView.Iterator Iterator.test.cpp )
203 changes: 203 additions & 0 deletions src/tools/ranges/TransformView/Iterator/test/Iterator.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
// include Catch2
#include <catch2/catch_test_macros.hpp>

// what we are testing
#include "tools/ranges/TransformView.hpp"

// other includes
#include <forward_list>
#include <list>
#include <vector>

// convenience typedefs
using namespace njoy::tools::ranges;

SCENARIO( "TransformView" ) {

auto transform = [] ( auto&& value ) { return value - 2; };

GIVEN( "a container with forward iterators" ) {

std::forward_list< int > values = { 0, 1, 2, 3, 4 };

WHEN( "when the container and the transformation are used" ) {

TransformView chunk( values, transform );

THEN( "the TransformView::Iterator functions as a normal forward iterator" ) {

auto begin = chunk.begin();
auto second = ++chunk.begin();
auto end = chunk.end();
auto iter = begin;

unsigned int counter = 0;
for ( auto iter = begin; iter != end; ++iter ) {

++counter;
}
CHECK( 5 == counter );

CHECK( 5 == std::distance( begin, end ) );
CHECK( begin != end );

CHECK( -2 == *begin );
CHECK( -1 == *second );

// the following should not compile: no random access iterator
// CHECK( -2 == begin[0] );
// CHECK( -1 == begin[1] );
// CHECK( 0 == begin[2] );
// CHECK( 1 == begin[3] );
// CHECK( 2 == begin[4] );

// the following should not compile: no random access iterator
// iter += 1;
// CHECK( second == iter );
// iter -= 1;
// CHECK( begin == iter );

CHECK( second == ++begin );
// the following should not compile: no bidirectional iterator
// CHECK( begin == --begin );

begin = chunk.begin();
iter = begin;
CHECK( begin == iter++ );
CHECK( second == iter );
// the following should not compile: no bidirectional iterator
// CHECK( second == iter-- );
// CHECK( begin == iter );

// the following should not compile: no random access iterator
// iter = begin + 1;
// CHECK( second == iter );
// iter = second - 1;
// CHECK( begin == iter );
// iter = 1 + begin;
// CHECK( second == iter );
} // THEN
} // WHEN
} // GIVEN

GIVEN( "a container with bidirectional iterators" ) {

std::list< int > values = { 0, 1, 2, 3, 4 };

WHEN( "when the container and the transformation are used" ) {

TransformView chunk( values, transform );

THEN( "the TransformView::Iterator functions as a normal bidirectional iterator" ) {

auto begin = chunk.begin();
auto second = ++chunk.begin();
auto end = chunk.end();
auto iter = begin;

unsigned int counter = 0;
for ( auto iter = begin; iter != end; ++iter ) {

++counter;
}
CHECK( 5 == counter );

CHECK( 5 == std::distance( begin, end ) );
CHECK( begin != end );

CHECK( -2 == *begin );
CHECK( -1 == *second );

// the following should not compile: no random access iterator
// CHECK( -2 == begin[0] );
// CHECK( -1 == begin[1] );
// CHECK( 0 == begin[2] );
// CHECK( 1 == begin[3] );
// CHECK( 2 == begin[4] );

// the following should not compile: no random access iterator
// iter += 1;
// CHECK( second == iter );
// iter -= 1;
// CHECK( begin == iter );

CHECK( second == ++begin );
CHECK( begin == --begin );

iter = begin;
CHECK( begin == iter++ );
CHECK( second == iter );
CHECK( second == iter-- );
CHECK( begin == iter );

// the following should not compile: no random access iterator
// iter = begin + 1;
// CHECK( second == iter );
// iter = second - 1;
// CHECK( begin == iter );
// iter = 1 + begin;
// CHECK( second == iter );
} // THEN
} // WHEN
} // GIVEN

GIVEN( "a container with random access iterators" ) {

std::vector< int > values = { 0, 1, 2, 3, 4 };

WHEN( "when the container and the transformation are used" ) {

TransformView chunk( values, transform );

THEN( "the TransformView::Iterator functions as a normal random access "
"iterator" ) {

auto begin = chunk.begin();
auto second = begin + 1;
auto end = chunk.end();
auto iter = begin;

unsigned int counter = 0;
for ( auto iter = begin; iter != end; ++iter ) {

++counter;
}
CHECK( 5 == counter );

CHECK( 5 == std::distance( begin, end ) );
CHECK( 5 == end - begin );
CHECK( begin != end );

CHECK( -2 == *begin );
CHECK( -1 == *second );

CHECK( -2 == begin[0] );
CHECK( -1 == begin[1] );
CHECK( 0 == begin[2] );
CHECK( 1 == begin[3] );
CHECK( 2 == begin[4] );

iter += 1;
CHECK( second == iter );
iter -= 1;
CHECK( begin == iter );

CHECK( second == ++begin );
CHECK( begin == --begin );

iter = begin;
CHECK( begin == iter++ );
CHECK( second == iter );
CHECK( second == iter-- );
CHECK( begin == iter );

iter = begin + 1;
CHECK( second == iter );
iter = second - 1;
CHECK( begin == iter );
iter = 1 + begin;
CHECK( second == iter );
} // THEN
} // WHEN
} // GIVEN
} // SCENARIO

0 comments on commit 416d056

Please sign in to comment.