geometry/test/iterators/concatenate_iterator.cpp
2014-10-20 18:17:53 +02:00

260 lines
8.3 KiB
C++

// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_TEST_MODULE
#define BOOST_TEST_MODULE test_concatenate_iterator
#endif
#include <boost/test/included/unit_test.hpp>
#include <cstddef>
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <iterator>
#include <vector>
#include <list>
#include <boost/assign/std/vector.hpp>
#include <boost/assign/std/list.hpp>
#include <boost/core/ignore_unused.hpp>
#include "test_iterator_common.hpp"
#include <boost/geometry/iterators/concatenate_iterator.hpp>
using namespace boost::assign;
struct test_concatenate_iterator
{
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 BOOST_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,
std::string const& containers_id)
{
boost::ignore_unused(case_id, containers_id);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::stringstream sstream;
sstream << case_id << " [" << containers_id << "]";
std::cout << "case id: " << sstream.str() << std::endl;
#endif
typedef typename Container1::const_iterator const_iterator1;
typedef typename Container2::const_iterator const_iterator2;
typedef typename Container1::iterator iterator1;
typedef typename Container2::iterator iterator2;
typedef boost::geometry::concatenate_iterator
<
const_iterator1, const_iterator2,
typename Container1::value_type const
> const_concat_iterator;
typedef boost::geometry::concatenate_iterator
<
iterator1, iterator2, typename Container1::value_type
> concat_iterator;
typedef typename std::iterator_traits
<
concat_iterator
>::value_type value_type;
// test constructors/assignment operators
concat_iterator begin(c1.begin(), c1.end(), c2.begin(), c2.begin());
concat_iterator end(c1.end(), c2.begin(), c2.end());
const_concat_iterator const_begin(begin);
const_concat_iterator const_end(end);
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<value_type> combined;
std::copy(c1.begin(), c1.end(), std::back_inserter(combined));
std::copy(c2.begin(), c2.end(), std::back_inserter(combined));
test_equality(begin, end, combined);
combined.clear();
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)
test_size(begin, end, combined);
test_size(const_begin, const_end, combined);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
print_container(std::cout, c1.begin(), c1.end(), "first :")
<< std::endl;
print_container(std::cout, c2.begin(), c2.end(), "second :")
<< std::endl;
print_container(std::cout, begin, end, "combined:")
<< std::endl;
if ( begin != end )
{
std::cout << "min element: "
<< *std::min_element(begin, end)
<< std::endl;
std::cout << "max element: "
<< *std::max_element(const_begin, const_end)
<< std::endl;
}
#endif
// perform reversals (std::reverse)
test_using_reverse(begin, end, combined);
// 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::count_if / std::remove_if
test_using_remove_if(begin, end, combined);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << "====================" << std::endl << std::endl;
#endif
}
};
template <typename Container1, typename Container2>
inline void test_concatenation_of_containers(Container1& c1, Container2& c2,
std::string const& containers_id)
{
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl;
std::cout << "************************************" << std::endl
<< " TESTING CONTAINERS COMBINATION: "
<< containers_id << std::endl
<< "************************************" << std::endl
<< std::endl;
#endif
c1.clear();
c2.clear();
test_concatenate_iterator::apply(c1, c2, "empty_both", containers_id);
c2 += 10,11,12,13,14,15,16,17,18,19,20;
test_concatenate_iterator::apply(c1, c2, "empty_first", containers_id);
c2.clear();
c1 += 0,1,2,3,4,5,6;
test_concatenate_iterator::apply(c1, c2, "empty_second", containers_id);
c1.clear();
c2.clear();
c1 += 0,1,2,3,4,5,6;
c2 += 10,11,12,13,14,15,16,17,18,19,20;
test_concatenate_iterator::apply(c1, c2, "non_empty", containers_id);
}
BOOST_AUTO_TEST_CASE( test_concatenate_iterator_all )
{
std::vector<int> v, vv;
std::list<int> l, ll;
test_concatenation_of_containers(v, vv, "VV");
test_concatenation_of_containers(v, l, "VL");
test_concatenation_of_containers(l, v, "LV");
test_concatenation_of_containers(l, ll, "LL");
}