diff --git a/test/iterators/concatenate_iterator.cpp b/test/iterators/concatenate_iterator.cpp index ba95f04d3..631b8f425 100644 --- a/test/iterators/concatenate_iterator.cpp +++ b/test/iterators/concatenate_iterator.cpp @@ -14,6 +14,7 @@ #include +#include #include #include #include @@ -53,6 +54,181 @@ struct is_odd struct test_concatenate_iterator { + template + static inline void test_size(ConcatenateIterator first, + ConcatenateIterator beyond, + CombinedContainer const& combined) + { + BOOST_CHECK( combined.size() == std::distance(first, beyond) ); + + std::size_t size(0); + for (ConcatenateIterator it = first; it != beyond; ++it) + { + ++size; + } + BOOST_CHECK( combined.size() == size ); + + size = 0; + for (ConcatenateIterator it = beyond; it != first; --it) + { + ++size; + } + BOOST_CHECK( combined.size() == size ); + } + + + template + static inline void test_equality(ConcatenateIterator first, + ConcatenateIterator beyond, + CombinedContainer const& combined) + { + typedef typename CombinedContainer::const_iterator iterator; + + iterator it = combined.begin(); + for (ConcatenateIterator cit = first; cit != beyond; ++cit, ++it) + { + BOOST_CHECK( *cit == *it ); + } + + if ( combined.begin() != combined.end() ) + { + BOOST_CHECK( first != beyond ); + iterator it = combined.end(); + ConcatenateIterator cit = beyond; + for (--cit, --it; cit != first; --cit, --it) + { + BOOST_CHECK( *cit == *it ); + } + BOOST_CHECK( cit == first && it == combined.begin() ); + BOOST_CHECK( *cit == *it ); + } + else + { + BOOST_CHECK( first == beyond ); + } + } + + + template + static inline void test_using_reverse(ConcatenateIterator first, + ConcatenateIterator beyond, + CombinedContainer& combined) + { + std::reverse(first, beyond); + std::reverse(combined.begin(), combined.end()); + test_equality(first, beyond, combined); + +#ifdef GEOMETRY_TEST_DEBUG + print_container(std::cout, first, beyond, "reversed:") << std::endl; +#endif + + std::reverse(first, beyond); + std::reverse(combined.begin(), combined.end()); + test_equality(first, beyond, combined); + +#ifdef GEOMETRY_TEST_DEBUG + print_container(std::cout, first, beyond, "re-reversed:") << std::endl; +#endif + } + + + template + static inline void test_using_remove_if(ConcatenateIterator first, + ConcatenateIterator beyond, + CombinedContainer& combined) + { + typedef typename std::iterator_traits + < + ConcatenateIterator + >::value_type value_type; + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "odd elements removed:" << std::endl; + print_container(std::cout, first, beyond, "before:") + << std::endl; +#endif + ConcatenateIterator new_beyond = + std::remove_if(first, beyond, is_odd()); + + for (ConcatenateIterator it = first; it != new_beyond; ++it) + { + BOOST_CHECK( !is_odd()(*it) ); + } + +#ifdef GEOMETRY_TEST_DEBUG + print_container(std::cout, first, new_beyond, "after :") + << std::endl; +#endif + + } + + template + < + typename ConcatenateIterator, + typename ConstConcatenateIterator, + typename Container + > + static inline + void test_using_max_element(ConcatenateIterator first, + ConcatenateIterator beyond, + ConstConcatenateIterator const_first, + ConstConcatenateIterator const_beyond, + Container const& c, + std::size_t other_size, + bool second_container) + { + typedef typename std::iterator_traits + < + ConcatenateIterator + >::value_type value_type; + + if ( c.size() == 0 ) + { + return; + } + + ConcatenateIterator c_first = first; + if ( second_container ) + { + std::size_t counter(0); + while ( counter != other_size ) + { + ++counter; + c_first++; + } + } + + ConcatenateIterator it_max = std::max_element(first, beyond); + ConstConcatenateIterator const_it_max = + std::max_element(const_first, const_beyond); + + BOOST_CHECK( it_max == const_it_max ); + BOOST_CHECK( *it_max == *const_it_max ); + + value_type old_value = *c_first; + value_type new_value = *it_max + 1; + + *c_first = *it_max + 1; + BOOST_CHECK( *c.begin() == new_value ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "modified element of "; + std::cout << (second_container ? "2nd" : "1st"); + std::cout << " container:" << std::endl; + print_container(std::cout, c.begin(), c.end(), + (second_container ? "second :" : "first :")) + << std::endl; + print_container(std::cout, first, beyond, "combined:") + << std::endl; +#endif + + *c_first = old_value; + BOOST_CHECK( *c.begin() == old_value ); + } + + template static inline void apply(Container1& c1, Container2& c2, std::string const& case_id, @@ -89,31 +265,32 @@ struct test_concatenate_iterator const_begin = begin; const_end = end; + concat_iterator begin2(c1.end(), c1.end(), c2.begin(), c2.begin()); + const_concat_iterator const_begin2(c1.end(), c1.end(), + c2.begin(), c2.begin()); + + BOOST_CHECK( c1.empty() || *begin == *c1.begin() ); + BOOST_CHECK( c1.empty() || *const_begin == *c1.begin() ); + + BOOST_CHECK( c2.empty() || *begin2 == *c2.begin() ); + BOOST_CHECK( c2.empty() || *const_begin2 == *c2.begin() ); + + + // test copying, dereferencing and element equality + std::vector combined; + std::copy(begin, end, std::back_inserter(combined)); + test_equality(begin, end, combined); + test_equality(const_begin, const_end, combined); + + combined.clear(); + std::copy(const_begin, const_end, std::back_inserter(combined)); + test_equality(begin, end, combined); + test_equality(const_begin, const_end, combined); + + // test sizes (and std::distance) - BOOST_CHECK( c1.size() + c2.size() == std::distance(begin, end) ); - BOOST_CHECK( c1.size() + c2.size() - == std::distance(const_begin, const_end) ); - - std::size_t size(0); - for (const_concat_iterator it = const_begin; it != const_end; ++it) - { - ++size; - } - BOOST_CHECK( c1.size() + c2.size() == size ); - - size = 0; - for (concat_iterator it = begin; it != end; ++it) - { - ++size; - } - BOOST_CHECK( c1.size() + c2.size() == size ); - - size = 0; - for (concat_iterator it = end; it != begin; --it) - { - ++size; - } - BOOST_CHECK( c1.size() + c2.size() == size ); + test_size(begin, end, combined); + test_size(const_begin, const_end, combined); #ifdef GEOMETRY_TEST_DEBUG @@ -135,150 +312,20 @@ struct test_concatenate_iterator } #endif - // test element equality of elements and dereferencing - { - const_iterator1 it1 = c1.begin(); - const_iterator2 it2 = c2.begin(); - for (const_concat_iterator it = const_begin; it != const_end; ++it) - { - if ( it1 != c1.end() ) - { - BOOST_CHECK( *it == *it1 ); - ++it1; - } - else - { - BOOST_CHECK( *it == *it2 ); - ++it2; - } - } - } - - if ( c1.begin() != c1.end() && c2.begin() != c2.end() ) - { - const_iterator1 it1 = c1.end(); - const_iterator2 it2 = --c2.end(); - const_concat_iterator it = const_end; - for (--it; it != const_begin; --it) - { - if ( it2 != c2.begin() ) - { - BOOST_CHECK( *it == *it2 ); - --it2; - } - else if ( it1 == c1.end() && it2 == c2.begin() ) - { - BOOST_CHECK( *it == *it2 ); - --it1; - } - else - { - BOOST_CHECK( *it == *it1 ); - --it1; - } - } - BOOST_CHECK( it == const_begin && *it == *it1 ); - } + // check that we get the first element of the second container + // properly // perform reversals (std::reverse) - std::reverse(begin, end); -#ifdef GEOMETRY_TEST_DEBUG - print_container(std::cout, begin, end, "reversed:") << std::endl; -#endif - std::reverse(begin, end); -#ifdef GEOMETRY_TEST_DEBUG - print_container(std::cout, begin, end, "re-reversed:") << std::endl; -#endif + test_using_reverse(begin, end, combined); - // test std::max_element and dereferencing - typedef typename std::iterator_traits - < - concat_iterator - >::value_type value_type; - - if ( c1.size() != 0 ) - { - concat_iterator it_max = std::max_element(begin, end); - const_concat_iterator const_it_max = - std::max_element(const_begin, const_end); - - BOOST_CHECK( it_max == const_it_max ); - BOOST_CHECK( *it_max == *const_it_max ); - - value_type old_value = *const_begin; - value_type new_value = *it_max + 1; - - *begin = *it_max + 1; - BOOST_CHECK( *c1.begin() == new_value ); - -#ifdef GEOMETRY_TEST_DEBUG - std::cout << std::endl; - std::cout << "modified element of 1st container:" << std::endl; - print_container(std::cout, c1.begin(), c1.end(), "first :") - << std::endl; - print_container(std::cout, begin, end, "combined:") - << std::endl; -#endif - - *begin = old_value; - BOOST_CHECK( *c1.begin() == old_value ); - } - - if ( c2.size() != 0 ) - { - concat_iterator begin2 = begin; - std::size_t counter(0); - while ( counter != c1.size() ) - { - ++counter; - begin2++; - } - - concat_iterator it_max = std::max_element(begin, end); - const_concat_iterator const_it_max = - std::max_element(const_begin, const_end); - - BOOST_CHECK( it_max == const_it_max ); - BOOST_CHECK( *it_max == *const_it_max ); - - value_type old_value = *begin2; - value_type new_value = *it_max + 1; - - *begin2 = *it_max + 1; - BOOST_CHECK( *c2.begin() == new_value ); - -#ifdef GEOMETRY_TEST_DEBUG - std::cout << std::endl; - std::cout << "modified element of 2nd container:" << std::endl; - print_container(std::cout, c2.begin(), c2.end(), "second :") - << std::endl; - print_container(std::cout, begin, end, "combined:") - << std::endl; -#endif - - *begin2 = old_value; - BOOST_CHECK( *c2.begin() == old_value ); - } + // test std::max_element, dereferencing and value assigment + test_using_max_element(begin, end, const_begin, const_end, + c1, c2.size(), false); + test_using_max_element(begin, end, const_begin, const_end, + c2, c1.size(), true); // test std::remove_if -#ifdef GEOMETRY_TEST_DEBUG - std::cout << std::endl; - std::cout << "odd elements removed:" << std::endl; - print_container(std::cout, begin, end, "before:") - << std::endl; -#endif - concat_iterator new_end = - std::remove_if(begin, end, is_odd()); - - for (const_concat_iterator it = const_begin; it != new_end; ++it) - { - BOOST_CHECK( !is_odd()(*it) ); - } - -#ifdef GEOMETRY_TEST_DEBUG - print_container(std::cout, begin, new_end, "after :") - << std::endl; -#endif + test_using_remove_if(begin, end, combined); #ifdef GEOMETRY_TEST_DEBUG std::cout << "====================" << std::endl << std::endl;