Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
rw_containers.h
Go to the documentation of this file.
1
27#ifndef RW_23_CONTAINERS_H_INCLUDED
28#define RW_23_CONTAINERS_H_INCLUDED
29
30#include <rw_testdefs.h>
31#include <rw_value.h> // for UserClass, UserPOD
32#include <rw_char.h> // for rw_expand ()
33
34
36// defines enumerations identifying the general template arguments,
37// sets of overloaded functions, member types used in the declarations
38// of their signatures, and specific overloads of such member functions
40
41 // identifiers for the T template argument
43
44 // identifiers for the Allocator template argument
46
47 // identifiers for the Iterator template argument
48 // used with member templates
55 };
56
59 };
60
61 // identifies a set of overloaded member or non-member
62 // container functions
63 enum FuncId {
64 // 6 bits, 64 functions max
65 // common
66 /* 0 */ fid_ctor,
67 /* 1 */ fid_op_set,
68 /* 2 */ fid_assign,
70 /* 4 */ fid_begin,
72 /* 5 */ fid_end,
74 /* 6 */ fid_rbegin,
76 /* 7 */ fid_rend,
78 /* 8 */ fid_empty,
79 /* 9 */ fid_size,
80 /* 10 */ fid_max_size,
81 /* 11 */ fid_resize,
82 /* 12 */ fid_insert,
83 /* 13 */ fid_erase,
84 /* 14 */ fid_swap,
85 /* 15 */ fid_clear,
86 /* 16 */ fid_op_equal,
87 /* 17 */ fid_op_less,
92 /* 22 */ fid_push_back,
93
94 // list, deque, vector
95 /* 23 */ fid_front,
97 /* 24 */ fid_back,
99 /* 25 */ fid_pop_back,
100
101 // list, deque
104
105 // list
106 /* 28 */ fid_splice,
107 /* 29 */ fid_remove,
109 /* 31 */ fid_unique,
110 /* 32 */ fid_merge,
111 /* 33 */ fid_sort,
112 /* 34 */ fid_reverse,
113
114 // vector, string, deque
115 /* 35 */ fid_op_index,
117 /* 36 */ fid_at,
119
120 // vector, string
121 /* 37 */ fid_capacity,
122 /* 38 */ fid_reserve,
123
124 // vector<bool>
125 /* 39 */ fid_flip,
126
127 /* -- */ fid_bits = 6,
128 /* -- */ fid_mask = 63
129 };
130
131 // identifies the type of a function argument, including
132 // the implicit this
133 enum ArgId {
134 // 4 bits, 16 types max
135 /* 0 */ arg_void, // void
136 /* 1 */ arg_size, // size_type
137 /* 2 */ arg_val, // value_type
138 /* 3 */ arg_ref, // reference
139 /* 4 */ arg_cref, // const_reference
140 /* 5 */ arg_iter, // iterator
141 /* 6 */ arg_citer, // const_iterator
142 /* 7 */ arg_range, // Iterator, Iterator
143 /* 8 */ arg_cont, // container& (or this for member functions)
144 /* 9 */ arg_ccont, // const container& (or const this for members)
145 /* 10 */ arg_alloc, // const allocator&
146 /* 11 */ arg_pred, // Predicate
147 /* 12 */ arg_bpred, // BinaryPredicate
148 /* 13 */ arg_comp, // Compare
149 /* -- */ arg_bits = 4,
150 /* -- */ arg_mask = 15
151 };
152
153 enum {
154 // bit designating a member function
155 bit_member = 1 << (fid_bits + 6 * arg_bits)
156 };
157
158 static ArgId arg_type (_RWSTD_SIZE_T id, int argno) {
159 return ArgId (((id >> fid_bits) >> argno * arg_bits) & arg_mask);
160 }
161};
162
163
166{
171 _RWSTD_SIZE_T which_;
172};
173
174
175// describes a single test case for any overload of any container
176// function (the same test case can be used to exercise more
177// than one overload of the same function)
179{
180 int line; // test case line number
181
182 int off; // offset (position argument)
183 int size; // size (count argument)
184
185 int off2; // offset 2 (position argument)
186 int size2; // size 2 (count argument)
187
188 int val; // value (single character to append)
189
190 const char* str; // controlled sequence
191 _RWSTD_SIZE_T str_len; // length of sequence
192
193 const char* arg; // sequence to insert
194 _RWSTD_SIZE_T arg_len; // length of sequence
195
196 const char* res; // resulting sequence
197 _RWSTD_SIZE_T nres; // length of sequence or expected result value
198
199 int bthrow; // exception expected
200};
201
202
203// describes a set of test cases for a single overload of a function
205{
206 // container function overload to exercise
207 _RWSTD_SIZE_T which;
208
209 // test cases to exercise overload with
211
212 // number of test cases
213 _RWSTD_SIZE_T case_count;
214};
215
216
218
219_TEST_EXPORT int
220rw_run_cont_test (int, char**, const char*, const char*,
222 const ContainerTest*, _RWSTD_SIZE_T);
223
224typedef void VoidFunc ();
225
226_TEST_EXPORT int
227rw_run_cont_test (int, char**, const char*, const char*,
229 const ContainerTest*, _RWSTD_SIZE_T);
230
231
233template <class T>
235{
236private:
237
238 // not defined, not copyable, not assignable
240 void operator= (const ContainerTestCaseData&);
241
242 // for convenience
243 typedef _RWSTD_SIZE_T SizeType;
244
245public:
246
247 SizeType strlen_; // the length of the expanded string
248 SizeType arglen_; // the length of the expanded argument
249 SizeType reslen_; // the length of the expanded result
250
251 // the offset and extent (the number of elements) of
252 // the first range into the container object being modified
253 SizeType off1_;
254 SizeType ext1_;
255
256 // the offset and extent (the number of elements) of
257 // the argument of the function call
258 SizeType off2_;
259 SizeType ext2_;
260
261 const T* str_; // pointer to the expanded string
262 const T* arg_; // pointer to the expanded argument
263 const T* res_; // pointer to the expanded result
264
267
268 // converts the narrow (and possibly) condensed strings to fully
269 // expanded wide character arrays that can be used to construct
270 // container objects
272 const ContainerTestCase&);
273
275};
276
277
278template <class T>
281 const ContainerTestCase &tcase)
282 : func_ (func), tcase_ (tcase)
283{
284 char buf [256];
285
286 strlen_ = sizeof (buf);
287 char* str = rw_expand (buf, tcase.str, tcase.str_len, &strlen_);
288 str_ = T::from_char (str, strlen_);
289 if (str != buf)
290 delete[] str;
291
292 arglen_ = sizeof (buf);
293 str = rw_expand (buf, tcase.arg, tcase.arg_len, &arglen_);
294 arg_ = T::from_char (str, arglen_);
295 if (str != buf)
296 delete[] str;
297
298 reslen_ = sizeof (buf);
299 str = rw_expand (buf, tcase.res, tcase.nres, &reslen_);
300 res_ = T::from_char (str, reslen_);
301 if (str != buf)
302 delete[] str;
303
304 // compute the offset and extent of the container object
305 // representing the controlled sequence and the offset
306 // and extent of the argument of the function call
307 const SizeType argl = tcase_.arg ? arglen_ : strlen_;
308
309 off1_ = SizeType (tcase_.off) < strlen_ ?
310 SizeType (tcase_.off) : strlen_;
311
313 SizeType (tcase_.size) : strlen_ - off1_;
314
315 off2_ = SizeType (tcase_.off2) < argl ?
316 SizeType (tcase_.off2) : argl;
317
318 ext2_ = off2_ + tcase_.size2 < argl ?
319 SizeType (tcase_.size2) : argl - off2_;
320}
321
322
323template <class T>
326{
327 // clean up dynamically allocated memory
328
329 // cast away the constness of the pointers to work around
330 // an HP aCC 6.16 and prior bug described in STDCXX-802
331 delete[] _RWSTD_CONST_CAST (T*, str_);
332 delete[] _RWSTD_CONST_CAST (T*, arg_);
333 delete[] _RWSTD_CONST_CAST (T*, res_);
334}
335
336
338// base class-functor for the range template overloads testing
339template <class Cont>
341
342 typedef typename Cont::value_type ContVal;
343 typedef typename Cont::iterator ContIter;
344 typedef typename Cont::const_iterator ContConstIter;
345 typedef typename Cont::reverse_iterator ContRevIter;
346 typedef typename Cont::const_reverse_iterator ContConstRevIter;
347
349
350 virtual ~ContRangeBase () { /* silence warnings */ }
351
352 static ContIter
353 begin (Cont &cont, ContIter*) {
354 return cont.begin ();
355 }
356
357 static ContConstIter
358 begin (const Cont &cont, ContConstIter*) {
359 return cont.begin ();
360 }
361
362 static ContRevIter
363 begin (Cont &cont, ContRevIter*) {
364 return cont.rbegin ();
365 }
366
367 static ContConstRevIter
368 begin (const Cont &cont, ContConstRevIter*) {
369 return cont.rbegin ();
370 }
371
372 virtual Cont&
373 operator() (Cont &cont, const ContainerTestCaseData<ContVal>&) const {
374 RW_ASSERT (!"logic error: should be never called");
375 return cont;
376 }
377};
378
379
381# define CONTAINER_TEST_DISPATCH(Alloc, fname, func, tcase) \
382 if (ContainerIds::UserPOD == func.elem_id_) \
383 fname (UserPOD (), (Alloc<UserPOD>*)0, func, tcase); \
384 else \
385 fname (UserClass (), (Alloc<UserClass>*)0, func, tcase)
386
387
388#define DEFINE_CONTAINER_TEST_DISPATCH(fname) \
389 static void \
390 fname (const ContainerFunc &func, \
391 const ContainerTestCase &tcase) { \
392 if (ContainerIds::DefaultAlloc == func.alloc_id_) { \
393 CONTAINER_TEST_DISPATCH (std::allocator, fname, func, tcase); \
394 } \
395 else if (ContainerIds::UserAlloc == func.alloc_id_) { \
396 CONTAINER_TEST_DISPATCH (UserAlloc, fname, func, tcase); \
397 } \
398 else \
399 RW_ASSERT (!"logic error: bad allocator"); \
400 } typedef void rw_unused_typedef
401
402
403#define CONTAINER_TFUNC(T, Allocator) \
404 void (*)(T*, Allocator<T>*, \
405 const ContainerTestCaseData<T>&)
406
407#define CONTAINER_TFUNC_ADDR(fname, T, Allocator) \
408 (VoidFunc*)(CONTAINER_TFUNC (T, Allocator)) \
409 &fname<T, Allocator<T> >
410
411#define DEFINE_CONTAINER_TEST_FUNCTIONS(fname) \
412 static VoidFunc* const fname ## _func_array [] = { \
413 CONTAINER_TFUNC_ADDR (fname, UserPOD, std::allocator), \
414 CONTAINER_TFUNC_ADDR (fname, UserPOD, UserAlloc), \
415 \
416 CONTAINER_TFUNC_ADDR (fname, UserClass, std::allocator), \
417 CONTAINER_TFUNC_ADDR (fname, UserClass, UserAlloc) \
418 }
419
420#endif // RW_23_CONTAINERS_H_INCLUDED
#define T
Definition 17.names.cpp:163
#define buf
Definition 17.names.cpp:452
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
const ContainerFunc & func_
const ContainerTestCase & tcase_
const char * str
Definition exec.cpp:170
_TEST_EXPORT char * rw_expand(char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX, _RWSTD_SIZE_T *=0)
_TEST_EXPORT int rw_run_cont_test(int, char **, const char *, const char *, ContainerIds::ContainerId, ContainerTestFunc *, const ContainerTest *, _RWSTD_SIZE_T)
void VoidFunc()
void ContainerTestFunc(const ContainerFunc &, const ContainerTestCase &)
#define _TEST_EXPORT
Definition rw_testdefs.h:55
#define RW_ASSERT(expr)
Cont::const_reverse_iterator ContConstRevIter
Cont::const_iterator ContConstIter
Cont::reverse_iterator ContRevIter
static ContRevIter begin(Cont &cont, ContRevIter *)
static ContConstRevIter begin(const Cont &cont, ContConstRevIter *)
static ContIter begin(Cont &cont, ContIter *)
virtual Cont & operator()(Cont &cont, const ContainerTestCaseData< ContVal > &) const
static ContConstIter begin(const Cont &cont, ContConstIter *)
Cont::value_type ContVal
Cont::iterator ContIter
virtual ~ContRangeBase()
ContainerIds::ElemId elem_id_
_RWSTD_SIZE_T which_
ContainerIds::ContainerId cont_id_
ContainerIds::IteratorId iter_id_
ContainerIds::AllocId alloc_id_
static ArgId arg_type(_RWSTD_SIZE_T id, int argno)
_RWSTD_SIZE_T str_len
_RWSTD_SIZE_T arg_len
_RWSTD_SIZE_T nres
_RWSTD_SIZE_T case_count
const ContainerTestCase * cases
_RWSTD_SIZE_T which