Chris@16: #ifndef BOOST_NEW_ITERATOR_TESTS_HPP Chris@16: # define BOOST_NEW_ITERATOR_TESTS_HPP Chris@16: Chris@16: // Chris@16: // Copyright (c) David Abrahams 2001. Chris@16: // Copyright (c) Jeremy Siek 2001-2003. Chris@16: // Copyright (c) Thomas Witt 2002. Chris@16: // Chris@16: // Use, modification and distribution is subject to the Chris@16: // Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: // This is meant to be the beginnings of a comprehensive, generic Chris@16: // test suite for STL concepts such as iterators and containers. Chris@16: // Chris@16: // Revision History: Chris@16: // 28 Oct 2002 Started update for new iterator categories Chris@16: // (Jeremy Siek) Chris@16: // 28 Apr 2002 Fixed input iterator requirements. Chris@16: // For a == b a++ == b++ is no longer required. Chris@16: // See 24.1.1/3 for details. Chris@16: // (Thomas Witt) Chris@16: // 08 Feb 2001 Fixed bidirectional iterator test so that Chris@16: // --i is no longer a precondition. Chris@16: // (Jeremy Siek) Chris@16: // 04 Feb 2001 Added lvalue test, corrected preconditions Chris@16: // (David Abrahams) Chris@16: Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include // for detail::dummy_constructor Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: Chris@16: // Do separate tests for *i++ so we can treat, e.g., smart pointers, Chris@16: // as readable and/or writable iterators. Chris@16: template Chris@16: void readable_iterator_traversal_test(Iterator i1, T v, mpl::true_) Chris@16: { Chris@16: T v2(*i1++); Chris@16: BOOST_TEST(v == v2); Chris@16: } Chris@16: Chris@16: template Chris@16: void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_) Chris@16: {} Chris@16: Chris@16: template Chris@16: void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_) Chris@16: { Chris@16: ++i1; // we just wrote into that position Chris@16: *i1++ = v; Chris@16: Iterator x(i1++); Chris@16: (void)x; Chris@16: } Chris@16: Chris@16: template Chris@16: void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_) Chris@16: {} Chris@16: Chris@16: Chris@16: // Preconditions: *i == v Chris@16: template Chris@16: void readable_iterator_test(const Iterator i1, T v) Chris@16: { Chris@16: Iterator i2(i1); // Copy Constructible Chris@16: typedef typename detail::iterator_traits::reference ref_t; Chris@16: ref_t r1 = *i1; Chris@16: ref_t r2 = *i2; Chris@16: T v1 = r1; Chris@16: T v2 = r2; Chris@16: BOOST_TEST(v1 == v); Chris@16: BOOST_TEST(v2 == v); Chris@16: Chris@16: # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) Chris@16: readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable()); Chris@16: Chris@16: // I think we don't really need this as it checks the same things as Chris@16: // the above code. Chris@16: BOOST_STATIC_ASSERT(is_readable_iterator::value); Chris@16: # endif Chris@16: } Chris@16: Chris@16: template Chris@16: void writable_iterator_test(Iterator i, T v, T v2) Chris@16: { Chris@16: Iterator i2(i); // Copy Constructible Chris@16: *i2 = v; Chris@16: Chris@16: # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) Chris@16: writable_iterator_traversal_test( Chris@16: i, v2, mpl::and_< Chris@16: detail::is_incrementable Chris@16: , detail::is_postfix_incrementable Chris@16: >()); Chris@16: # endif Chris@16: } Chris@16: Chris@16: template Chris@16: void swappable_iterator_test(Iterator i, Iterator j) Chris@16: { Chris@16: Iterator i2(i), j2(j); Chris@16: typename detail::iterator_traits::value_type bi = *i, bj = *j; Chris@16: iter_swap(i2, j2); Chris@16: typename detail::iterator_traits::value_type ai = *i, aj = *j; Chris@16: BOOST_TEST(bi == aj && bj == ai); Chris@16: } Chris@16: Chris@16: template Chris@16: void constant_lvalue_iterator_test(Iterator i, T v1) Chris@16: { Chris@16: Iterator i2(i); Chris@16: typedef typename detail::iterator_traits::value_type value_type; Chris@16: typedef typename detail::iterator_traits::reference reference; Chris@16: BOOST_STATIC_ASSERT((is_same::value)); Chris@16: const T& v2 = *i2; Chris@16: BOOST_TEST(v1 == v2); Chris@16: # ifndef BOOST_NO_LVALUE_RETURN_DETECTION Chris@16: BOOST_STATIC_ASSERT(is_lvalue_iterator::value); Chris@16: BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator::value); Chris@16: # endif Chris@16: } Chris@16: Chris@16: template Chris@16: void non_const_lvalue_iterator_test(Iterator i, T v1, T v2) Chris@16: { Chris@16: Iterator i2(i); Chris@16: typedef typename detail::iterator_traits::value_type value_type; Chris@16: typedef typename detail::iterator_traits::reference reference; Chris@16: BOOST_STATIC_ASSERT((is_same::value)); Chris@16: T& v3 = *i2; Chris@16: BOOST_TEST(v1 == v3); Chris@16: Chris@16: // A non-const lvalue iterator is not neccessarily writable, but we Chris@16: // are assuming the value_type is assignable here Chris@16: *i = v2; Chris@16: Chris@16: T& v4 = *i2; Chris@16: BOOST_TEST(v2 == v4); Chris@16: # ifndef BOOST_NO_LVALUE_RETURN_DETECTION Chris@16: BOOST_STATIC_ASSERT(is_lvalue_iterator::value); Chris@16: BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator::value); Chris@16: # endif Chris@16: } Chris@16: Chris@16: template Chris@16: void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2) Chris@16: { Chris@16: Iterator i2; Chris@16: Iterator i3(i); Chris@16: i2 = i; Chris@16: BOOST_TEST(i2 == i3); Chris@16: BOOST_TEST(i != j); Chris@16: BOOST_TEST(i2 != j); Chris@16: readable_iterator_test(i, val1); Chris@16: readable_iterator_test(i2, val1); Chris@16: readable_iterator_test(i3, val1); Chris@16: Chris@16: BOOST_TEST(i == i2++); Chris@16: BOOST_TEST(i != ++i3); Chris@16: Chris@16: readable_iterator_test(i2, val2); Chris@16: readable_iterator_test(i3, val2); Chris@16: Chris@16: readable_iterator_test(i, val1); Chris@16: } Chris@16: Chris@16: template Chris@16: void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2) Chris@16: { Chris@16: forward_readable_iterator_test(i, j, val1, val2); Chris@16: Iterator i2 = i; Chris@16: ++i2; Chris@16: swappable_iterator_test(i, i2); Chris@16: } Chris@16: Chris@16: // bidirectional Chris@16: // Preconditions: *i == v1, *++i == v2 Chris@16: template Chris@16: void bidirectional_readable_iterator_test(Iterator i, T v1, T v2) Chris@16: { Chris@16: Iterator j(i); Chris@16: ++j; Chris@16: forward_readable_iterator_test(i, j, v1, v2); Chris@16: ++i; Chris@16: Chris@16: Iterator i1 = i, i2 = i; Chris@16: Chris@16: BOOST_TEST(i == i1--); Chris@16: BOOST_TEST(i != --i2); Chris@16: Chris@16: readable_iterator_test(i, v2); Chris@16: readable_iterator_test(i1, v1); Chris@16: readable_iterator_test(i2, v1); Chris@16: Chris@16: --i; Chris@16: BOOST_TEST(i == i1); Chris@16: BOOST_TEST(i == i2); Chris@16: ++i1; Chris@16: ++i2; Chris@16: Chris@16: readable_iterator_test(i, v1); Chris@16: readable_iterator_test(i1, v2); Chris@16: readable_iterator_test(i2, v2); Chris@16: } Chris@16: Chris@16: // random access Chris@16: // Preconditions: [i,i+N) is a valid range Chris@16: template Chris@16: void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals) Chris@16: { Chris@16: bidirectional_readable_iterator_test(i, vals[0], vals[1]); Chris@16: const Iterator j = i; Chris@16: int c; Chris@16: Chris@16: for (c = 0; c < N-1; ++c) Chris@16: { Chris@16: BOOST_TEST(i == j + c); Chris@16: BOOST_TEST(*i == vals[c]); Chris@16: typename detail::iterator_traits::value_type x = j[c]; Chris@16: BOOST_TEST(*i == x); Chris@16: BOOST_TEST(*i == *(j + c)); Chris@16: BOOST_TEST(*i == *(c + j)); Chris@16: ++i; Chris@16: BOOST_TEST(i > j); Chris@16: BOOST_TEST(i >= j); Chris@16: BOOST_TEST(j <= i); Chris@16: BOOST_TEST(j < i); Chris@16: } Chris@16: Chris@16: Iterator k = j + N - 1; Chris@16: for (c = 0; c < N-1; ++c) Chris@16: { Chris@16: BOOST_TEST(i == k - c); Chris@16: BOOST_TEST(*i == vals[N - 1 - c]); Chris@16: typename detail::iterator_traits::value_type x = j[N - 1 - c]; Chris@16: BOOST_TEST(*i == x); Chris@16: Iterator q = k - c; Chris@16: BOOST_TEST(*i == *q); Chris@16: BOOST_TEST(i > j); Chris@16: BOOST_TEST(i >= j); Chris@16: BOOST_TEST(j <= i); Chris@16: BOOST_TEST(j < i); Chris@16: --i; Chris@16: } Chris@16: } Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: # include Chris@16: Chris@16: #endif // BOOST_NEW_ITERATOR_TESTS_HPP