Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:54:09

0001 // Copyright David Abrahams and Jeremy Siek 2003.
0002 // Distributed under the Boost Software License, Version 1.0. (See
0003 // accompanying file LICENSE_1_0.txt or copy at
0004 // http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef BOOST_ITERATOR_TESTS_HPP
0006 # define BOOST_ITERATOR_TESTS_HPP
0007 
0008 // This is meant to be the beginnings of a comprehensive, generic
0009 // test suite for STL concepts such as iterators and containers.
0010 //
0011 // Revision History:
0012 // 28 Apr 2002  Fixed input iterator requirements.
0013 //              For a == b a++ == b++ is no longer required.
0014 //              See 24.1.1/3 for details.
0015 //              (Thomas Witt)
0016 // 08 Feb 2001  Fixed bidirectional iterator test so that
0017 //              --i is no longer a precondition.
0018 //              (Jeremy Siek)
0019 // 04 Feb 2001  Added lvalue test, corrected preconditions
0020 //              (David Abrahams)
0021 
0022 # include <iterator>
0023 # include <type_traits>
0024 # include <boost/concept_archetype.hpp> // for detail::dummy_constructor
0025 # include <boost/core/ignore_unused.hpp>
0026 # include <boost/core/lightweight_test.hpp>
0027 
0028 namespace boost {
0029 
0030   // use this for the value type
0031 struct dummyT {
0032   dummyT() { }
0033   dummyT(detail::dummy_constructor) { }
0034   dummyT(int x) : m_x(x) { }
0035   int foo() const { return m_x; }
0036   bool operator==(const dummyT& d) const { return m_x == d.m_x; }
0037   int m_x;
0038 };
0039 
0040 }
0041 
0042 namespace boost {
0043 namespace iterators {
0044 
0045 // Tests whether type Iterator satisfies the requirements for a
0046 // TrivialIterator.
0047 // Preconditions: i != j, *i == val
0048 template <class Iterator, class T>
0049 void trivial_iterator_test(const Iterator i, const Iterator j, T val)
0050 {
0051   Iterator k;
0052   BOOST_TEST(i == i);
0053   BOOST_TEST(j == j);
0054   BOOST_TEST(i != j);
0055 #ifdef BOOST_NO_STD_ITERATOR_TRAITS
0056   T v = *i;
0057 #else
0058   typename std::iterator_traits<Iterator>::value_type v = *i;
0059 #endif
0060   BOOST_TEST(v == val);
0061   boost::ignore_unused(v);
0062 #if 0
0063   // hmm, this will give a warning for transform_iterator...  perhaps
0064   // this should be separated out into a stand-alone test since there
0065   // are several situations where it can't be used, like for
0066   // integer_range::iterator.
0067   BOOST_TEST(v == i->foo());
0068 #endif
0069   k = i;
0070   BOOST_TEST(k == k);
0071   BOOST_TEST(k == i);
0072   BOOST_TEST(k != j);
0073   BOOST_TEST(*k == val);
0074   boost::ignore_unused(k);
0075 }
0076 
0077 
0078 // Preconditions: i != j
0079 template <class Iterator, class T>
0080 void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
0081 {
0082   *i = val;
0083   trivial_iterator_test(i, j, val);
0084 }
0085 
0086 
0087 // Preconditions: *i == v1, *++i == v2
0088 template <class Iterator, class T>
0089 void input_iterator_test(Iterator i, T v1, T v2)
0090 {
0091   Iterator i1(i);
0092 
0093   BOOST_TEST(i == i1);
0094   BOOST_TEST(!(i != i1));
0095 
0096   // I can see no generic way to create an input iterator
0097   // that is in the domain of== of i and != i.
0098   // The following works for istream_iterator but is not
0099   // guaranteed to work for arbitrary input iterators.
0100   //
0101   //   Iterator i2;
0102   //
0103   //   BOOST_TEST(i != i2);
0104   //   BOOST_TEST(!(i == i2));
0105 
0106   BOOST_TEST(*i1 == v1);
0107   BOOST_TEST(*i  == v1);
0108 
0109   // we cannot test for equivalence of (void)++i & (void)i++
0110   // as i is only guaranteed to be single pass.
0111   BOOST_TEST(*i++ == v1);
0112   boost::ignore_unused(i1);
0113 
0114   i1 = i;
0115 
0116   BOOST_TEST(i == i1);
0117   BOOST_TEST(!(i != i1));
0118 
0119   BOOST_TEST(*i1 == v2);
0120   BOOST_TEST(*i  == v2);
0121   boost::ignore_unused(i1);
0122 
0123   // i is dereferencable, so it must be incrementable.
0124   ++i;
0125 
0126   // how to test for operator-> ?
0127 }
0128 
0129 // how to test output iterator?
0130 
0131 
0132 template <bool is_pointer> struct lvalue_test
0133 {
0134     template <class Iterator> static void check(Iterator)
0135     {
0136 # ifndef BOOST_NO_STD_ITERATOR_TRAITS
0137         typedef typename std::iterator_traits<Iterator>::reference reference;
0138         typedef typename std::iterator_traits<Iterator>::value_type value_type;
0139 # else
0140         typedef typename Iterator::reference reference;
0141         typedef typename Iterator::value_type value_type;
0142 # endif
0143         static_assert(std::is_reference<reference>::value, "reference must be a reference type.");
0144         static_assert(
0145             std::is_same<reference, value_type&>::value || std::is_same<reference, const value_type&>::value,
0146             "reference must either be a reference to value_type or constant reference to value_type."
0147         );
0148     }
0149 };
0150 
0151 # ifdef BOOST_NO_STD_ITERATOR_TRAITS
0152 template <> struct lvalue_test<true> {
0153     template <class T> static void check(T) {}
0154 };
0155 #endif
0156 
0157 template <class Iterator, class T>
0158 void forward_iterator_test(Iterator i, T v1, T v2)
0159 {
0160   input_iterator_test(i, v1, v2);
0161 
0162   Iterator i1 = i, i2 = i;
0163 
0164   BOOST_TEST(i == i1++);
0165   BOOST_TEST(i != ++i2);
0166 
0167   trivial_iterator_test(i, i1, v1);
0168   trivial_iterator_test(i, i2, v1);
0169 
0170   ++i;
0171   BOOST_TEST(i == i1);
0172   BOOST_TEST(i == i2);
0173   ++i1;
0174   ++i2;
0175 
0176   trivial_iterator_test(i, i1, v2);
0177   trivial_iterator_test(i, i2, v2);
0178 
0179  // borland doesn't allow non-type template parameters
0180 # if !defined(BOOST_BORLANDC) || (BOOST_BORLANDC > 0x551)
0181   lvalue_test<std::is_pointer<Iterator>::value>::check(i);
0182 #endif
0183 }
0184 
0185 // Preconditions: *i == v1, *++i == v2
0186 template <class Iterator, class T>
0187 void bidirectional_iterator_test(Iterator i, T v1, T v2)
0188 {
0189   forward_iterator_test(i, v1, v2);
0190   ++i;
0191 
0192   Iterator i1 = i, i2 = i;
0193 
0194   BOOST_TEST(i == i1--);
0195   BOOST_TEST(i != --i2);
0196 
0197   trivial_iterator_test(i, i1, v2);
0198   trivial_iterator_test(i, i2, v2);
0199 
0200   --i;
0201   BOOST_TEST(i == i1);
0202   BOOST_TEST(i == i2);
0203   ++i1;
0204   ++i2;
0205 
0206   trivial_iterator_test(i, i1, v1);
0207   trivial_iterator_test(i, i2, v1);
0208 }
0209 
0210 // mutable_bidirectional_iterator_test
0211 
0212 template <class U> struct undefined;
0213 
0214 // Preconditions: [i,i+N) is a valid range
0215 template <class Iterator, class TrueVals>
0216 void random_access_iterator_test(Iterator i, int N, TrueVals vals)
0217 {
0218   bidirectional_iterator_test(i, vals[0], vals[1]);
0219   const Iterator j = i;
0220   int c;
0221 
0222   typedef typename std::iterator_traits<Iterator>::value_type value_type;
0223   struct local
0224   {
0225     static value_type to_value_type(value_type v) { return v; }
0226   };
0227 
0228   for (c = 0; c < N-1; ++c) {
0229     BOOST_TEST(i == j + c);
0230     BOOST_TEST(*i == vals[c]);
0231     BOOST_TEST(*i == local::to_value_type(j[c]));
0232     BOOST_TEST(*i == *(j + c));
0233     BOOST_TEST(*i == *(c + j));
0234     ++i;
0235     BOOST_TEST(i > j);
0236     BOOST_TEST(i >= j);
0237     BOOST_TEST(j <= i);
0238     BOOST_TEST(j < i);
0239   }
0240 
0241   Iterator k = j + N - 1;
0242   for (c = 0; c < N-1; ++c) {
0243     BOOST_TEST(i == k - c);
0244     BOOST_TEST(*i == vals[N - 1 - c]);
0245     BOOST_TEST(*i == local::to_value_type(j[N - 1 - c]));
0246     Iterator q = k - c;
0247     boost::ignore_unused(q);
0248     BOOST_TEST(*i == *q);
0249     BOOST_TEST(i > j);
0250     BOOST_TEST(i >= j);
0251     BOOST_TEST(j <= i);
0252     BOOST_TEST(j < i);
0253     --i;
0254   }
0255 }
0256 
0257 // Precondition: i != j
0258 template <class Iterator, class ConstIterator>
0259 void const_nonconst_iterator_test(Iterator i, ConstIterator j)
0260 {
0261   BOOST_TEST(i != j);
0262   BOOST_TEST(j != i);
0263 
0264   ConstIterator k(i);
0265   BOOST_TEST(k == i);
0266   BOOST_TEST(i == k);
0267 
0268   k = i;
0269   BOOST_TEST(k == i);
0270   BOOST_TEST(i == k);
0271   boost::ignore_unused(k);
0272 }
0273 
0274 } // namespace iterators
0275 
0276 using iterators::undefined;
0277 using iterators::trivial_iterator_test;
0278 using iterators::mutable_trivial_iterator_test;
0279 using iterators::input_iterator_test;
0280 using iterators::lvalue_test;
0281 using iterators::forward_iterator_test;
0282 using iterators::bidirectional_iterator_test;
0283 using iterators::random_access_iterator_test;
0284 using iterators::const_nonconst_iterator_test;
0285 
0286 } // namespace boost
0287 
0288 #endif // BOOST_ITERATOR_TESTS_HPP