Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
26.valarray.cons.cpp
Go to the documentation of this file.
1
27#include <cstdlib> // for free(), strtol(), size_t
28#include <valarray> // for indirect_array, valarray
29
30#include <rw_value.h> // for UserClass
31#include <rw_driver.h> // for rw_test()
32#include <rw_printf.h> // for rw_asnprintf()
33
34
36// returns an array of size elements of type T constructed from a string
37// of comma-separated values
38template <class T>
39T*
40make_array (const T*, const char *s, std::size_t *psize)
41{
42 std::size_t nelems = psize ? *psize : 0;
43
44 T* const buf = new T [nelems ? nelems : 4096];
45
46 if (0 == nelems && (0 == s || '\0' == *s))
47 return buf;
48
49 std::size_t i;
50
51 for (i = 0; ; ++i) {
52
53 char *end = 0;
54 long val = s ? std::strtol (s, &end, 0) : 0L;
55
56 RW_ASSERT (0 == end || '\0' == *end || ',' == *end);
57
58 buf [i] = T (val);
59
60 if (0 == end || '\0' == *end) {
61 while (++i < nelems)
62 buf [i] = buf [i - 1];
63
64 break;
65 }
66
67 s = end + 1;
68 }
69
70 if (psize)
71 *psize = i;
72
73 return buf;
74}
75
76
77// deletes an array of elements of type T returned from make_array
78template <class T>
79void
80delete_array (const T *array, std::size_t)
81{
82 T* const a = _RWSTD_CONST_CAST (T*, array);
83 delete[] a;
84}
85
86
87template <class T>
88const std::size_t* count (const T*) { return 0; }
89
90
91template <class T>
92T value (const T &val) { return val; }
93
94
96// returns an array of size elements of type UserClass
97// constructed from a string of comma-separated values
99make_array (const UserClass*, const char *s, std::size_t *psize)
100{
101 std::size_t nelems = psize ? *psize : 0;
102
103 const std::size_t size = sizeof (UserClass);
104 void* const raw = operator new ((nelems ? nelems : 1024) * size);
105 UserClass* const buf = _RWSTD_STATIC_CAST (UserClass*, raw);
106
107 if (0 == nelems && (0 == s || '\0' == *s))
108 return buf;
109
110 std::size_t i;
111
112 for (i = 0; ; ++i) {
113
114 char *end = 0;
115 long val = s ? std::strtol (s, &end, 0) : 0L;
116
117 RW_ASSERT (0 == end || '\0' == *end || ',' == *end);
118
119 new (buf + i) UserClass ();
120 buf [i].data_.val_ = int (val);
121
122 if (0 == end || '\0' == *end) {
123 while (++i < nelems)
124 new (buf + i) UserClass (buf [i - 1]);
125
126 break;
127 }
128
129 s = end + 1;
130 }
131
132 if (psize)
133 *psize = i;
134
135 return buf;
136}
137
138
139// deletes an array of elements of type T returned from make_array
140void
141delete_array (const UserClass *array, std::size_t nelems)
142{
144
145 for (std::size_t i = 0; i != nelems; ++i)
146 (a + i)->~UserClass ();
147
148 operator delete (a);
149}
150
151
152const std::size_t* count (const UserClass*) { return &UserClass::count_; }
153
154int value (const UserClass &val) { return val.data_.val_; }
155
156
158enum CtorId {
159 DefaultCtor, // valarray<T>::valarray()
160 SizeCtor, // valarray<T>::valarra(size_t)
161 ValueCtor, // valarray<T>::valarray(const T&, size_t)
162 ArrayCtor // valarray<T>::valarray(const T*, size_t)
164
165
166template <class T>
167void
168test_ctor (const T*, const char *tname, CtorId which, bool copy,
169 int line, const char *str, std::size_t nelems)
170{
171 std::valarray<T> *pva = 0;
172
173 T* const array = make_array ((const T*)0, str, &nelems);
174
175 char* fname = 0;
176 std::size_t size = 0;
177
178 // pointer to a counter keepint track of all objects of type T
179 // in existence (non-null only for T=UserClass)
180 const std::size_t* const pcounter = count ((const T*)0);
181
182 // get the number of objects of type T before invoking the ctor
183 std::size_t nobjects = pcounter ? *pcounter : 0;
184
185 switch (which) {
186
187 case DefaultCtor:
188 rw_asnprintf (&fname, &size, "valarray<%s>::valarray()", tname);
189 pva = new std::valarray<T>;
190 break;
191
192 case SizeCtor:
193 rw_asnprintf (&fname, &size,
194 "valarray<%s>::valarray(size_t = %zu)",
195 tname, nelems);
196 pva = new std::valarray<T>(nelems);
197 break;
198
199 case ValueCtor: {
200 rw_asnprintf (&fname, &size,
201 "valarray<%s>::valarray(const %1$s& = %1$s(%d), "
202 "size_t = %zu)",
203 tname, value (array [0]), nelems);
204 pva = new std::valarray<T>(array [0], nelems);
205 break;
206 }
207
208 case ArrayCtor: {
209 rw_asnprintf (&fname, &size,
210 "valarray<%s>::valarray(const %1$s* = {%s}, "
211 "size_t = %zu)",
212 tname, str, nelems);
213 pva = new std::valarray<T>(array, nelems);
214 break;
215 }
216
217 }
218
219 std::valarray<T> *psave = 0;
220
221 if (copy) {
222 char *tmpbuf = 0;
223 std::size_t tmpsize = 0;
224
225 rw_asnprintf (&tmpbuf, &tmpsize, "valarray<%s>::valarray(%s)",
226 tname, fname);
227
228 std::free (fname);
229 fname = tmpbuf;
230 size = tmpsize;
231
232 // replace the stored object counter value
233 nobjects = pcounter ? *pcounter : 0;
234
235 // save the original and replace it with the new array
236 psave = pva;
237
238 // invoke the copy ctor
239 pva = new std::valarray<T>(*pva);
240 }
241
242 // verify the size of the array
243 rw_assert (pva->size () == nelems, 0, line,
244 "line %d. %s.size() == %zu, got %zu",
245 __LINE__, fname, nelems, pva->size ());
246
247 if (pcounter) {
248 // compute the number of objects of type T constructed
249 // by the ctor (valid only for T=UserClass)
250 nobjects = *pcounter - nobjects;
251
252 rw_assert (nobjects == nelems, 0, line,
253 "line %d. %s constucted %zu objects, expected %zu",
254 __LINE__, fname, nobjects, nelems);
255 }
256
257 // verify the element values
258 for (std::size_t i = 0; i != nelems; ++i) {
259 if (!((*pva)[i] == array [i])) {
260 rw_assert (i == nelems, 0, line,
261 "line %d. %s[%zu] == %s(%d), got %4$s(%d)",
262 __LINE__, fname, i, tname,
263 value (array [i]), value ((*pva)[i]));
264
265 break;
266 }
267 }
268
269 delete_array (array, nelems);
270
271 // get the number of objects of type T before invoking the dtor
272 nobjects = pcounter ? *pcounter : 0;
273
274 delete pva;
275
276 if (pcounter) {
277 // compute the number of objects of type T destroyed by the dtor
278 nobjects = nobjects - *pcounter;
279
280 // verify that all objects constructed by the ctor have been
281 // destroyed (i.e., none leaked)
282 rw_assert (nobjects == nelems, 0, line,
283 "line %d. %s dtor destroyed %zu objects, expected %zu",
284 __LINE__, fname, nobjects, nelems);
285 }
286
287 delete psave;
288 std::free (fname);
289}
290
291
292
294template <class T>
295void
296test_default_ctor (const T*, const char *tname, bool copy)
297{
298 if (!copy)
299 rw_info (0, 0, __LINE__, "std::valarray<%s>::valarray()", tname);
300
301 test_ctor ((const T*)0, tname, DefaultCtor, copy, __LINE__, 0, 0);
302}
303
304
306template <class T>
307void
308test_size_ctor (const T*, const char *tname, bool copy)
309{
310 if (!copy)
311 rw_info (0, 0, __LINE__, "std::valarray<%s>::valarray(size_t)",
312 tname);
313
314#undef TEST
315#define TEST(n) \
316 test_ctor ((const T*)0, tname, SizeCtor, copy, __LINE__, "0", n)
317
318 TEST (0);
319 TEST (1);
320 TEST (2);
321 TEST (3);
322 TEST (4);
323 TEST (5);
324 TEST (6);
325 TEST (7);
326 TEST (8);
327 TEST (9);
328 TEST (10);
329 TEST (123);
330 TEST (1023);
331}
332
333
335template <class T>
336void
337test_value_ctor (const T*, const char *tname, bool copy)
338{
339 if (!copy)
340 rw_info (0, 0, __LINE__,
341 "std::valarray<%s>::valarray(const %1$s&, size_t)",
342 tname);
343#undef TEST
344#define TEST(str, n) \
345 test_ctor ((const T*)0, tname, ValueCtor, copy, __LINE__, str, n)
346
347 TEST ("0", 0);
348 TEST ("0", 1);
349 TEST ("1", 1);
350 TEST ("2", 2);
351 TEST ("3", 3);
352 TEST ("4", 4);
353 TEST ("5", 5);
354 TEST ("6", 12345);
355}
356
357
359template <class T>
360void
361test_array_ctor (const T*, const char *tname, bool copy)
362{
363 if (!copy)
364 rw_info (0, 0, __LINE__,
365 "std::valarray<%s>::valarray(const %1$s*, size_t)",
366 tname);
367
368#undef TEST
369#define TEST(str) \
370 test_ctor ((const T*)0, tname, ArrayCtor, copy, __LINE__, str, 0)
371
372 TEST (""); // empty array
373 TEST ("0");
374 TEST ("0,1");
375 TEST ("0,1,2");
376 TEST ("0,1,2,3");
377 TEST ("0,1,2,3,4");
378 TEST ("0,1,2,3,4,5");
379 TEST ("0,1,2,3,4,5,6");
380 TEST ("0,1,2,3,4,5,6,7");
381 TEST ("0,1,2,3,4,5,6,7,8");
382 TEST ("0,1,2,3,4,5,6,7,8,9");
383}
384
385
387template <class T>
388void
389test_copy_ctor (const T*, const char *tname)
390{
391 rw_info (0, 0, __LINE__,
392 "std::valarray<%s>::valarray(const valarray<%1$s>&)", tname);
393}
394
395
397template <class T>
398void
399test_ctors (const T*, const char *tname)
400{
401 for (int i = 0; i != 2; ++i) {
402
403 // exercise the respective ctor in the first iteration
404 // and the copy ctor invoked an object constructed with
405 // the same respective ctor as in the first iteration
406 // then
407
408 const bool test_copy_ctor = 0 < i;
409
410 test_default_ctor ((T*)0, tname, test_copy_ctor);
411 test_size_ctor ((T*)0, tname, test_copy_ctor);
412 test_value_ctor ((T*)0, tname, test_copy_ctor);
413 test_array_ctor ((T*)0, tname, test_copy_ctor);
414 }
415}
416
417
419static int
420run_test (int, char**)
421{
422#undef TEST
423#define TEST(T) test_ctors ((const T*)0, #T)
424 TEST (char);
425 TEST (int);
426 TEST (double);
427
428 TEST (UserClass);
429
430 return 0;
431}
432
433
435int main (int argc, char *argv[])
436{
437 // FIXME: add command line options to enable/disable each operator
438 return rw_test (argc, argv, __FILE__,
439 "valarray.cons",
440 0 /* no comment */,
441 run_test,
442 "",
443 (void*)0 /* sentinel */);
444}
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define line
Definition 17.names.cpp:490
#define which
Definition 17.names.cpp:575
#define a
Definition 17.names.cpp:109
#define buf
Definition 17.names.cpp:452
#define L
Definition 17.names.cpp:155
#define s
#define val
Definition 17.names.cpp:570
void test_default_ctor(std::bitset< N > *)
void test_ctors()
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
T value(const T &val)
void test_size_ctor(const T *, const char *tname, bool copy)
void test_array_ctor(const T *, const char *tname, bool copy)
const std::size_t * count(const T *)
@ ValueCtor
@ ArrayCtor
@ DefaultCtor
T * make_array(const T *, const char *s, std::size_t *psize)
void test_copy_ctor(const T *, const char *tname)
void delete_array(const T *array, std::size_t)
void test_value_ctor(const T *, const char *tname, bool copy)
#define TEST(n)
void test_ctor(const charT *, const Traits *, const char *cname, const char *tname)
const int end
#define main
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
A TOML array.
Definition array.hpp:258
const char * str
Definition exec.cpp:170
_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_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
_TEST_EXPORT int rw_asnprintf(char **pbuf, _RWSTD_SIZE_T *pbufsize, const char *fmt,...)
#define RW_ASSERT(expr)
UserData data_
Definition rw_value.h:79
static _RWSTD_SIZE_T count_
Definition rw_value.h:120
int val_
Definition rw_value.h:39