~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to boost/boost/pending/iterator_tests.hpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

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