265 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			265 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | #ifndef BOOST_NEW_ITERATOR_TESTS_HPP | ||
|  | # define BOOST_NEW_ITERATOR_TESTS_HPP | ||
|  | 
 | ||
|  | // | ||
|  | // Copyright (c) David Abrahams 2001. | ||
|  | // Copyright (c) Jeremy Siek 2001-2003. | ||
|  | // Copyright (c) Thomas Witt 2002. | ||
|  | // | ||
|  | // Use, modification and distribution is subject to 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) | ||
|  | // | ||
|  | 
 | ||
|  | // This is meant to be the beginnings of a comprehensive, generic | ||
|  | // test suite for STL concepts such as iterators and containers. | ||
|  | // | ||
|  | // Revision History: | ||
|  | // 28 Oct 2002  Started update for new iterator categories | ||
|  | //              (Jeremy Siek) | ||
|  | // 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/type_traits.hpp> | ||
|  | # include <boost/static_assert.hpp> | ||
|  | # include <boost/concept_archetype.hpp> // for detail::dummy_constructor | ||
|  | # include <boost/detail/iterator.hpp> | ||
|  | # include <boost/pending/iterator_tests.hpp> | ||
|  | # include <boost/iterator/is_readable_iterator.hpp> | ||
|  | # include <boost/iterator/is_lvalue_iterator.hpp> | ||
|  | 
 | ||
|  | # include <boost/iterator/detail/config_def.hpp> | ||
|  | # include <boost/detail/is_incrementable.hpp> | ||
|  | # include <boost/detail/lightweight_test.hpp> | ||
|  | 
 | ||
|  | namespace boost { | ||
|  | 
 | ||
|  | 
 | ||
|  | // Do separate tests for *i++ so we can treat, e.g., smart pointers, | ||
|  | // as readable and/or writable iterators. | ||
|  | template <class Iterator, class T> | ||
|  | void readable_iterator_traversal_test(Iterator i1, T v, mpl::true_) | ||
|  | { | ||
|  |     T v2(*i1++); | ||
|  |     BOOST_TEST(v == v2); | ||
|  | } | ||
|  | 
 | ||
|  | template <class Iterator, class T> | ||
|  | void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_) | ||
|  | {} | ||
|  | 
 | ||
|  | template <class Iterator, class T> | ||
|  | void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_) | ||
|  | { | ||
|  |     ++i1;  // we just wrote into that position | ||
|  |     *i1++ = v; | ||
|  |     Iterator x(i1++); | ||
|  |     (void)x; | ||
|  | } | ||
|  | 
 | ||
|  | template <class Iterator, class T> | ||
|  | void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_) | ||
|  | {} | ||
|  | 
 | ||
|  | 
 | ||
|  | // Preconditions: *i == v | ||
|  | template <class Iterator, class T> | ||
|  | void readable_iterator_test(const Iterator i1, T v) | ||
|  | { | ||
|  |   Iterator i2(i1); // Copy Constructible | ||
|  |   typedef typename detail::iterator_traits<Iterator>::reference ref_t; | ||
|  |   ref_t r1 = *i1; | ||
|  |   ref_t r2 = *i2; | ||
|  |   T v1 = r1; | ||
|  |   T v2 = r2; | ||
|  |   BOOST_TEST(v1 == v); | ||
|  |   BOOST_TEST(v2 == v); | ||
|  | 
 | ||
|  | # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) | ||
|  |   readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>()); | ||
|  |        | ||
|  |   // I think we don't really need this as it checks the same things as | ||
|  |   // the above code. | ||
|  |   BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value); | ||
|  | # endif  | ||
|  | } | ||
|  | 
 | ||
|  | template <class Iterator, class T> | ||
|  | void writable_iterator_test(Iterator i, T v, T v2) | ||
|  | { | ||
|  |   Iterator i2(i); // Copy Constructible | ||
|  |   *i2 = v; | ||
|  | 
 | ||
|  | # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) | ||
|  |   writable_iterator_traversal_test( | ||
|  |       i, v2, mpl::and_< | ||
|  |           detail::is_incrementable<Iterator> | ||
|  |         , detail::is_postfix_incrementable<Iterator> | ||
|  |       >()); | ||
|  | # endif  | ||
|  | } | ||
|  | 
 | ||
|  | template <class Iterator> | ||
|  | void swappable_iterator_test(Iterator i, Iterator j) | ||
|  | { | ||
|  |   Iterator i2(i), j2(j); | ||
|  |   typename detail::iterator_traits<Iterator>::value_type bi = *i, bj = *j; | ||
|  |   iter_swap(i2, j2); | ||
|  |   typename detail::iterator_traits<Iterator>::value_type ai = *i, aj = *j; | ||
|  |   BOOST_TEST(bi == aj && bj == ai); | ||
|  | } | ||
|  | 
 | ||
|  | template <class Iterator, class T> | ||
|  | void constant_lvalue_iterator_test(Iterator i, T v1) | ||
|  | { | ||
|  |   Iterator i2(i); | ||
|  |   typedef typename detail::iterator_traits<Iterator>::value_type value_type; | ||
|  |   typedef typename detail::iterator_traits<Iterator>::reference reference; | ||
|  |   BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value)); | ||
|  |   const T& v2 = *i2; | ||
|  |   BOOST_TEST(v1 == v2); | ||
|  | # ifndef BOOST_NO_LVALUE_RETURN_DETECTION | ||
|  |   BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value); | ||
|  |   BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value); | ||
|  | # endif  | ||
|  | } | ||
|  | 
 | ||
|  | template <class Iterator, class T> | ||
|  | void non_const_lvalue_iterator_test(Iterator i, T v1, T v2) | ||
|  | { | ||
|  |   Iterator i2(i); | ||
|  |   typedef typename detail::iterator_traits<Iterator>::value_type value_type; | ||
|  |   typedef typename detail::iterator_traits<Iterator>::reference reference; | ||
|  |   BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value)); | ||
|  |   T& v3 = *i2; | ||
|  |   BOOST_TEST(v1 == v3); | ||
|  |    | ||
|  |   // A non-const lvalue iterator is not neccessarily writable, but we | ||
|  |   // are assuming the value_type is assignable here | ||
|  |   *i = v2; | ||
|  |    | ||
|  |   T& v4 = *i2; | ||
|  |   BOOST_TEST(v2 == v4); | ||
|  | # ifndef BOOST_NO_LVALUE_RETURN_DETECTION | ||
|  |   BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value); | ||
|  |   BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value); | ||
|  | # endif  | ||
|  | } | ||
|  | 
 | ||
|  | template <class Iterator, class T> | ||
|  | void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2) | ||
|  | { | ||
|  |   Iterator i2; | ||
|  |   Iterator i3(i); | ||
|  |   i2 = i; | ||
|  |   BOOST_TEST(i2 == i3); | ||
|  |   BOOST_TEST(i != j); | ||
|  |   BOOST_TEST(i2 != j); | ||
|  |   readable_iterator_test(i, val1); | ||
|  |   readable_iterator_test(i2, val1); | ||
|  |   readable_iterator_test(i3, val1); | ||
|  | 
 | ||
|  |   BOOST_TEST(i == i2++); | ||
|  |   BOOST_TEST(i != ++i3); | ||
|  | 
 | ||
|  |   readable_iterator_test(i2, val2); | ||
|  |   readable_iterator_test(i3, val2); | ||
|  | 
 | ||
|  |   readable_iterator_test(i, val1); | ||
|  | } | ||
|  | 
 | ||
|  | template <class Iterator, class T> | ||
|  | void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2) | ||
|  | { | ||
|  |   forward_readable_iterator_test(i, j, val1, val2); | ||
|  |   Iterator i2 = i; | ||
|  |   ++i2; | ||
|  |   swappable_iterator_test(i, i2); | ||
|  | } | ||
|  | 
 | ||
|  | // bidirectional | ||
|  | // Preconditions: *i == v1, *++i == v2 | ||
|  | template <class Iterator, class T> | ||
|  | void bidirectional_readable_iterator_test(Iterator i, T v1, T v2) | ||
|  | { | ||
|  |   Iterator j(i); | ||
|  |   ++j; | ||
|  |   forward_readable_iterator_test(i, j, v1, v2); | ||
|  |   ++i; | ||
|  | 
 | ||
|  |   Iterator i1 = i, i2 = i; | ||
|  | 
 | ||
|  |   BOOST_TEST(i == i1--); | ||
|  |   BOOST_TEST(i != --i2); | ||
|  | 
 | ||
|  |   readable_iterator_test(i, v2); | ||
|  |   readable_iterator_test(i1, v1); | ||
|  |   readable_iterator_test(i2, v1); | ||
|  | 
 | ||
|  |   --i; | ||
|  |   BOOST_TEST(i == i1); | ||
|  |   BOOST_TEST(i == i2); | ||
|  |   ++i1; | ||
|  |   ++i2; | ||
|  | 
 | ||
|  |   readable_iterator_test(i, v1); | ||
|  |   readable_iterator_test(i1, v2); | ||
|  |   readable_iterator_test(i2, v2); | ||
|  | } | ||
|  | 
 | ||
|  | // random access | ||
|  | // Preconditions: [i,i+N) is a valid range | ||
|  | template <class Iterator, class TrueVals> | ||
|  | void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals) | ||
|  | { | ||
|  |   bidirectional_readable_iterator_test(i, vals[0], vals[1]); | ||
|  |   const Iterator j = i; | ||
|  |   int c; | ||
|  | 
 | ||
|  |   for (c = 0; c < N-1; ++c) | ||
|  |   { | ||
|  |     BOOST_TEST(i == j + c); | ||
|  |     BOOST_TEST(*i == vals[c]); | ||
|  |     typename detail::iterator_traits<Iterator>::value_type x = j[c]; | ||
|  |     BOOST_TEST(*i == x); | ||
|  |     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]); | ||
|  |     typename detail::iterator_traits<Iterator>::value_type x = j[N - 1 - c]; | ||
|  |     BOOST_TEST(*i == x); | ||
|  |     Iterator q = k - c;  | ||
|  |     BOOST_TEST(*i == *q); | ||
|  |     BOOST_TEST(i > j); | ||
|  |     BOOST_TEST(i >= j); | ||
|  |     BOOST_TEST(j <= i); | ||
|  |     BOOST_TEST(j < i); | ||
|  |     --i; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | } // namespace boost | ||
|  | 
 | ||
|  | # include <boost/iterator/detail/config_undef.hpp> | ||
|  | 
 | ||
|  | #endif // BOOST_NEW_ITERATOR_TESTS_HPP |