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;
281template<
class Iter,
class Opt,
typename iterator_category>
282int testIterator(Iter& begin, Iter& end, Opt& opt, iterator_category cat);
284template<
class Iter,
class Opt>
285int testIterator(Iter& begin, Iter& end, Opt& opt, std::forward_iterator_tag)
287 return testForwardIterator(begin, end, opt);
290template<
class Iter,
class Opt>
291int testIterator(Iter& begin, Iter& end, Opt& opt, std::bidirectional_iterator_tag)
293 return testBidirectionalIterator(begin, end, opt);
296template<
class Iter,
class Opt>
297int testIterator(Iter& begin, Iter& end, Opt& opt, std::random_access_iterator_tag)
300 int ret = testRandomAccessIterator(begin, end, opt);
305template<
class Iter,
class Opt>
306int testConstIterator(Iter& begin, Iter& end, Opt& opt)
309 int ret=testIterator(begin, end, opt,
typename std::iterator_traits<Iter>::iterator_category());
317 template<
class Container,
typename IteratorTag>
318 static void testSorting(Container&, IteratorTag)
320 template<
class Container>
321 static void testSorting(Container& c, std::random_access_iterator_tag)
323 std::sort(c.begin(), c.end());
329struct TestSorting<false>
331 template<
class Container>
332 static void testSorting(Container&, std::random_access_iterator_tag)
334 template<
class Container,
typename IteratorTag>
335 static void testSorting(Container&, IteratorTag)
340template<
class Container,
class Opt,
bool testSort>
341int testIterator(Container& c, Opt& opt)
343 typename Container::iterator begin=c.begin(), end=c.end();
344 typename Container::const_iterator cbegin(begin);
345 [[maybe_unused]]
typename Container::const_iterator cbegin1 = begin;
346 typename Container::const_iterator cend=c.end();
349 TestSorting<testSort>::testSorting(c,
typename std::iterator_traits<typename Container::iterator>::iterator_category());
351 if(end!=cend || cend!=end)
353 std::cerr<<
"constant and mutable iterators should be equal!"<<std::endl;
356 ret += testConstIterator(cbegin, cend, opt);
358 ret += testIterator(begin,end,opt);
363template<
class Container,
class Opt>
364int testIterator(Container& c, Opt& opt)
366 return testIterator<Container,Opt,true>(c,opt);
369template<
class Iter,
class Opt>
370void testAssignment(Iter begin, Iter end, Opt&)
373 for(; begin!=end; begin++)
374 *begin=
typename std::iterator_traits<Iter>::value_type();
378template<
class Iter,
class Opt>
379int testIterator(Iter& begin, Iter& end, Opt& opt)
381 testAssignment(begin, end, opt);
382 return testConstIterator(begin, end, opt);
388 typename std::remove_const<T>::type res;
391 void operator()(
const T& t){
397template<
class Container,
class Opt>
398int testIterator(
const Container& c, Opt& opt)
400 typename Container::const_iterator begin=c.begin(), end=c.end();
401 return testConstIterator(begin,end, opt);
405template<
class Container>
406int testIterator(Container& c)
408 Printer<typename std::iterator_traits<typename Container::iterator>::value_type> print;
409 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.