/* Copyright 2016-2018 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 #include #include #include "any_types.hpp" #include "base_types.hpp" #include "function_types.hpp" #include "test_utilities.hpp" using namespace test_utilities; template using is_input=std::is_base_of< std::input_iterator_tag, typename std::iterator_traits::iterator_category >; template using is_forward=std::is_base_of< std::forward_iterator_tag, typename std::iterator_traits::iterator_category >; template using is_random_access=std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits::iterator_category >; template 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; using const_local_iterator= typename PolyCollection::template const_local_iterator; 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; using segment_info=typename PolyCollection::template segment_info; static_assert(is_random_access::value, "local_iterator must be random access"); static_assert(is_random_access::value, "const_local_iterator must be random access"); static_assert(std::is_base_of::value, "segment_info must derive from const_segment_info"); { local_iterator lit,lit2; const_local_iterator clit,clit2(lit); /* sorry about the names */ lit=lit2; 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(), llast=p.template end(); const_local_iterator clfirst=cp.template begin(), cllast=cp.template end(); base_segment_info bi=p.segment(typeid(Type)); const_base_segment_info cbi=cp.segment(typeid(Type)); segment_info i=p.template segment(); const_segment_info ci=cp.template segment(); BOOST_TEST(clbfirst==cp.cbegin(typeid(Type))); BOOST_TEST(clblast==cp.cend(typeid(Type))); BOOST_TEST(clfirst==cp.template cbegin()); BOOST_TEST(cllast==cp.template cend()); 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(lbfirst)); BOOST_TEST(static_cast(lfirst)==lbfirst); BOOST_TEST(clfirst==static_cast(clbfirst)); BOOST_TEST(static_cast(clfirst)==clbfirst); BOOST_TEST(clfirst==lfirst); BOOST_TEST(&*lfirst==&*static_cast(lbfirst)); BOOST_TEST(&*clfirst==&*static_cast(clbfirst)); BOOST_TEST(&*clfirst==&*lfirst); Type& r=p.template begin()[n]; const Type& cr=cp.template begin()[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(llast)); BOOST_TEST(clfirst==static_cast(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()-p.template begin()); for(auto s:p.segment_traversal()){ if(s.type_info()==typeid(Type)){ const auto& cs=s; BOOST_TEST( s.template begin()== static_cast(s.begin())); BOOST_TEST( s.template end()== static_cast(s.end())); BOOST_TEST( cs.template begin()== static_cast(cs.begin())); BOOST_TEST( cs.template end()== static_cast(cs.end())); BOOST_TEST( cs.template cbegin()== static_cast(cs.cbegin())); BOOST_TEST( cs.template cend()== static_cast(cs.cend())); } } } template 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::value, "iterator must be forward"); static_assert(is_forward::value, "const_iterator must be forward"); static_assert(is_random_access::value, "local_base_iterator must be random access"); static_assert(is_random_access::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::value, "base_segment_info_iterator must be input"); static_assert(is_input::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,it2; const_iterator cit,cit2(it); local_base_iterator lbit,lbit2; const_local_base_iterator clbit,clbit2(lbit); base_segment_info_iterator sit,sit2; const_base_segment_info_iterator csit,csit2(csit); it=it2; cit=cit2; cit=it; lbit=lbit2; clbit=clbit2; clbit=lbit; sit=sit2; csit=csit2; csit=sit; } PolyCollection p; const PolyCollection& cp=p; ValueFactory v; fill,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(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>(); }