311 lines
11 KiB
C++
311 lines
11 KiB
C++
/* Copyright 2016-2017 Joaquin M Lopez Munoz.
|
|
* Distributed under the Boost Software License, Version 1.0.
|
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
|
* http://www.boost.org/LICENSE_1_0.txt)
|
|
*
|
|
* See http://www.boost.org/libs/poly_collection for library home page.
|
|
*/
|
|
|
|
#include "test_iterators.hpp"
|
|
|
|
#include <boost/core/lightweight_test.hpp>
|
|
#include <iterator>
|
|
#include <type_traits>
|
|
#include "any_types.hpp"
|
|
#include "base_types.hpp"
|
|
#include "function_types.hpp"
|
|
#include "test_utilities.hpp"
|
|
|
|
using namespace test_utilities;
|
|
|
|
template<typename Iterator>
|
|
using is_input=std::is_base_of<
|
|
std::input_iterator_tag,
|
|
typename std::iterator_traits<Iterator>::iterator_category
|
|
>;
|
|
template<typename Iterator>
|
|
using is_forward=std::is_base_of<
|
|
std::forward_iterator_tag,
|
|
typename std::iterator_traits<Iterator>::iterator_category
|
|
>;
|
|
template<typename Iterator>
|
|
using is_random_access=std::is_base_of<
|
|
std::random_access_iterator_tag,
|
|
typename std::iterator_traits<Iterator>::iterator_category
|
|
>;
|
|
|
|
template<typename Type,typename PolyCollection>
|
|
void test_iterators(PolyCollection& p)
|
|
{
|
|
using local_base_iterator=typename PolyCollection::local_base_iterator;
|
|
using const_local_base_iterator=
|
|
typename PolyCollection::const_local_base_iterator;
|
|
using local_iterator=typename PolyCollection::template local_iterator<Type>;
|
|
using const_local_iterator=
|
|
typename PolyCollection::template const_local_iterator<Type>;
|
|
using base_segment_info=typename PolyCollection::base_segment_info;
|
|
using const_base_segment_info=
|
|
typename PolyCollection::const_base_segment_info;
|
|
using const_segment_info=
|
|
typename PolyCollection::template const_segment_info<Type>;
|
|
using segment_info=typename PolyCollection::template segment_info<Type>;
|
|
|
|
static_assert(is_random_access<local_iterator>::value,
|
|
"local_iterator must be random access");
|
|
static_assert(is_random_access<const_local_iterator>::value,
|
|
"const_local_iterator must be random access");
|
|
static_assert(std::is_base_of<const_segment_info,segment_info>::value,
|
|
"segment_info must derive from const_segment_info");
|
|
|
|
{
|
|
local_iterator lit;
|
|
const_local_iterator clit,clit2(lit); /* sorry about the names */
|
|
|
|
lit=lit;
|
|
clit=clit2;
|
|
clit=lit;
|
|
}
|
|
|
|
const PolyCollection& cp=p;
|
|
std::size_t n=0;
|
|
local_base_iterator lbfirst=p.begin(typeid(Type)),
|
|
lblast=p.end(typeid(Type));
|
|
const_local_base_iterator clbfirst=cp.begin(typeid(Type)),
|
|
clblast=cp.end(typeid(Type));
|
|
local_iterator lfirst=p.template begin<Type>(),
|
|
llast=p.template end<Type>();
|
|
const_local_iterator clfirst=cp.template begin<Type>(),
|
|
cllast=cp.template end<Type>();
|
|
base_segment_info bi=p.segment(typeid(Type));
|
|
const_base_segment_info cbi=cp.segment(typeid(Type));
|
|
segment_info i=p.template segment<Type>();
|
|
const_segment_info ci=cp.template segment<Type>();
|
|
|
|
BOOST_TEST(clbfirst==cp.cbegin(typeid(Type)));
|
|
BOOST_TEST(clblast==cp.cend(typeid(Type)));
|
|
BOOST_TEST(clfirst==cp.template cbegin<Type>());
|
|
BOOST_TEST(cllast==cp.template cend<Type>());
|
|
|
|
BOOST_TEST(lbfirst==bi.begin());
|
|
BOOST_TEST(lblast==bi.end());
|
|
BOOST_TEST(clbfirst==bi.cbegin());
|
|
BOOST_TEST(clbfirst==cbi.begin());
|
|
BOOST_TEST(clblast==bi.cend());
|
|
BOOST_TEST(clblast==cbi.end());
|
|
|
|
BOOST_TEST(lfirst==i.begin());
|
|
BOOST_TEST(llast==i.end());
|
|
BOOST_TEST(clfirst==i.cbegin());
|
|
BOOST_TEST(clfirst==ci.begin());
|
|
BOOST_TEST(cllast==i.cend());
|
|
BOOST_TEST(cllast==ci.end());
|
|
|
|
for(;lbfirst!=lblast;++lbfirst,++clbfirst,++lfirst,++clfirst){
|
|
BOOST_TEST(lfirst==static_cast<local_iterator>(lbfirst));
|
|
BOOST_TEST(static_cast<local_base_iterator>(lfirst)==lbfirst);
|
|
BOOST_TEST(clfirst==static_cast<const_local_iterator>(clbfirst));
|
|
BOOST_TEST(static_cast<const_local_base_iterator>(clfirst)==clbfirst);
|
|
BOOST_TEST(clfirst==lfirst);
|
|
BOOST_TEST(&*lfirst==&*static_cast<local_iterator>(lbfirst));
|
|
BOOST_TEST(&*clfirst==&*static_cast<const_local_iterator>(clbfirst));
|
|
BOOST_TEST(&*clfirst==&*lfirst);
|
|
|
|
Type& r=p.template begin<Type>()[n];
|
|
const Type& cr=cp.template begin<Type>()[n];
|
|
|
|
BOOST_TEST(&*lfirst==&r);
|
|
BOOST_TEST(&*clfirst==&cr);
|
|
|
|
++n;
|
|
}
|
|
BOOST_TEST(clbfirst==clblast);
|
|
BOOST_TEST(lfirst==llast);
|
|
BOOST_TEST(clfirst==cllast);
|
|
BOOST_TEST(lfirst==static_cast<local_iterator>(llast));
|
|
BOOST_TEST(clfirst==static_cast<const_local_iterator>(cllast));
|
|
BOOST_TEST(clfirst==llast);
|
|
BOOST_TEST((std::ptrdiff_t)n==p.end(typeid(Type))-p.begin(typeid(Type)));
|
|
BOOST_TEST(
|
|
(std::ptrdiff_t)n==p.template end<Type>()-p.template begin<Type>());
|
|
|
|
for(auto s:p.segment_traversal()){
|
|
if(s.type_info()==typeid(Type)){
|
|
const auto& cs=s;
|
|
|
|
BOOST_TEST(
|
|
s.template begin<Type>()==
|
|
static_cast<local_iterator>(s.begin()));
|
|
BOOST_TEST(
|
|
s.template end<Type>()==
|
|
static_cast<local_iterator>(s.end()));
|
|
BOOST_TEST(
|
|
cs.template begin<Type>()==
|
|
static_cast<const_local_iterator>(cs.begin()));
|
|
BOOST_TEST(
|
|
cs.template end<Type>()==
|
|
static_cast<const_local_iterator>(cs.end()));
|
|
BOOST_TEST(
|
|
cs.template cbegin<Type>()==
|
|
static_cast<const_local_iterator>(cs.cbegin()));
|
|
BOOST_TEST(
|
|
cs.template cend<Type>()==
|
|
static_cast<const_local_iterator>(cs.cend()));
|
|
}
|
|
}
|
|
}
|
|
|
|
template<typename PolyCollection,typename ValueFactory,typename... Types>
|
|
void test_iterators()
|
|
{
|
|
using value_type=typename PolyCollection::value_type;
|
|
using iterator=typename PolyCollection::iterator;
|
|
using const_iterator=typename PolyCollection::const_iterator;
|
|
using local_base_iterator=typename PolyCollection::local_base_iterator;
|
|
using const_local_base_iterator=
|
|
typename PolyCollection::const_local_base_iterator;
|
|
using const_base_segment_info=
|
|
typename PolyCollection::const_base_segment_info;
|
|
using base_segment_info=typename PolyCollection::base_segment_info;
|
|
using base_segment_info_iterator=
|
|
typename PolyCollection::base_segment_info_iterator;
|
|
using const_base_segment_info_iterator=
|
|
typename PolyCollection::const_base_segment_info_iterator;
|
|
using const_segment_traversal_info=
|
|
typename PolyCollection::const_segment_traversal_info;
|
|
using segment_traversal_info=
|
|
typename PolyCollection::segment_traversal_info;
|
|
|
|
static_assert(is_forward<iterator>::value,
|
|
"iterator must be forward");
|
|
static_assert(is_forward<const_iterator>::value,
|
|
"const_iterator must be forward");
|
|
static_assert(is_random_access<local_base_iterator>::value,
|
|
"local_base_iterator must be random access");
|
|
static_assert(is_random_access<const_local_base_iterator>::value,
|
|
"const_local_base_iterator must be random access");
|
|
static_assert(std::is_base_of<
|
|
const_base_segment_info,base_segment_info>::value,
|
|
"base_segment_info must derive from const_base_segment_info");
|
|
static_assert(is_input<base_segment_info_iterator>::value,
|
|
"base_segment_info_iterator must be input");
|
|
static_assert(is_input<const_base_segment_info_iterator>::value,
|
|
"const_base_segment_info_iterator must be input");
|
|
static_assert(std::is_base_of<
|
|
const_segment_traversal_info,segment_traversal_info>::value,
|
|
"const_segment_traversal_info must derive "\
|
|
"from segment_traversal_info");
|
|
|
|
{
|
|
iterator it;
|
|
const_iterator cit,cit2(it);
|
|
local_base_iterator lbit;
|
|
const_local_base_iterator clbit,clbit2(lbit);
|
|
base_segment_info_iterator sit;
|
|
const_base_segment_info_iterator csit,csit2(csit);
|
|
|
|
it=it;
|
|
cit=cit2;
|
|
cit=it;
|
|
lbit=lbit;
|
|
clbit=clbit2;
|
|
clbit=lbit;
|
|
sit=sit;
|
|
csit=csit2;
|
|
csit=sit;
|
|
}
|
|
|
|
PolyCollection p;
|
|
const PolyCollection& cp=p;
|
|
ValueFactory v;
|
|
|
|
fill<constraints<>,Types...>(p,v,2);
|
|
|
|
{
|
|
std::size_t n=0;
|
|
iterator first=p.begin(),last=p.end();
|
|
const_iterator cfirst=cp.begin(),clast=cp.end();
|
|
|
|
BOOST_TEST(cfirst==cp.cbegin());
|
|
BOOST_TEST(clast==cp.cend());
|
|
|
|
for(;first!=last;++first,++cfirst){
|
|
BOOST_TEST(first==cfirst);
|
|
BOOST_TEST(&*first==&*cfirst);
|
|
|
|
++n;
|
|
}
|
|
BOOST_TEST(cfirst==clast);
|
|
BOOST_TEST(last==clast);
|
|
BOOST_TEST(n==p.size());
|
|
}
|
|
|
|
{
|
|
std::size_t n=0;
|
|
base_segment_info_iterator first=p.segment_traversal().begin(),
|
|
last=p.segment_traversal().end();
|
|
const_base_segment_info_iterator cfirst=cp.segment_traversal().begin(),
|
|
clast=cp.segment_traversal().end();
|
|
|
|
BOOST_TEST(cfirst==cp.segment_traversal().cbegin());
|
|
BOOST_TEST(clast==cp.segment_traversal().cend());
|
|
|
|
for(;first!=last;++first,++cfirst){
|
|
BOOST_TEST(first==cfirst);
|
|
|
|
std::size_t m=0;
|
|
local_base_iterator lbfirst=first->begin(),lblast=first->end();
|
|
const_local_base_iterator clbfirst=cfirst->begin(),clblast=cfirst->end();
|
|
|
|
BOOST_TEST(clbfirst==cfirst->cbegin());
|
|
BOOST_TEST(clblast==cfirst->cend());
|
|
BOOST_TEST(lbfirst==p.begin(first->type_info()));
|
|
BOOST_TEST(lblast==p.end(first->type_info()));
|
|
BOOST_TEST(clbfirst==cp.begin(first->type_info()));
|
|
BOOST_TEST(clblast==cp.end(first->type_info()));
|
|
BOOST_TEST(clbfirst==cp.cbegin(first->type_info()));
|
|
BOOST_TEST(clblast==cp.cend(first->type_info()));
|
|
|
|
for(;lbfirst!=lblast;++lbfirst,++clbfirst){
|
|
BOOST_TEST(lbfirst==clbfirst);
|
|
BOOST_TEST(&*lbfirst==&*clbfirst);
|
|
|
|
value_type& r=first->begin()[m];
|
|
const value_type& cr=cfirst->begin()[m];
|
|
|
|
BOOST_TEST(&*lbfirst==&r);
|
|
BOOST_TEST(&*clbfirst==&cr);
|
|
|
|
++m;
|
|
}
|
|
BOOST_TEST(clbfirst==clblast);
|
|
BOOST_TEST(lblast==clblast);
|
|
BOOST_TEST((std::ptrdiff_t)m==first->end()-first->begin());
|
|
BOOST_TEST((std::ptrdiff_t)m==cfirst->end()-cfirst->begin());
|
|
BOOST_TEST((std::ptrdiff_t)m==cfirst->cend()-cfirst->cbegin());
|
|
|
|
n+=m;
|
|
}
|
|
BOOST_TEST(cfirst==clast);
|
|
BOOST_TEST(last==clast);
|
|
BOOST_TEST(n==p.size());
|
|
}
|
|
|
|
do_((test_iterators<Types>(p),0)...);
|
|
}
|
|
|
|
void test_iterators()
|
|
{
|
|
test_iterators<
|
|
any_types::collection,auto_increment,
|
|
any_types::t1,any_types::t2,any_types::t3,
|
|
any_types::t4,any_types::t5>();
|
|
test_iterators<
|
|
base_types::collection,auto_increment,
|
|
base_types::t1,base_types::t2,base_types::t3,
|
|
base_types::t4,base_types::t5>();
|
|
test_iterators<
|
|
function_types::collection,auto_increment,
|
|
function_types::t1,function_types::t2,function_types::t3,
|
|
function_types::t4,function_types::t5>();
|
|
}
|