annotate DEPENDENCIES/generic/include/boost/pending/iterator_tests.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
rev   line source
Chris@16 1 // Copyright David Abrahams and Jeremy Siek 2003.
Chris@16 2 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 3 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 4 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5 #ifndef BOOST_ITERATOR_TESTS_HPP
Chris@16 6 # define BOOST_ITERATOR_TESTS_HPP
Chris@16 7
Chris@16 8 // This is meant to be the beginnings of a comprehensive, generic
Chris@16 9 // test suite for STL concepts such as iterators and containers.
Chris@16 10 //
Chris@16 11 // Revision History:
Chris@16 12 // 28 Apr 2002 Fixed input iterator requirements.
Chris@16 13 // For a == b a++ == b++ is no longer required.
Chris@16 14 // See 24.1.1/3 for details.
Chris@16 15 // (Thomas Witt)
Chris@16 16 // 08 Feb 2001 Fixed bidirectional iterator test so that
Chris@16 17 // --i is no longer a precondition.
Chris@16 18 // (Jeremy Siek)
Chris@16 19 // 04 Feb 2001 Added lvalue test, corrected preconditions
Chris@16 20 // (David Abrahams)
Chris@16 21
Chris@16 22 # include <iterator>
Chris@16 23 # include <assert.h>
Chris@16 24 # include <boost/type_traits.hpp>
Chris@16 25 # include <boost/static_assert.hpp>
Chris@16 26 # include <boost/concept_archetype.hpp> // for detail::dummy_constructor
Chris@16 27 # include <boost/implicit_cast.hpp>
Chris@16 28 # include <boost/type_traits/broken_compiler_spec.hpp>
Chris@16 29
Chris@16 30 namespace boost {
Chris@16 31
Chris@16 32 // use this for the value type
Chris@16 33 struct dummyT {
Chris@16 34 dummyT() { }
Chris@16 35 dummyT(detail::dummy_constructor) { }
Chris@16 36 dummyT(int x) : m_x(x) { }
Chris@16 37 int foo() const { return m_x; }
Chris@16 38 bool operator==(const dummyT& d) const { return m_x == d.m_x; }
Chris@16 39 int m_x;
Chris@16 40 };
Chris@16 41
Chris@16 42 }
Chris@16 43
Chris@16 44 BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
Chris@16 45
Chris@16 46 namespace boost {
Chris@16 47
Chris@16 48 // Tests whether type Iterator satisfies the requirements for a
Chris@16 49 // TrivialIterator.
Chris@16 50 // Preconditions: i != j, *i == val
Chris@16 51 template <class Iterator, class T>
Chris@16 52 void trivial_iterator_test(const Iterator i, const Iterator j, T val)
Chris@16 53 {
Chris@16 54 Iterator k;
Chris@16 55 assert(i == i);
Chris@16 56 assert(j == j);
Chris@16 57 assert(i != j);
Chris@16 58 #ifdef BOOST_NO_STD_ITERATOR_TRAITS
Chris@16 59 T v = *i;
Chris@16 60 #else
Chris@16 61 typename std::iterator_traits<Iterator>::value_type v = *i;
Chris@16 62 #endif
Chris@16 63 assert(v == val);
Chris@16 64 #if 0
Chris@16 65 // hmm, this will give a warning for transform_iterator... perhaps
Chris@16 66 // this should be separated out into a stand-alone test since there
Chris@16 67 // are several situations where it can't be used, like for
Chris@16 68 // integer_range::iterator.
Chris@16 69 assert(v == i->foo());
Chris@16 70 #endif
Chris@16 71 k = i;
Chris@16 72 assert(k == k);
Chris@16 73 assert(k == i);
Chris@16 74 assert(k != j);
Chris@16 75 assert(*k == val);
Chris@16 76 }
Chris@16 77
Chris@16 78
Chris@16 79 // Preconditions: i != j
Chris@16 80 template <class Iterator, class T>
Chris@16 81 void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
Chris@16 82 {
Chris@16 83 *i = val;
Chris@16 84 trivial_iterator_test(i, j, val);
Chris@16 85 }
Chris@16 86
Chris@16 87
Chris@16 88 // Preconditions: *i == v1, *++i == v2
Chris@16 89 template <class Iterator, class T>
Chris@16 90 void input_iterator_test(Iterator i, T v1, T v2)
Chris@16 91 {
Chris@16 92 Iterator i1(i);
Chris@16 93
Chris@16 94 assert(i == i1);
Chris@16 95 assert(!(i != i1));
Chris@16 96
Chris@16 97 // I can see no generic way to create an input iterator
Chris@16 98 // that is in the domain of== of i and != i.
Chris@16 99 // The following works for istream_iterator but is not
Chris@16 100 // guaranteed to work for arbitrary input iterators.
Chris@16 101 //
Chris@16 102 // Iterator i2;
Chris@16 103 //
Chris@16 104 // assert(i != i2);
Chris@16 105 // assert(!(i == i2));
Chris@16 106
Chris@16 107 assert(*i1 == v1);
Chris@16 108 assert(*i == v1);
Chris@16 109
Chris@16 110 // we cannot test for equivalence of (void)++i & (void)i++
Chris@16 111 // as i is only guaranteed to be single pass.
Chris@16 112 assert(*i++ == v1);
Chris@16 113
Chris@16 114 i1 = i;
Chris@16 115
Chris@16 116 assert(i == i1);
Chris@16 117 assert(!(i != i1));
Chris@16 118
Chris@16 119 assert(*i1 == v2);
Chris@16 120 assert(*i == v2);
Chris@16 121
Chris@16 122 // i is dereferencable, so it must be incrementable.
Chris@16 123 ++i;
Chris@16 124
Chris@16 125 // how to test for operator-> ?
Chris@16 126 }
Chris@16 127
Chris@16 128 // how to test output iterator?
Chris@16 129
Chris@16 130
Chris@16 131 template <bool is_pointer> struct lvalue_test
Chris@16 132 {
Chris@16 133 template <class Iterator> static void check(Iterator)
Chris@16 134 {
Chris@16 135 # ifndef BOOST_NO_STD_ITERATOR_TRAITS
Chris@16 136 typedef typename std::iterator_traits<Iterator>::reference reference;
Chris@16 137 typedef typename std::iterator_traits<Iterator>::value_type value_type;
Chris@16 138 # else
Chris@16 139 typedef typename Iterator::reference reference;
Chris@16 140 typedef typename Iterator::value_type value_type;
Chris@16 141 # endif
Chris@16 142 BOOST_STATIC_ASSERT(boost::is_reference<reference>::value);
Chris@16 143 BOOST_STATIC_ASSERT((boost::is_same<reference,value_type&>::value
Chris@16 144 || boost::is_same<reference,const value_type&>::value
Chris@16 145 ));
Chris@16 146 }
Chris@16 147 };
Chris@16 148
Chris@16 149 # ifdef BOOST_NO_STD_ITERATOR_TRAITS
Chris@16 150 template <> struct lvalue_test<true> {
Chris@16 151 template <class T> static void check(T) {}
Chris@16 152 };
Chris@16 153 #endif
Chris@16 154
Chris@16 155 template <class Iterator, class T>
Chris@16 156 void forward_iterator_test(Iterator i, T v1, T v2)
Chris@16 157 {
Chris@16 158 input_iterator_test(i, v1, v2);
Chris@16 159
Chris@16 160 Iterator i1 = i, i2 = i;
Chris@16 161
Chris@16 162 assert(i == i1++);
Chris@16 163 assert(i != ++i2);
Chris@16 164
Chris@16 165 trivial_iterator_test(i, i1, v1);
Chris@16 166 trivial_iterator_test(i, i2, v1);
Chris@16 167
Chris@16 168 ++i;
Chris@16 169 assert(i == i1);
Chris@16 170 assert(i == i2);
Chris@16 171 ++i1;
Chris@16 172 ++i2;
Chris@16 173
Chris@16 174 trivial_iterator_test(i, i1, v2);
Chris@16 175 trivial_iterator_test(i, i2, v2);
Chris@16 176
Chris@16 177 // borland doesn't allow non-type template parameters
Chris@16 178 # if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
Chris@16 179 lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);
Chris@16 180 #endif
Chris@16 181 }
Chris@16 182
Chris@16 183 // Preconditions: *i == v1, *++i == v2
Chris@16 184 template <class Iterator, class T>
Chris@16 185 void bidirectional_iterator_test(Iterator i, T v1, T v2)
Chris@16 186 {
Chris@16 187 forward_iterator_test(i, v1, v2);
Chris@16 188 ++i;
Chris@16 189
Chris@16 190 Iterator i1 = i, i2 = i;
Chris@16 191
Chris@16 192 assert(i == i1--);
Chris@16 193 assert(i != --i2);
Chris@16 194
Chris@16 195 trivial_iterator_test(i, i1, v2);
Chris@16 196 trivial_iterator_test(i, i2, v2);
Chris@16 197
Chris@16 198 --i;
Chris@16 199 assert(i == i1);
Chris@16 200 assert(i == i2);
Chris@16 201 ++i1;
Chris@16 202 ++i2;
Chris@16 203
Chris@16 204 trivial_iterator_test(i, i1, v1);
Chris@16 205 trivial_iterator_test(i, i2, v1);
Chris@16 206 }
Chris@16 207
Chris@16 208 // mutable_bidirectional_iterator_test
Chris@16 209
Chris@16 210 template <class U> struct undefined;
Chris@16 211
Chris@16 212 // Preconditions: [i,i+N) is a valid range
Chris@16 213 template <class Iterator, class TrueVals>
Chris@16 214 void random_access_iterator_test(Iterator i, int N, TrueVals vals)
Chris@16 215 {
Chris@16 216 bidirectional_iterator_test(i, vals[0], vals[1]);
Chris@16 217 const Iterator j = i;
Chris@16 218 int c;
Chris@16 219
Chris@16 220 typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
Chris@16 221
Chris@16 222 for (c = 0; c < N-1; ++c) {
Chris@16 223 assert(i == j + c);
Chris@16 224 assert(*i == vals[c]);
Chris@16 225 assert(*i == boost::implicit_cast<value_type>(j[c]));
Chris@16 226 assert(*i == *(j + c));
Chris@16 227 assert(*i == *(c + j));
Chris@16 228 ++i;
Chris@16 229 assert(i > j);
Chris@16 230 assert(i >= j);
Chris@16 231 assert(j <= i);
Chris@16 232 assert(j < i);
Chris@16 233 }
Chris@16 234
Chris@16 235 Iterator k = j + N - 1;
Chris@16 236 for (c = 0; c < N-1; ++c) {
Chris@16 237 assert(i == k - c);
Chris@16 238 assert(*i == vals[N - 1 - c]);
Chris@16 239 assert(*i == boost::implicit_cast<value_type>(j[N - 1 - c]));
Chris@16 240 Iterator q = k - c;
Chris@16 241 assert(*i == *q);
Chris@16 242 assert(i > j);
Chris@16 243 assert(i >= j);
Chris@16 244 assert(j <= i);
Chris@16 245 assert(j < i);
Chris@16 246 --i;
Chris@16 247 }
Chris@16 248 }
Chris@16 249
Chris@16 250 // Precondition: i != j
Chris@16 251 template <class Iterator, class ConstIterator>
Chris@16 252 void const_nonconst_iterator_test(Iterator i, ConstIterator j)
Chris@16 253 {
Chris@16 254 assert(i != j);
Chris@16 255 assert(j != i);
Chris@16 256
Chris@16 257 ConstIterator k(i);
Chris@16 258 assert(k == i);
Chris@16 259 assert(i == k);
Chris@16 260
Chris@16 261 k = i;
Chris@16 262 assert(k == i);
Chris@16 263 assert(i == k);
Chris@16 264 }
Chris@16 265
Chris@16 266 } // namespace boost
Chris@16 267
Chris@16 268 #endif // BOOST_ITERATOR_TESTS_HPP