Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.for.each.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for for_each
30#include <cstddef> // for ptrdiff_t
31
32#include <rw_alg_test.h>
33#include <rw_value.h> // for UserClass
34#include <rw_driver.h> // for rw_test(), ...
35
36
39{
40 static std::size_t funcalls_;
41 static int sum_;
43
44 FunctionBase (bool is_const)
45 : is_const_ (is_const) {
46 funcalls_ = 0;
47 sum_ = 0;
48 }
49
50private:
51 void operator= (FunctionBase&); // not assignable
52};
53
54std::size_t FunctionBase::funcalls_;
56
57
59{
60 // dummy arguments provided to prevent the class
61 // from being default constructible
63
64 void operator() (UserClass val) /* not const */ {
65 ++funcalls_;
66 sum_ += val.data_.val_;
67 }
68
69 static const char* name () { return "ConstFunction"; }
70};
71
72
74{
75 // dummy arguments provided to prevent the class
76 // from being default constructible
78
79 void operator() (UserClass &val) /* not const */ {
80 ++funcalls_;
81 val.data_.val_ = -val.data_.val_;
82 }
83
84 static const char* name () { return "MutableFunction"; }
85};
86
87
88// exercises std::for_each()
89template <class InputIterator, class T, class Function>
90void test_for_each (std::size_t N, InputIterator dummy, T*, Function*)
91{
92 static const char* const itname = type_name (dummy, (T*)0);
93 static const char* const fnname = Function::name ();
94
95 rw_info (0, 0, 0, "std::for_each (%s, %1$s, %s)", itname, fnname);
96
97 // generate sequential values for each default constructed UserClass
99
100 UserClass *buf = new UserClass [N];
101
102 const int first_val = buf [0].data_.val_;
103
104 for (std::size_t i = 0; i != N; ++i) {
105
106 UserClass* const buf_end = buf + i;
107
108 const InputIterator first (buf, buf, buf_end);
109 const InputIterator last (buf_end, buf_end, buf_end);
110
111 // create a const function object and zero out all its counters
112 const Function fun (0, 0);
113
114 std::for_each (first, last, fun);
115
116 // compute the sum of elements in the sequence and check each
117 // element's value against the expected one
118 int sum = 0;
119
120 for (std::size_t j = 0; j != i; ++j) {
121
122 int expect;
123
124 if (fun.is_const_) {
125 // const function object doesn't modify the subject
126 // sequence; the expected value of the element is
127 // the same as the original value
128 expect = first_val + int (j);
129 }
130 else {
131 // non-const function object negates each argument
132 expect = -(first_val + int (j));
133 }
134
135 // compute the sum (computed by the const function object)
136 sum += buf [j].data_.val_;
137
138 // assert the element value as the same as the expected value
139 rw_assert (expect == buf [j].data_.val_, 0, __LINE__,
140 "for_each (%s, %1$s, %s); element [%zu] == %d, got %d",
141 itname, fnname, j, expect, buf [j].data_.val_);
142
143 if (expect != buf [j].data_.val_) {
144 // break out of both loops on failure
145 i = N;
146 break;
147 }
148
149 // restore the original value of the element
150 buf [j].data_.val_ = first_val + int (j);
151 }
152
153 // assert that for_each invoked the function object's operator()
154 // exactly as many times as necessary and required
155 rw_assert (i == fun.funcalls_, 0, __LINE__,
156 "for_each (%s, %1$s, %s); expected %zu invocations of "
157 "Function::operator(), got %zu", itname, fnname,
158 i, fun.funcalls_);
159
160 if (fun.is_const_) {
161 rw_assert (sum == fun.sum_, 0, __LINE__,
162 "for_each (%s, %1$s, %s); sum of %zu elements == %d, "
163 "got %d", itname, fnname, sum, fun.sum_);
164 }
165 }
166
167 delete[] (buf);
168}
169
170
172static int rw_opt_nloops = 32; // --nloops=#
173static int rw_opt_no_input_iter; // --no-InputIterator
174static int rw_opt_no_fwd_iter; // --no-ForwardIterator
175static int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
176static int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
177
178
179static int
180run_test (int, char*[])
181{
182 const std::size_t N = std::size_t (rw_opt_nloops);
183
184 rw_info (0, 0, 0,
185 "template <class %s, class %s> "
186 "%2$s std::for_each (%1$s, %1$s, %2$s)",
187 "InputIterator", "Function");
188
189 if (rw_opt_no_input_iter) {
190 rw_note (0, __FILE__, __LINE__, "InputIterator test disabled");
191 }
192 else {
194 (ConstFunction*)0);
195 }
196
197 if (rw_opt_no_fwd_iter) {
198 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
199 }
200 else {
202 (ConstFunction*)0);
204 (ConstFunction*)0);
206 (MutableFunction*)0);
207 }
208
209 if (rw_opt_no_bidir_iter) {
210 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
211 }
212 else {
214 (ConstFunction*)0);
216 (ConstFunction*)0);
218 (MutableFunction*)0);
219 }
220
221 if (rw_opt_no_rnd_iter) {
222 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
223 }
224 else {
226 (ConstFunction*)0);
228 (ConstFunction*)0);
230 (MutableFunction*)0);
231 }
232
233 return 0;
234}
235
236
238int main (int argc, char *argv[])
239{
240 return rw_test (argc, argv, __FILE__,
241 "lib.alg.foreach",
242 0 /* no comment */, run_test,
243 "|-nloops#0 " // must be non-negative
244 "|-no-InputIterator# "
245 "|-no-ForwardIterator# "
246 "|-no-BidirectionalIterator# "
247 "|-no-RandomAccessIterator#",
253}
#define N
Definition 17.names.cpp:157
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define fun
Definition 17.names.cpp:471
#define last
Definition 17.names.cpp:487
#define buf
Definition 17.names.cpp:452
#define j
Definition 17.names.cpp:127
#define Function
Definition 17.names.cpp:472
#define val
Definition 17.names.cpp:570
int rw_opt_no_fwd_iter
int rw_opt_no_rnd_iter
int rw_opt_no_bidir_iter
int rw_opt_no_input_iter
Definition 25.copy.cpp:236
int rw_opt_nloops
Definition 25.copy.cpp:235
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
void test_for_each(std::size_t N, InputIterator dummy, T *, Function *)
const char * type_name()
#define main
_TEST_EXPORT int gen_seq()
Definition alg_test.cpp:38
_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
#define true
Definition stdbool.h:25
#define false
Definition stdbool.h:26
static const char * name()
ConstFunction(int, int)
void operator()(UserClass val)
FunctionBase(bool is_const)
static int sum_
static std::size_t funcalls_
void operator()(UserClass &val)
static const char * name()
MutableFunction(int, int)
UserData data_
Definition rw_value.h:79
static int(* gen_)()
Definition rw_value.h:122
int val_
Definition rw_value.h:39