[concatenate iterator] re-factor unit test; add tests for bidirectional iterators;

This commit is contained in:
Menelaos Karavelas 2014-05-02 13:29:06 +03:00
parent 75488e0988
commit 6fd158cf90

View File

@ -14,6 +14,7 @@
#include <boost/test/included/unit_test.hpp>
#include <cstddef>
#include <iostream>
#include <string>
#include <algorithm>
@ -53,6 +54,181 @@ struct is_odd
struct test_concatenate_iterator
{
template <typename ConcatenateIterator, typename CombinedContainer>
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 <typename ConcatenateIterator, typename CombinedContainer>
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 <typename ConcatenateIterator, typename CombinedContainer>
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 <typename ConcatenateIterator, typename CombinedContainer>
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<value_type>());
for (ConcatenateIterator it = first; it != new_beyond; ++it)
{
BOOST_CHECK( !is_odd<value_type>()(*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 <typename Container1, typename Container2>
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<typename Container1::value_type> 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<value_type>());
for (const_concat_iterator it = const_begin; it != new_end; ++it)
{
BOOST_CHECK( !is_odd<value_type>()(*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;