6#ifndef DUNE_COMMON_TEST_ITERATORTEST_HH 
    7#define DUNE_COMMON_TEST_ITERATORTEST_HH 
   20template<
class Iter, 
class Value>
 
   21void testOutputIterator(Iter iterator, std::size_t iterations, Value value)
 
   32  for (
size_t i=0; i<iterations; ++i, ++tmp1)
 
   38  for (
size_t i=0; i<iterations; ++i, tmp2++)
 
   45                "std::iterator_traits::difference_type is not defined!");
 
   47                "std::iterator_traits::value_type is not defined!");
 
   49                "std::iterator_traits::pointer is not defined!");
 
   51                "std::iterator_traits::reference is not defined!");
 
   54  static_assert(std::is_same<typename std::iterator_traits<Iter>::iterator_category, std::output_iterator_tag>::value,
 
   55                "std::iterator_traits::iterator_category is not properly defined!");
 
   65template<
class Iter, 
class Opt>
 
   66int testForwardIterator(Iter begin, Iter end, Opt& opt)
 
   74  Iter defaultConstructedIterator1{}, defaultConstructedIterator2{};
 
   82  if (defaultConstructedIterator1 != defaultConstructedIterator2) {
 
   83    std::cerr<<
"Default constructed iterators do not compare equal for "+Dune::className<Iter>()+
"."<<std::endl;
 
   94  if (tmp!=begin || tmp1!=begin || tmp!=tmp1) {
 
   95    std::cerr<<
" Copying iterator failed "<<__FILE__<<
":"<<__LINE__<<std::endl;
 
  100  if (not (tmp==begin && tmp1==begin && tmp==tmp1)) {
 
  101    std::cerr<<
" Copying iterator failed "<<__FILE__<<
":"<<__LINE__<<std::endl;
 
  106  for(; begin!=end; ++begin)
 
  111  for(; begin!=end; begin++)
 
  117  static_assert(std::is_same<typename std::iterator_traits<Iter>::difference_type, 
typename std::iterator_traits<Iter>::difference_type>::value,
 
  118                "std::iterator_traits::difference_type is not defined!");
 
  119  static_assert(std::is_same<typename std::iterator_traits<Iter>::value_type,      
typename std::iterator_traits<Iter>::value_type>::value,
 
  120                "std::iterator_traits::value_type is not defined!");
 
  121  static_assert(std::is_same<typename std::iterator_traits<Iter>::pointer,         
typename std::iterator_traits<Iter>::pointer>::value,
 
  122                "std::iterator_traits::pointer is not defined!");
 
  123  static_assert(std::is_same<typename std::iterator_traits<Iter>::reference,       
typename std::iterator_traits<Iter>::reference>::value,
 
  124                "std::iterator_traits::reference is not defined!");
 
  127  static_assert(std::is_same<typename std::iterator_traits<Iter>::iterator_category, std::forward_iterator_tag>::value
 
  128                or std::is_same<typename std::iterator_traits<Iter>::iterator_category, std::bidirectional_iterator_tag>::value
 
  129                or std::is_same<typename std::iterator_traits<Iter>::iterator_category, std::random_access_iterator_tag>::value,
 
  130                "std::iterator_traits::iterator_category is not properly defined!");
 
  145template<
class Iter, 
class Opt>
 
  146int testBidirectionalIterator(Iter begin, Iter end, Opt opt)
 
  148  int ret=testForwardIterator(begin, end, opt);
 
  149  for(Iter pre = end, post = end; pre != begin; )
 
  153      std::cerr << 
"Postdecrement did not return the old iterator" 
  159      std::cerr << 
"Predecrement did not return the new iterator" 
  166  typename Iter::difference_type size = std::distance(begin, end);
 
  169  int no= (size>10) ? 10 : size;
 
  171  for(
int i=0; i < no; i++)
 
  173    int index = 
static_cast<int>(size*(rand()/(RAND_MAX+1.0)));
 
  174    int backwards=size-index;
 
  177    for(
int j=0; j < index; j++) ++tbegin;
 
  178    for(
int j=0; j < backwards; j++) --tend;
 
  182      std::cerr<<
"Did not reach same index by starting forward from " 
  183               <<
"begin and backwards from end."<<std::endl;
 
  190template<
class Iter, 
class Opt>
 
  191int testRandomAccessIterator(Iter begin, Iter end, Opt opt){
 
  192  int ret=testBidirectionalIterator(begin, end, opt);
 
  194  typename Iter::difference_type size = end-begin;
 
  198  int no= (size>10) ? 10 : size;
 
  200  for(
int i=0; i < no; i++)
 
  202    int index = 
static_cast<int>(size*(rand()/(RAND_MAX+1.0)));
 
  207  if(begin != end &&!( begin<end))
 
  209    std::cerr<<
"! (begin()<end())"<<std::endl;
 
  215      std::cerr<<
"begin!=end, but begin-end >= 0!"<<std::endl;
 
  219      std::cerr<<
"begin!=end, but end-begin <= 0!"<<std::endl;
 
  224  for(
int i=0; i < no; i++)
 
  226    int index = 
static_cast<int>(size*(rand()/(RAND_MAX+1.0)));
 
  227    Iter rand(begin), test(begin), res{};
 
  230    if((res=begin+index) != rand)
 
  232      std::cerr << 
" i+n should have the result i+=n, where i is the " 
  233                <<
"iterator and n is the difference type!" <<std::endl;
 
  236    for(
int j = 0; j < index; j++)
 
  241      std::cerr << 
"i+=n should have the same result as applying the " 
  242                << 
"increment operator n times!"<< std::endl;
 
  250    if((end-index) != rand)
 
  252      std::cerr << 
" i-n should have the result i-=n, where i is the " 
  253                <<
"iterator and n is the difference type!" <<std::endl;
 
  256    for(
int j = 0; j < index; j++)
 
  261      std::cerr << 
"i-=n should have the same result as applying the " 
  262                << 
"decrement operator n times!"<< std::endl;
 
  267  for(
int i=0; i < no; i++)
 
  269    Iter iter1 = begin+
static_cast<int>(size*(rand()/(RAND_MAX+1.0)));
 
  270    Iter iter2 = begin+
static_cast<int>(size*(rand()/(RAND_MAX+1.0)));
 
  271    typename Iter::difference_type diff = iter2 -iter1;
 
  272    if((iter1+diff)!=iter2) {
 
  273      std::cerr<< 
"i+(j-i) = j should hold, where i,j are iterators!"<<std::endl;
 
  278  for(
int i=0; i < no-1; i++)
 
  280    Iter iter1 = begin+i;
 
  281    Iter iter2 = begin+i+1;
 
  283    if (!(iter1 < iter2) || (iter1 < iter1)) {
 
  284      std::cerr<< 
"i<j and !(i<i) should hold, where i,j=i+1 are iterators!"<<std::endl;
 
  287    if (!(iter1 <= iter2) || !(iter1 <= iter1)) {
 
  288      std::cerr<< 
"i<=j and i<=i should hold, where i,j=i+1 are iterators!"<<std::endl;
 
  291    if (!(iter2 > iter1) || (iter1 > iter1)) {
 
  292      std::cerr<< 
"j>i and !(i>i) should hold, where i,j=i+1 are iterators!"<<std::endl;
 
  295    if (!(iter2 >= iter1) || !(iter1 >= iter1)) {
 
  296      std::cerr<< 
"j>=i and i>=i should hold, where i,j=i+1 are iterators!"<<std::endl;
 
  299    if (!(iter1 == iter1) || (iter1 != iter1)) {
 
  300      std::cerr<< 
"i==i and !(i!=i) should hold, where i is an iterator!"<<std::endl;
 
  308template<
class Iter, 
class Opt, 
typename iterator_category>
 
  309int testIterator(Iter& begin, Iter& end, Opt& opt, iterator_category cat);
 
  311template<
class Iter, 
class Opt>
 
  312int testIterator(Iter& begin, Iter& end, Opt& opt, std::forward_iterator_tag)
 
  314  return testForwardIterator(begin, end, opt);
 
  317template<
class Iter, 
class Opt>
 
  318int testIterator(Iter& begin, Iter& end, Opt& opt, std::bidirectional_iterator_tag)
 
  320  return testBidirectionalIterator(begin, end, opt);
 
  323template<
class Iter, 
class Opt>
 
  324int testIterator(Iter& begin, Iter& end, Opt& opt, std::random_access_iterator_tag)
 
  327  int ret = testRandomAccessIterator(begin, end, opt);
 
  332template<
class Iter, 
class Opt>
 
  333int testConstIterator(Iter& begin, Iter& end, Opt& opt)
 
  336  int ret=testIterator(begin, end, opt, 
typename std::iterator_traits<Iter>::iterator_category());
 
  344  template<
class Container, 
typename IteratorTag>
 
  345  static void testSorting(Container&, IteratorTag)
 
  347  template<
class Container>
 
  348  static void testSorting(Container& c, std::random_access_iterator_tag)
 
  350    std::sort(c.begin(), c.end());
 
  356struct TestSorting<false>
 
  358  template<
class Container>
 
  359  static void testSorting(Container&, std::random_access_iterator_tag)
 
  361  template<
class Container, 
typename IteratorTag>
 
  362  static void testSorting(Container&, IteratorTag)
 
  367template<
class Container, 
class Opt, 
bool testSort>
 
  368int testIterator(Container& c, Opt& opt)
 
  370  typename Container::iterator begin=c.begin(), end=c.end();
 
  371  typename Container::const_iterator cbegin(begin);
 
  372  [[maybe_unused]] 
typename Container::const_iterator cbegin1 = begin;
 
  373  typename Container::const_iterator cend=c.end();
 
  376  TestSorting<testSort>::testSorting(c, 
typename std::iterator_traits<typename Container::iterator>::iterator_category());
 
  378  if(end!=cend || cend!=end)
 
  380    std::cerr<<
"constant and mutable iterators should be equal!"<<std::endl;
 
  383  ret += testConstIterator(cbegin, cend, opt);
 
  385    ret += testIterator(begin,end,opt);
 
  390template<
class Container, 
class Opt>
 
  391int testIterator(Container& c, Opt& opt)
 
  393  return testIterator<Container,Opt,true>(c,opt);
 
  396template<
class Iter, 
class Opt>
 
  397void testAssignment(Iter begin, Iter end, Opt&)
 
  400  for(; begin!=end; begin++)
 
  401    *begin=
typename std::iterator_traits<Iter>::value_type();
 
  405template<
class Iter, 
class Opt>
 
  406int testIterator(Iter& begin, Iter& end, Opt& opt)
 
  408  testAssignment(begin, end, opt);
 
  409  return testConstIterator(begin, end, opt);
 
  415  typename std::remove_const<T>::type res;
 
  418  void operator()(
const T& t){
 
  424template<
class Container, 
class Opt>
 
  425int testIterator(
const Container& c, Opt& opt)
 
  427  typename Container::const_iterator begin=c.begin(), end=c.end();
 
  428  return testConstIterator(begin,end, opt);
 
  432template<
class Container>
 
  433int testIterator(Container& c)
 
  435  Printer<typename std::iterator_traits<typename Container::iterator>::value_type> print;
 
  436  return testIterator(c,print);
 
A free function to provide the demangled class name of a given object or type as a string.
 
template which always yields a true value
Definition: typetraits.hh:134
 
Traits for type conversions and type information.