📄 iterator_tests.hpp
字号:
// 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 <assert.h># include <boost/type_traits.hpp># include <boost/static_assert.hpp># include <boost/concept_archetype.hpp> // for detail::dummy_constructor# include <boost/implicit_cast.hpp># include <boost/type_traits/broken_compiler_spec.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;};}BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT) namespace boost {// 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; assert(i == i); assert(j == j); assert(i != j);#ifdef BOOST_NO_STD_ITERATOR_TRAITS T v = *i;#else typename std::iterator_traits<Iterator>::value_type v = *i;#endif assert(v == val);#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. assert(v == i->foo());#endif k = i; assert(k == k); assert(k == i); assert(k != j); assert(*k == val);}// 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); assert(i == i1); assert(!(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; // // assert(i != i2); // assert(!(i == i2)); assert(*i1 == v1); assert(*i == v1); // we cannot test for equivalence of (void)++i & (void)i++ // as i is only guaranteed to be single pass. assert(*i++ == v1); i1 = i; assert(i == i1); assert(!(i != i1)); assert(*i1 == v2); assert(*i == v2); // 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; assert(i == i1++); assert(i != ++i2); trivial_iterator_test(i, i1, v1); trivial_iterator_test(i, i2, v1); ++i; assert(i == i1); assert(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; assert(i == i1--); assert(i != --i2); trivial_iterator_test(i, i1, v2); trivial_iterator_test(i, i2, v2); --i; assert(i == i1); assert(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 boost::detail::iterator_traits<Iterator>::value_type value_type; for (c = 0; c < N-1; ++c) { assert(i == j + c); assert(*i == vals[c]); assert(*i == boost::implicit_cast<value_type>(j[c])); assert(*i == *(j + c)); assert(*i == *(c + j)); ++i; assert(i > j); assert(i >= j); assert(j <= i); assert(j < i); } Iterator k = j + N - 1; for (c = 0; c < N-1; ++c) { assert(i == k - c); assert(*i == vals[N - 1 - c]); assert(*i == boost::implicit_cast<value_type>(j[N - 1 - c])); Iterator q = k - c; assert(*i == *q); assert(i > j); assert(i >= j); assert(j <= i); assert(j < i); --i; }}// Precondition: i != jtemplate <class Iterator, class ConstIterator>void const_nonconst_iterator_test(Iterator i, ConstIterator j){ assert(i != j); assert(j != i); ConstIterator k(i); assert(k == i); assert(i == k); k = i; assert(k == i); assert(i == k);}} // namespace boost#endif // BOOST_ITERATOR_TESTS_HPP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -