| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 | // Copyright David Abrahams and Jeremy Siek 2003.// 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)#ifndef BOOST_ITERATOR_TESTS_HPP# define BOOST_ITERATOR_TESTS_HPP// This is meant to be the beginnings of a comprehensive, generic// test suite for STL concepts such as iterators and containers.//// Revision History:// 28 Apr 2002  Fixed input iterator requirements.//              For a == b a++ == b++ is no longer required.//              See 24.1.1/3 for details.//              (Thomas Witt)// 08 Feb 2001  Fixed bidirectional iterator test so that//              --i is no longer a precondition.//              (Jeremy Siek)// 04 Feb 2001  Added lvalue test, corrected preconditions//              (David Abrahams)# include <iterator># include <boost/static_assert.hpp># include <boost/concept_archetype.hpp> // for detail::dummy_constructor# include <boost/implicit_cast.hpp># include <boost/core/ignore_unused.hpp># include <boost/core/lightweight_test.hpp># include <boost/type_traits/is_same.hpp># include <boost/type_traits/is_pointer.hpp># include <boost/type_traits/is_reference.hpp>namespace boost {  // use this for the value typestruct dummyT {  dummyT() { }  dummyT(detail::dummy_constructor) { }  dummyT(int x) : m_x(x) { }  int foo() const { return m_x; }  bool operator==(const dummyT& d) const { return m_x == d.m_x; }  int m_x;};}namespace boost {namespace iterators {// Tests whether type Iterator satisfies the requirements for a// TrivialIterator.// Preconditions: i != j, *i == valtemplate <class Iterator, class T>void trivial_iterator_test(const Iterator i, const Iterator j, T val){  Iterator k;  BOOST_TEST(i == i);  BOOST_TEST(j == j);  BOOST_TEST(i != j);#ifdef BOOST_NO_STD_ITERATOR_TRAITS  T v = *i;#else  typename std::iterator_traits<Iterator>::value_type v = *i;#endif  BOOST_TEST(v == val);  boost::ignore_unused(v);#if 0  // hmm, this will give a warning for transform_iterator...  perhaps  // this should be separated out into a stand-alone test since there  // are several situations where it can't be used, like for  // integer_range::iterator.  BOOST_TEST(v == i->foo());#endif  k = i;  BOOST_TEST(k == k);  BOOST_TEST(k == i);  BOOST_TEST(k != j);  BOOST_TEST(*k == val);  boost::ignore_unused(k);}// Preconditions: i != jtemplate <class Iterator, class T>void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val){  *i = val;  trivial_iterator_test(i, j, val);}// Preconditions: *i == v1, *++i == v2template <class Iterator, class T>void input_iterator_test(Iterator i, T v1, T v2){  Iterator i1(i);  BOOST_TEST(i == i1);  BOOST_TEST(!(i != i1));  // I can see no generic way to create an input iterator  // that is in the domain of== of i and != i.  // The following works for istream_iterator but is not  // guaranteed to work for arbitrary input iterators.  //  //   Iterator i2;  //  //   BOOST_TEST(i != i2);  //   BOOST_TEST(!(i == i2));  BOOST_TEST(*i1 == v1);  BOOST_TEST(*i  == v1);  // we cannot test for equivalence of (void)++i & (void)i++  // as i is only guaranteed to be single pass.  BOOST_TEST(*i++ == v1);  boost::ignore_unused(i1);  i1 = i;  BOOST_TEST(i == i1);  BOOST_TEST(!(i != i1));  BOOST_TEST(*i1 == v2);  BOOST_TEST(*i  == v2);  boost::ignore_unused(i1);  // i is dereferencable, so it must be incrementable.  ++i;  // how to test for operator-> ?}// how to test output iterator?template <bool is_pointer> struct lvalue_test{    template <class Iterator> static void check(Iterator)    {# ifndef BOOST_NO_STD_ITERATOR_TRAITS        typedef typename std::iterator_traits<Iterator>::reference reference;        typedef typename std::iterator_traits<Iterator>::value_type value_type;# else        typedef typename Iterator::reference reference;        typedef typename Iterator::value_type value_type;# endif        BOOST_STATIC_ASSERT(boost::is_reference<reference>::value);        BOOST_STATIC_ASSERT((boost::is_same<reference,value_type&>::value                             || boost::is_same<reference,const value_type&>::value            ));    }};# ifdef BOOST_NO_STD_ITERATOR_TRAITStemplate <> struct lvalue_test<true> {    template <class T> static void check(T) {}};#endiftemplate <class Iterator, class T>void forward_iterator_test(Iterator i, T v1, T v2){  input_iterator_test(i, v1, v2);  Iterator i1 = i, i2 = i;  BOOST_TEST(i == i1++);  BOOST_TEST(i != ++i2);  trivial_iterator_test(i, i1, v1);  trivial_iterator_test(i, i2, v1);  ++i;  BOOST_TEST(i == i1);  BOOST_TEST(i == i2);  ++i1;  ++i2;  trivial_iterator_test(i, i1, v2);  trivial_iterator_test(i, i2, v2); // borland doesn't allow non-type template parameters# if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)  lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);#endif}// Preconditions: *i == v1, *++i == v2template <class Iterator, class T>void bidirectional_iterator_test(Iterator i, T v1, T v2){  forward_iterator_test(i, v1, v2);  ++i;  Iterator i1 = i, i2 = i;  BOOST_TEST(i == i1--);  BOOST_TEST(i != --i2);  trivial_iterator_test(i, i1, v2);  trivial_iterator_test(i, i2, v2);  --i;  BOOST_TEST(i == i1);  BOOST_TEST(i == i2);  ++i1;  ++i2;  trivial_iterator_test(i, i1, v1);  trivial_iterator_test(i, i2, v1);}// mutable_bidirectional_iterator_testtemplate <class U> struct undefined;// Preconditions: [i,i+N) is a valid rangetemplate <class Iterator, class TrueVals>void random_access_iterator_test(Iterator i, int N, TrueVals vals){  bidirectional_iterator_test(i, vals[0], vals[1]);  const Iterator j = i;  int c;  typedef typename std::iterator_traits<Iterator>::value_type value_type;  boost::ignore_unused<value_type>();  for (c = 0; c < N-1; ++c) {    BOOST_TEST(i == j + c);    BOOST_TEST(*i == vals[c]);    BOOST_TEST(*i == boost::implicit_cast<value_type>(j[c]));    BOOST_TEST(*i == *(j + c));    BOOST_TEST(*i == *(c + j));    ++i;    BOOST_TEST(i > j);    BOOST_TEST(i >= j);    BOOST_TEST(j <= i);    BOOST_TEST(j < i);  }  Iterator k = j + N - 1;  for (c = 0; c < N-1; ++c) {    BOOST_TEST(i == k - c);    BOOST_TEST(*i == vals[N - 1 - c]);    BOOST_TEST(*i == boost::implicit_cast<value_type>(j[N - 1 - c]));    Iterator q = k - c;    boost::ignore_unused(q);    BOOST_TEST(*i == *q);    BOOST_TEST(i > j);    BOOST_TEST(i >= j);    BOOST_TEST(j <= i);    BOOST_TEST(j < i);    --i;  }}// Precondition: i != jtemplate <class Iterator, class ConstIterator>void const_nonconst_iterator_test(Iterator i, ConstIterator j){  BOOST_TEST(i != j);  BOOST_TEST(j != i);  ConstIterator k(i);  BOOST_TEST(k == i);  BOOST_TEST(i == k);  k = i;  BOOST_TEST(k == i);  BOOST_TEST(i == k);  boost::ignore_unused(k);}} // namespace iteratorsusing iterators::undefined;using iterators::trivial_iterator_test;using iterators::mutable_trivial_iterator_test;using iterators::input_iterator_test;using iterators::lvalue_test;using iterators::forward_iterator_test;using iterators::bidirectional_iterator_test;using iterators::random_access_iterator_test;using iterators::const_nonconst_iterator_test;} // namespace boost#endif // BOOST_ITERATOR_TESTS_HPP
 |