Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
26.gslice.array.cassign.cpp
Go to the documentation of this file.
1
29#include <cstdlib> // for free(), strtod(), size_t
30#include <valarray> // for indirect_array, valarray
31
32//#include <rw_value.h> // for UserClass
33#include <rw_driver.h> // for rw_test()
34#include <rw_printf.h> // for rw_asnprintf()
35
36
38// returns an array of size elements of type T constructed from a string
39// of comma-separated values
40static std::valarray<std::size_t>
41make_array (const char *s)
42{
43 std::size_t buf [256];
44 bool repeat = false;
45
46 std::size_t i = 0;
47 while (s && *s) {
48
49 char *end;
50 unsigned long val = std::strtoul (s, &end, 10);
51
52 RW_ASSERT ('\0' == *end || ',' == *end || '@' == *end);
53
54 if (!repeat)
55 {
56 buf [i++] = std::size_t (val);
57 }
58 else
59 {
60 const std::size_t n = buf [i-1];
61
62 for (std::size_t j = 0; j < (val - 1); ++j)
63 buf [i+j] = n;
64 i += (val - 1);
65 }
66
67 if ('\0' == *end)
68 break;
69
70 s = end + 1;
71 repeat = '@' == *end;
72 }
73
74 return std::valarray<std::size_t>(buf, i);
75}
76
77
79void
81 void (std::gslice_array<std::size_t>::*op_assign)(const std::valarray<std::size_t>&) const,
82 const char *tname, // T's type name
83 const char *opname, // which assignment operator
84 int line, // test case line number
85 std::size_t start, // start index of slice
86 const char *length_str,// number of strides
87 const char *stride_str,// length of stride
88 const char *lhs_str, // original array
89 const char *rhs_str, // right hand side of assignment
90 const char *res_str) // result of assignment
91{
92 // create an array of values from the string length_str
93 // representing the length array of the slice
94 const std::valarray<std::size_t> lengths (make_array (length_str));
95
96 // create an array of values from the string stride_str
97 // representing the stride array of the slice
98 const std::valarray<std::size_t> strides (make_array (stride_str));
99
100 // valarray(s)[gslice(start, length, stride)] op= rhs
101
102 const std::gslice gsl (start, lengths, strides);
103
104 // create an array of values from the string lhs_str
105 // representing the left-hand side array before slicing
106 /* const */ std::valarray<std::size_t> lhs_va (make_array (lhs_str));
107
108 // create an array of values from the string rhs_str
109 // representing the right-hand side argument of the assignment
110 const std::valarray<std::size_t> rhs_va (make_array (rhs_str));
111
112 // create an array of values from the string res_str
113 // representing the result of the assignment
114 const std::valarray<std::size_t> res_va (make_array (res_str));
115
116 // verify sizes match
117 RW_ASSERT (lhs_va.size () == res_va.size ());
118
119 // take a gslice of lhs_va, this is the lhs of the assignment
120 std::gslice_array<std::size_t> lhs_ga = lhs_va [gsl];
121
122 char* fname = 0;
123 std::size_t size = 0;
124
125 // format the name of the function call to be used in diagnostic
126 // messages below
127 rw_asnprintf (&fname, &size,
128 "gslice_array<%s>(%s) %s std::valarray<%1$s>(%s)",
129 tname, lhs_str, opname, rhs_str);
130
131 // invoke the assignment operator through the member pointer
132 (lhs_ga.*op_assign)(rhs_va);
133
134 // verify the element values
135 for (std::size_t i = 0; i != lhs_va.size (); ++i) {
136 if (!rw_assert (lhs_va [i] == res_va [i], 0, line,
137 "line %d. %s: element at index %zu == %zu, got %zu",
138 __LINE__, fname, i, res_va [i], lhs_va [i]))
139 break;
140
141 }
142
143 std::free (fname);
144}
145
146
147
149#define OP(start, lengths, strides, lhs, rhs, res) \
150 test_op_assign ((T*)0, op, tname, opname, __LINE__, start, lengths, strides, lhs, rhs, res)
151
152
153template <class T>
154void test_mul_assign (const T*, const char *tname, const char *opname)
155{
156 rw_info (0, 0, __LINE__,
157 "std::gslice_array<%s>::operator%s (const std::valarray<%1$s>&)",
158 tname, opname);
159
160 void (std::gslice_array<T>::*op)(const std::valarray<T>&) const =
161 &std::gslice_array<T>::operator*=;
162
163 // +- start
164 // | +- lengths
165 // | | +- strides +- rhs
166 // | | | +- lhs | +- expect
167 // v v v v v v
168 OP (0, "", "", "1@4", "2", "1@4");
169 OP (0, "0", "1", "1@4", "2", "1@4");
170 OP (2, "0", "9", "1@4", "2", "1@4");
171 OP (3, "0", "2", "1@4", "7", "1@4");
172
173 OP (0, "1", "1", "1@4", "5", "5,1@3");
174 OP (2, "1", "1", "1@4", "5", "1,1,5,1");
175
176 OP (1, "2", "1", "1@4", "3,4", "1,3,4,1");
177 OP (1, "1", "2", "2@4", "2", "2,4,2,2");
178
179 OP (0, "2,1", "2,3", "2@4", "3,7", "6,2,14,2");
180 OP (1, "1,0", "2,3", "3@4", "3", "3,9,3,3");
181}
182
183
185template <class T>
186void test_div_assign (const T*, const char *tname, const char *opname)
187{
188 rw_info (0, 0, __LINE__,
189 "std::gslice_array<%s>::operator%s (const std::valarray<%1$s>&)",
190 tname, opname);
191
192 void (std::gslice_array<T>::*op)(const std::valarray<T>&) const =
193 &std::gslice_array<T>::operator/=;
194
195 OP (0, "", "", "1@4", "2", "1@4");
196 OP (0, "0", "1", "1@4", "2", "1@4");
197 OP (2, "0", "9", "1@4", "2", "1@4");
198 OP (3, "0", "2", "1@4", "7", "1@4");
199
200 OP (0, "1", "1", "10@4", "5", "2,10@3");
201 OP (2, "1", "1", "12@4", "5", "12,12,2,12");
202
203 OP (1, "2", "1", "12@4", "3,4", "12,4,3,12");
204 OP (1, "1", "2", "6@4", "2", "6,3,6,6");
205
206 OP (0, "2,1", "2,3", "42@4", "3,7", "14,42,6,42");
207 OP (1, "1,0", "2,3", "3@4", "3", "3,1,3,3");
208}
209
210
212template <class T>
213void test_mod_assign (const T*, const char *tname, const char *opname)
214{
215 rw_info (0, 0, __LINE__,
216 "std::gslice_array<%s>::operator%s (const std::valarray<%1$s>&)",
217 tname, opname);
218
219 void (std::gslice_array<T>::*op)(const std::valarray<T>&) const =
220 &std::gslice_array<T>::operator%=;
221
222 OP (0, "", "", "1@4", "2", "1@4");
223 OP (0, "0", "1", "1@4", "2", "1@4");
224 OP (2, "0", "9", "1@4", "2", "1@4");
225 OP (3, "0", "2", "1@4", "7", "1@4");
226
227 OP (0, "1", "1", "10@4", "5", "0,10@3");
228 OP (2, "1", "1", "12@4", "5", "12,12,2,12");
229
230 OP (1, "2", "1", "12@4", "3,4", "12,0,0,12");
231 OP (1, "1", "2", "7@4", "2", "7,1,7,7");
232
233 OP (0, "2,1", "2,3", "14@4", "3,7", "2,14,0,14");
234 OP (1, "1,0", "2,3", "3@4", "3", "3,0,3,3");
235}
236
237
239template <class T>
240void test_add_assign (const T*, const char *tname, const char *opname)
241{
242 rw_info (0, 0, __LINE__,
243 "std::valarray<%s>::operator%s (const std::valarray<%1$s>&)",
244 tname, opname);
245
246 void (std::gslice_array<T>::*op)(const std::valarray<T>&) const =
247 &std::gslice_array<T>::operator+=;
248
249 OP (0, "", "", "1@4", "2", "1@4");
250 OP (0, "0", "1", "1@4", "2", "1@4");
251 OP (2, "0", "9", "1@4", "2", "1@4");
252 OP (3, "0", "2", "1@4", "7", "1@4");
253
254 OP (0, "1", "1", "1@4", "5", "6,1@3");
255 OP (2, "1", "1", "2@4", "5", "2,2,7,2");
256
257 OP (1, "2", "1", "3@4", "3,4", "3,6,7,3");
258 OP (1, "1", "2", "7@4", "2", "7,9,7,7");
259
260 OP (0, "2,1", "2,3", "1@4", "3,7", "4,1,8,1");
261 OP (1, "1,0", "2,3", "3@4", "3", "3,6,3,3");
262}
263
264
266template <class T>
267void test_sub_assign (const T*, const char *tname, const char *opname)
268{
269 rw_info (0, 0, __LINE__,
270 "std::gslice_array<%s>::operator%s (const std::valarray<%1$s>&)",
271 tname, opname);
272
273 void (std::gslice_array<T>::*op)(const std::valarray<T>&) const =
274 &std::gslice_array<T>::operator-=;
275
276 OP (0, "", "", "1@4", "2", "1@4");
277 OP (0, "0", "1", "1@4", "2", "1@4");
278 OP (2, "0", "9", "1@4", "2", "1@4");
279 OP (3, "0", "2", "1@4", "7", "1@4");
280
281 OP (0, "1", "1", "9@4", "5", "4,9@3");
282 OP (2, "1", "1", "7@4", "5", "7,7,2,7");
283
284 OP (1, "2", "1", "3@4", "3,2", "3,0,1,3");
285 OP (1, "1", "2", "7@4", "2", "7,5,7,7");
286
287 OP (0, "2,1", "2,3", "7@4", "3,7", "4,7,0,7");
288 OP (1, "1,0", "2,3", "3@4", "3", "3,0,3,3");
289}
290
291
293template <class T>
294void test_xor_assign (const T*, const char *tname, const char *opname)
295{
296 rw_info (0, 0, __LINE__,
297 "std::gslice_array<%s>::operator%s (const std::valarray<%1$s>&)",
298 tname, opname);
299
300 void (std::gslice_array<T>::*op)(const std::valarray<T>&) const =
301 &std::gslice_array<T>::operator^=;
302
303 OP (0, "", "", "1@4", "2", "1@4");
304 OP (0, "0", "1", "1@4", "2", "1@4");
305 OP (2, "0", "9", "1@4", "2", "1@4");
306 OP (3, "0", "2", "1@4", "7", "1@4");
307
308 OP (0, "1", "1", "9@4", "5", "12,9@3");
309 OP (2, "1", "1", "7@4", "5", "7,7,2,7");
310
311 OP (1, "2", "1", "3@4", "3,4", "3,0,7,3");
312 OP (1, "1", "2", "7@4", "2", "7,5,7,7");
313
314 OP (0, "2,1", "2,3", "7@4", "3,7", "4,7,0,7");
315 OP (1, "1,0", "2,3", "3@4", "3", "3,0,3,3");
316}
317
318
320template <class T>
321void test_and_assign (const T*, const char *tname, const char *opname)
322{
323 rw_info (0, 0, __LINE__,
324 "std::valarray<%s>::operator%s (const std::valarray<%1$s>&)",
325 tname, opname);
326
327 void (std::gslice_array<T>::*op)(const std::valarray<T>&) const =
328 &std::gslice_array<T>::operator&=;
329
330 OP (0, "", "", "1@4", "2", "1@4");
331 OP (0, "0", "1", "1@4", "2", "1@4");
332 OP (2, "0", "9", "1@4", "2", "1@4");
333 OP (3, "0", "2", "1@4", "7", "1@4");
334
335 OP (0, "1", "1", "9@4", "5", "1,9@3");
336 OP (2, "1", "1", "7@4", "5", "7,7,5,7");
337
338 OP (1, "2", "1", "3@4", "3,4", "3,3,0,3");
339 OP (1, "1", "2", "7@4", "2", "7,2,7,7");
340
341 OP (0, "2,1", "2,3", "7@4", "3,2", "3,7,2,7");
342 OP (1, "1,0", "2,3", "3@4", "1", "3,1,3,3");
343}
344
345
347template <class T>
348void test_or_assign (const T*, const char *tname, const char *opname)
349{
350 rw_info (0, 0, __LINE__,
351 "std::gslice_array<%s>::operator%s (const std::valarray<%1$s>&)",
352 tname, opname);
353
354 void (std::gslice_array<T>::*op)(const std::valarray<T>&) const =
355 &std::gslice_array<T>::operator|=;
356
357 OP (0, "", "", "1@4", "2", "1@4");
358 OP (0, "0", "1", "1@4", "2", "1@4");
359 OP (2, "0", "9", "1@4", "2", "1@4");
360 OP (3, "0", "2", "1@4", "7", "1@4");
361
362 OP (0, "1", "1", "9@4", "5", "13,9@3");
363 OP (2, "1", "1", "7@4", "5", "7,7,7,7");
364
365 OP (1, "2", "1", "3@4", "3,4", "3,3,7,3");
366 OP (1, "1", "2", "7@4", "2", "7,7,7,7");
367
368 OP (0, "2,1", "2,3", "4@4", "3,7", "7,4,7,4");
369 OP (1, "1,0", "2,3", "3@4", "4", "3,7,3,3");
370}
371
372
374template <class T>
375void test_shl_assign (const T*, const char *tname, const char *opname)
376{
377 rw_info (0, 0, __LINE__,
378 "std::gslice_array<%s>::operator%s (const std::valarray<%1$s>&)",
379 tname, opname);
380
381 void (std::gslice_array<T>::*op)(const std::valarray<T>&) =
382 &std::gslice_array<T>::operator<<=;
383
384 OP (0, "", "", "1@4", "2", "1@4");
385 OP (0, "0", "1", "1@4", "2", "1@4");
386 OP (2, "0", "9", "1@4", "2", "1@4");
387 OP (3, "0", "2", "1@4", "7", "1@4");
388
389 OP (0, "1", "1", "1@4", "1", "2,1@3");
390 OP (2, "1", "1", "2@4", "1", "2,2,4,2");
391
392 OP (1, "2", "1", "1@4", "3,4", "1,4,8,1");
393 OP (1, "1", "2", "3@4", "2", "3,12,3,3");
394
395 OP (0, "2,1", "2,3", "1@4", "3,2", "8,1,4,1");
396 OP (1, "1,0", "2,3", "5@4", "3", "5,20,5,5");
397}
398
399
401template <class T>
402void test_shr_assign (const T*, const char *tname, const char *opname)
403{
404 rw_info (0, 0, __LINE__,
405 "std::gslice_array<%s>::operator%s (const std::valarray<%1$s>&)",
406 tname, opname);
407
408 void (std::gslice_array<T>::*op)(const std::valarray<T>&) const =
409 &std::gslice_array<T>::operator>>=;
410
411 OP (0, "", "", "1@4", "2", "1@4");
412 OP (0, "0", "1", "1@4", "2", "1@4");
413 OP (2, "0", "9", "1@4", "2", "1@4");
414 OP (3, "0", "2", "1@4", "7", "1@4");
415
416 OP (0, "1", "1", "1@4", "1", "0,1@3");
417 OP (2, "1", "1", "2@4", "1", "2,2,1,2");
418
419 OP (1, "2", "1", "9@4", "3,4", "9,1,0,9");
420 OP (1, "1", "2", "9@4", "2", "9,2,9,9");
421
422 OP (0, "2,1", "2,3", "14@4", "3,2", "1,14,3,14");
423 OP (1, "1,0", "2,3", "5@4", "3", "5,0,5,5");
424}
425
426
428enum {
441
442static int opt_assign [n_assign_ops];
443
444
445template <class T>
446void test_op_assign (const T*, const char *tname)
447{
448 const std::size_t nassigns = sizeof opt_assign / sizeof *opt_assign;
449 for (std::size_t i = 0; i != nassigns; ++i) {
450 if (0 < opt_assign [i]) {
451 for (std::size_t j = 0; j != nassigns; ++j) {
452 if (0 == opt_assign [j])
453 opt_assign [j] = -1;
454 }
455 break;
456 }
457 }
458
459 if (rw_note (0 <= opt_assign [inx_mul_assign], 0, __LINE__,
460 "tests of operator*= disabled"))
461 test_mul_assign ((const T*)0, tname, "*=");
462
463 if (rw_note (0 <= opt_assign [inx_div_assign], 0, __LINE__,
464 "tests of operator/= disabled"))
465 test_div_assign ((const T*)0, tname, "/=");
466
467 if (rw_note (0 <= opt_assign [inx_mod_assign], 0, __LINE__,
468 "tests of operator%= disabled"))
469 test_mod_assign ((const T*)0, tname, "%=");
470
471 if (rw_note (0 <= opt_assign [inx_add_assign], 0, __LINE__,
472 "tests of operator+= disabled"))
473 test_add_assign ((const T*)0, tname, "+=");
474
475 if (rw_note (0 <= opt_assign [inx_sub_assign], 0, __LINE__,
476 "tests of operator-= disabled"))
477 test_sub_assign ((const T*)0, tname, "-=");
478
479 if (rw_note (0 <= opt_assign [inx_xor_assign], 0, __LINE__,
480 "tests of operator^= disabled"))
481 test_xor_assign ((const T*)0, tname, "^=");
482
483 if (rw_note (0 <= opt_assign [inx_and_assign], 0, __LINE__,
484 "tests of operator&= disabled"))
485 test_and_assign ((const T*)0, tname, "&=");
486
487 if (rw_note (0 <= opt_assign [inx_or_assign], 0, __LINE__,
488 "tests of operator|= disabled"))
489 test_or_assign ((const T*)0, tname, "|=");
490
491 if (rw_note (0 <= opt_assign [inx_shl_assign], 0, __LINE__,
492 "tests of operator<<= disabled"))
493 test_shr_assign ((const T*)0, tname, "<<=");
494
495 if (rw_note (0 <= opt_assign [inx_shr_assign], 0, __LINE__,
496 "tests of operator>>= disabled"))
497 test_shr_assign ((const T*)0, tname, ">>=");
498}
499
500
502static int
503run_test (int, char**)
504{
505#undef TEST
506#define TEST(T) test_op_assign ((const T*)0, #T)
507
508 TEST (std::size_t);
509// TEST (double);
510//
511//#if 0x04020100 >= _RWSTD_VER
512//
513// // test fails to compile with stdcxx 4.2.1 and prior due to
514// // STDCXX-512: http://issues.apache.org/jira/browse/STDCXX-512
515// rw_warn (0, 0, __LINE__,
516// "test of UserClass disabled in stdcxx 4.2.0 and prior "
517// "due to STDCXX-512");
518//
519//#else // stdcxx >= 4.2.1
520//
521// //TEST (UserClass);
522//
523//#endif // stdcxx version
524
525 return 0;
526}
527
528
530int main (int argc, char *argv[])
531{
532 // FIXME: add command line options to enable/disable each operator
533 return rw_test (argc, argv, __FILE__,
534 "gslice.array.comp.assign",
535 0 /* no comment */,
536 run_test,
537 "|-times~ "
538 "|-divide~ "
539 "|-modulo~ "
540 "|-plus~ "
541 "|-minus~ "
542 "|-xor~ "
543 "|-and~ "
544 "|-or~ "
545 "|-shift_left~ "
546 "|-shift_right~",
547 opt_assign + inx_mul_assign,
548 opt_assign + inx_div_assign,
549 opt_assign + inx_mod_assign,
550 opt_assign + inx_add_assign,
551 opt_assign + inx_sub_assign,
552 opt_assign + inx_xor_assign,
553 opt_assign + inx_and_assign,
554 opt_assign + inx_or_assign,
555 opt_assign + inx_shl_assign,
556 opt_assign + inx_shr_assign,
557 (void*)0 /* sentinel */);
558}
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define start
Definition 17.names.cpp:547
#define line
Definition 17.names.cpp:490
#define buf
Definition 17.names.cpp:452
#define j
Definition 17.names.cpp:127
#define s
#define n
Definition 17.names.cpp:130
#define val
Definition 17.names.cpp:570
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
void test_or_assign(const T *, const char *tname, const char *opname)
void test_op_assign(void *, void(std::gslice_array< std::size_t >::*op_assign)(const std::valarray< std::size_t > &) const, const char *tname, const char *opname, int line, std::size_t start, const char *length_str, const char *stride_str, const char *lhs_str, const char *rhs_str, const char *res_str)
void test_and_assign(const T *, const char *tname, const char *opname)
void test_xor_assign(const T *, const char *tname, const char *opname)
void test_mul_assign(const T *, const char *tname, const char *opname)
#define OP(start, lengths, strides, lhs, rhs, res)
void test_mod_assign(const T *, const char *tname, const char *opname)
#define TEST(T)
void test_shl_assign(const T *, const char *tname, const char *opname)
void test_div_assign(const T *, const char *tname, const char *opname)
void test_shr_assign(const T *, const char *tname, const char *opname)
void test_add_assign(const T *, const char *tname, const char *opname)
void test_sub_assign(const T *, const char *tname, const char *opname)
const int end
#define main
constexpr std::array< T, sizeof...(Args)> make_array(Args &&... args)
Definition json.h:3222
Definition json.h:5363
_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
_TEST_EXPORT int rw_asnprintf(char **pbuf, _RWSTD_SIZE_T *pbufsize, const char *fmt,...)
#define RW_ASSERT(expr)