Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
23.deque.iterators.cpp
Go to the documentation of this file.
1
29#include <cstddef> // for size_t
30#include <deque> // for deque
31
32#include <rw_driver.h> // for rw_test()
33#include <rw_alg_test.h>
34
35#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
36 // disabled for compilers that can't reliably replace the operators
37
38 // replace operators new and delete with versions that invalidate
39 // storage to detect problems due to deque iterators accessing
40 // uninitialized pointers
41# include <rw_new.h>
42#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
43
44
46std::size_t new_capacity;
47
48typedef std::deque<int> IntDeque;
49
50namespace __rw {
51
53inline IntDeque::size_type
54__rw_new_capacity<IntDeque>(IntDeque::size_type n, const IntDeque*)
55{
56 if (n) {
57 // non-zero size argument indicates a request for an increase
58 // in the capacity of a deque object's dynamically sizable
59 // vector of nodes
60 return n * 2;
61 }
62
63 // zero size argument is a request for the initial size of a deque
64 // object's dynamically sizable vector of nodes or for the size of
65 // the objects's fixed-size buffer for elements
66 return new_capacity;
67}
68
69}
70
71
73template <class T>
74void test_iterators (std::size_t N, int dir, T*)
75{
76 typedef std::deque<T> Deque;
77 typedef typename Deque::difference_type Difference;
78 typedef typename Deque::size_type Size;
79 typedef typename Deque::value_type Value;
80 typedef typename Deque::iterator Iterator;
81 typedef typename Deque::const_iterator ConstIterator;
82
83 Deque d;
84
85 // fill `d' with the range of values [1, N)
86 if (dir < 0) {
87 for (std::size_t i = 0; i != N; ++i)
88 d.push_front (Value (N - i));
89 }
90 else if (dir > 0) {
91 for (std::size_t i = 0; i != N; ++i)
92 d.push_back (Value (i + 1));
93 }
94 else {
95 d = Deque (Size (N), Value ());
96 for (std::size_t i = 0; i != N; ++i)
97 d [i] = Value (i + 1);
98 }
99
100 const Iterator begin = d.begin ();
101 const Iterator end = d.end ();
102
103 Iterator i0 = begin;
104 Iterator i1 = end;
105
106 // convert N to Difference to avoid any potential issues
107 // due to integer promotion in expressions below (e.g.,
108 // on LP64)
109 const Difference N_diff = Difference (N);
110
111 for (std::size_t i = 0; i != N; ++i, ++i0, --i1) {
112
113 // convert i to Difference for the same reason as N above
114 const Difference i_diff = Difference (i);
115
116 // exercise iterator::operator*()
117 // and iterator::operator[](difference_type)
118 rw_assert (Value (i + 1) == *i0, 0, __LINE__,
119 "Expected iterator::operator*() value to be %d; got %d.",
120 Value (i + 1), *i0);
121
122 rw_assert (Value (N - i) == i0 [N_diff - 2 * i_diff - 1], 0, __LINE__,
123 "Expected value of iterator::operator[](%d) to be %d; "
124 "got %d.", N_diff - 2 * i_diff - 1, Value (N - i),
125 i0 [N_diff - 2 * i_diff - 1]);
126
127 rw_assert (Value (N - i) == i1 [Difference (-1)], 0, __LINE__,
128 "Expected value of iterator::operator[](%d) to be %d; "
129 "got %d.", Difference (-1), Value (N - i),
130 i1 [Difference (-1)]);
131
132 rw_assert (Value (i + 1) == i1 [2 * i_diff - N_diff], 0, __LINE__,
133 "Expected value of iterator::operator[](%d) to be %d; "
134 "got %d.", 2 * i_diff - N_diff, Value (i + 1),
135 i1 [2 * i_diff - N_diff]);
136
137 // exercise operator-(deque::iterator, deque::iterator)
138 Difference d0_begin = i0 - begin;
139 Difference d1_begin = i1 - begin;
140 Difference d0_end = end - i0;
141 Difference d1_end = end - i1;
142
143 rw_assert (d0_begin == Difference (i), 0, __LINE__,
144 "Expected value of operator-(deque::iterator, "
145 "deque::iterator) to be %d; got %d.",
146 Difference (i), d0_begin);
147
148 rw_assert (d1_begin == N_diff - i_diff, 0, __LINE__,
149 "Expected value of operator-(deque::iterator, "
150 "deque::iterator) to be %d; got %d.",
151 N_diff - i_diff, d1_begin);
152
153 rw_assert (d0_end == N_diff - i_diff, 0, __LINE__,
154 "Expected value of operator-(deque::iterator, "
155 "deque::iterator) to be %d; got %d.",
156 N_diff - i_diff, d0_end);
157
158 rw_assert (d1_end == i_diff, 0, __LINE__,
159 "Expected value of operator-(deque::iterator, "
160 "deque::iterator) to be %d; got %d.",
161 i_diff, d1_end);
162
163 // exercise operator+(deque::iterator, deque::difference_type),
164 // operator-(deque::iterator, deque::difference_type),
165 // operator==(deque::iterator, deque::iterator), and
166 // operator< (deque::iterator, deque::iterator)
167 const Iterator i_begin = begin + i_diff;
168 const Iterator i_end = end - (N_diff - i_diff);
169
170 rw_assert (i_begin == i0, 0, __LINE__,
171 "Expected operator==(deque::iterator, "
172 "deque::iterator) to evaluate true.");
173
174 rw_assert (i_end == i0, 0, __LINE__,
175 "Expected operator==(deque::iterator, "
176 "deque::iterator) to evaluate true.");
177
178 rw_assert (!(i_begin < i0), 0, __LINE__,
179 "Expected operator<(deque::iterator, "
180 "deque::iterator) to evaluate true.");
181
182 rw_assert (!(i_end < i0), 0, __LINE__,
183 "Expected operator<(deque::iterator, "
184 "deque::iterator) to evaluate true.");
185
186 d0_begin = i_begin - begin;
187 d0_end = end - i_end;
188
189 rw_assert (d0_begin == i_diff, 0, __LINE__,
190 "Expected operator==(deque::iterator, "
191 "deque::iterator) to evaluate true.");
192
193 rw_assert (d0_end == N_diff - i_diff, 0, __LINE__,
194 "Expected operator==(deque::iterator, "
195 "deque::iterator) to evaluate true.");
196
197 // exercise iterator::operator++() and iterator::operator--()
198 Iterator i2 = i0;
199 Iterator i3 = i0;
200
201 if (i && i < N - 1) {
202 ++i2;
203 rw_assert (i2 == i0 + 1, 0, __LINE__,
204 "Expected ++iterator(it) == it + 1.");
205
206 rw_assert (i0 < i2, 0, __LINE__,
207 "Expected it < ++iterator(it).");
208
209 rw_assert (!(i2 < i0), 0, __LINE__,
210 "Expected !(++iterator (it) < it) to yield true.");
211
212 rw_assert (i2 - i0 == Difference (+1), 0, __LINE__,
213 "Expected ++iterator(it) - it == 1.");
214
215 rw_assert (i0 - i2 == Difference (-1), 0, __LINE__,
216 "Expected it - (++iterator(it)) == -1");
217
218 i2 -= 1;
219
220 rw_assert (i2 - i0 == 0, 0, __LINE__,
221 "Expected (++iterator(it) - 1) - it == 0.");
222
223 rw_assert (i0 - i2 == 0, 0, __LINE__,
224 "Expected it - (++iterator(it) - 1) == 0.");
225
226 i3 -= 1;
227 rw_assert (i3 == i0 - 1, 0, __LINE__,
228 "Expected --iterator (it) == it - 1.");
229 rw_assert (i3 < i0, 0, __LINE__,
230 "Expected --iterator (it) < it.");
231 rw_assert (!(i0 < i3), 0, __LINE__,
232 "Expected !(it < --iterator (it)) to yield true.");
233
234 rw_assert (i3 - i0 == Difference (-1), 0, __LINE__,
235 "Expected (--iterator(it) - it) == -1.");
236
237 rw_assert (i0 - i3 == Difference (+1), 0, __LINE__,
238 "Expected (it - (--iterator(it))) == 1.");
239
240 ++i3;
241
242 rw_assert (i3 - i0 == 0, 0, __LINE__,
243 "Expected --iterator (it) + 1 - it == 0.");
244 rw_assert (i0 - i3 == 0, 0, __LINE__,
245 "Expected it - (--iterator (it) + 1) == 0.");
246 }
247
248 rw_assert (i2 == i0, 0, __LINE__,
249 "Expected iterators to be equal.");
250 rw_assert (i3 == i0, 0, __LINE__,
251 "Expected iterators to be equal.");
252 rw_assert (i2 == i3, 0, __LINE__,
253 "Expected iterators to be equal.");
254
255 rw_assert (!(i2 < i0), 0, __LINE__,
256 "Expected iterators to be equal.");
257 rw_assert (!(i3 < i0), 0, __LINE__,
258 "Expected iterators to be equal.");
259 rw_assert (!(i2 < i3), 0, __LINE__,
260 "Expected iterators to be equal.");
261 }
262}
263
264
266#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
267// replacement operator new is expensive, avoid long runtimes
268unsigned rw_opt_nloops = 6; // for --nloops
269#else
270unsigned rw_opt_nloops = 10; // for --nloops
271#endif
272
273int rw_opt_no_fill; // for --no-fill
274int rw_opt_no_push_back; // for --no-push_back
275int rw_opt_no_push_front; // for --no-push_front
276
277
278template <class T>
279void test_iterators (std::size_t N, T*)
280{
281 // avoid repeatedly noting that test has been disabled
282 static int push_back_noted;
283 static int push_front_noted;
284 static int fill_noted;
285
286 // fill deque by repeatedly calling either push_front() or push_back()
287
289 rw_note (push_back_noted++, 0, 0, "push_back test disabled");
290 else
291 test_iterators (N, -1, (T*)0);
292
293 if (rw_opt_no_fill)
294 rw_note (fill_noted++, 0, 0, "fill test disabled");
295 else
296 test_iterators (N, 0, (T*)0);
297
299 rw_note (push_front_noted++, 0, 0, "push_front test disabled");
300 else
301 test_iterators (N, 1, (T*)0);
302}
303
304
306int run_test (int, char**)
307{
308#ifdef _RWSTD_NO_DEBUG_ITER
309
310 // verify the size of deque<int>::iterator (space optimization
311 // available only when debugging iterators are not enabled)
312
313 const std::size_t itsize = sizeof (IntDeque::iterator);
314
315 rw_assert (itsize == 2 * sizeof (IntDeque::pointer), 0, __LINE__,
316 "sizeof(deque<int>::iterator) == %zu, got %zu "
317 "[space optimization]",
318 2 * sizeof (IntDeque::pointer), itsize);
319
320#endif // _RWSTD_NO_DEBUG_ITER
321
322 // capacity must be at least 2
323 for (std::size_t i = 2; i < rw_opt_nloops; ++i) {
324
325 // set the result of __rw::__rw_new_capacity() to override
326 // the container's allocation policy and force an early
327 // reallocation
328
329 new_capacity = i;
330
331 const IntDeque::size_type cap =
332 __rw::__rw_new_capacity (IntDeque::size_type (),
333 (const IntDeque*)0);
334
335 rw_info (0, 0, 0,
336 "__rw::__rw_new_capacity(std::deque<int>::"
337 "size_type, std::deque<int>*) = %zu", cap);
338
339 const std::size_t max_size = i * i * 10;
340
341 for (std::size_t j = 0; j != max_size; ++j) {
342
343 if (j % (max_size / 10) == 0)
344 rw_info (0, 0, 0, "std::deque<int>(%u, ...)", j);
345
346 test_iterators (j, (int*)0);
347 }
348 }
349
350 return 0;
351}
352
353
355int main (int argc, char** argv)
356{
357 return rw_test (argc, argv, __FILE__,
358 "lib.deque.iterators",
359 0 /* no comment */,
360 run_test,
361 "|-nloops#2 " // argument must be greater than 1
362 "|-no-push_back# "
363 "|-no-push_front# "
364 "|-no-fill#",
369}
InputIter< UserClass > Iterator
#define N
Definition 17.names.cpp:157
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define d
Definition 17.names.cpp:115
#define i2
Definition 17.names.cpp:259
#define j
Definition 17.names.cpp:127
#define i1
Definition 17.names.cpp:233
#define n
Definition 17.names.cpp:130
int run_test(int, char **)
void test_iterators(std::size_t N, int dir, T *)
unsigned rw_opt_nloops
int rw_opt_no_push_front
std::deque< int > IntDeque
int rw_opt_no_fill
int rw_opt_no_push_back
std::size_t new_capacity
#define Size(sig)
const int end
#define main
#define _RWSTD_SPECIALIZED_FUNCTION
Definition _defs.h:556
std::deque< std::string, std::allocator< std::string > > Deque
Definition deque.cpp:35
_RWSTD_SPECIALIZED_FUNCTION IntDeque::size_type __rw_new_capacity< IntDeque >(IntDeque::size_type n, const IntDeque *)
std::deque< int, std::allocator< int > > IntDeque
Definition radix.cpp:39
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_info(int, const char *, int, const char *,...)
Definition driver.cpp:1681
_TEST_EXPORT int rw_note(int, const char *, int, const char *,...)
Definition driver.cpp:1664
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630