Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.permutation.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for prev_permutation, next_permutation
30#include <cstring> // for strlen, size_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// disable explicit instantiation for compilers that can't handle it
41#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
42
43template
44bool
45prev_permutation (BidirIter<lt_comp<assign<base<cpy_ctor> > > >,
47
48template
49bool
50prev_permutation (BidirIter<lt_comp<assign<base<cpy_ctor> > > >,
53
54template
55bool
56next_permutation (BidirIter<lt_comp<assign<base<cpy_ctor> > > >,
58
59template
60bool
61next_permutation (BidirIter<lt_comp<assign<base<cpy_ctor> > > >,
64
65#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
66
67} // namespace std
68
69
71template <class T>
72struct Less
73{
74 static std::size_t funcalls_;
75
76 // dummy arguments provided to prevent the class from being
77 // default constructible and implicit conversion from int
78 Less (int /* dummy */, int /* dummy */) {
79 funcalls_ = 0;
80 }
81
82 // return a type other than bool but one that is implicitly
83 // convertible to bool to detect incorrect assumptions
84 conv_to_bool operator() (const T &x, const T &y) /* non-const */ {
85 ++funcalls_;
86 return conv_to_bool::make (x.data_.val_ < y.data_.val_);
87 }
88
89 static const char* name () { return "Less"; }
90
91private:
92 void operator= (Less&); // not assignable
93};
94
95template<class T> std::size_t Less<T>::funcalls_;
96
97
99// exercise prev_permutation and next_permutation 25.3.9
100template <class T, class BidirectIterator, class Predicate>
102 const char *src,
103 const char *dst,
104 bool res,
105 const BidirectIterator &it,
106 const T*,
107 const Predicate *ppred,
108 bool prev)
109{
110 const char* const itname = type_name (it, (T*)0);
111 const char* const algname = prev ? "prev_permutation" : "next_permutation";
112 const char* const predname = Predicate::name ();
113
114 const std::size_t nsrc = std::strlen (src);
115
116 T* const xsrc = T::from_char (src, nsrc);
117 T* const xsrc_end = xsrc + nsrc;
118
119 const BidirectIterator first = make_iter (xsrc, xsrc, xsrc_end, it);
120 const BidirectIterator last = make_iter (xsrc_end, xsrc, xsrc_end, it);
121
122 const Predicate pred (0, 0);
123
124 const std::size_t last_n_op_assign = T::n_total_op_assign_;
125
126 bool result = false;
127
128 if (ppred) {
129 result = prev ?
130 std::prev_permutation (first, last, pred)
131 : std::next_permutation (first, last, pred);
132 }
133 else {
134 result = prev ?
135 std::prev_permutation (first, last)
136 : std::next_permutation (first, last);
137 }
138
139 std::size_t n_ops_assign = T::n_total_op_assign_ - last_n_op_assign;
140
141 // verify the returned value: 25.3.9, p1 and p4
142 bool success = result == res;
143 rw_assert (success, 0, line,
144 "line %d. %s <%s%{?}, %s%{;}> (\"%s\", ...) == %b, got %b",
145 __LINE__, algname, itname, 0 != ppred, predname,
146 src, result, res);
147
148 // verify the permutation result
149 std::size_t i = 0;
150 for ( ; i < nsrc; i++) {
151 success = xsrc [i].data_.val_ == dst [i];
152 if (!success)
153 break;
154 }
155
156 // to avoid errors in --trace mode
157 i = i < nsrc ? i : nsrc - 1;
158
159 rw_assert (success, 0, line,
160 "line %d. %s <%s%{?}, %s%{;}> (\"%s\", ...) "
161 "==> got \"%{X=*.*}\", expected \"%s\"",
162 __LINE__, algname, itname, 0 != ppred, predname, src,
163 int (sizeof (*xsrc)), int (nsrc), int (i), xsrc, dst);
164
165 // verify the complexity: 25.3.9 p2 and p5.
166 // (last - first) / 2 swaps, 2 assign per swap
167 success = n_ops_assign <= nsrc;
168 rw_assert (success, 0, line,
169 "line %d. %s <%s%{?}, %s%{;}> (\"%s\", ...) "
170 "complexity: got %zu assigns, expected no more than %zu",
171 __LINE__, algname, itname, 0 != ppred, predname, src,
172 n_ops_assign, nsrc);
173
174 delete[] xsrc;
175}
176
177
179template <class T, class BidirectIterator, class Predicate>
180void test_permutations (const BidirectIterator &it,
181 const T*,
182 const Predicate *ppred,
183 bool prev)
184{
185 const char* const itname = type_name (it, (T*)0);
186 const char* const algname = prev ? "prev_permutation" : "next_permutation";
187 const char* const predname = Predicate::name();
188
189 rw_info (0, 0, 0,
190 "std::%s(%s, %2$s%{?}, %s%{;})",
191 algname, itname, 0 != ppred, predname);
192
193#define TEST(src, dst, res) \
194 test_permutations (__LINE__, src, dst, res, it, (T*)0, ppred, prev)
195
196 if (prev) {
197 // +------------- initial (source) sequence
198 // | +------- final (destination) sequence
199 // | | +-- expected return value
200 // | | |
201 // V V V
202 TEST ("a", "a", false);
203 TEST ("aa", "aa", false);
204 TEST ("ab", "ba", false);
205 TEST ("ba", "ab", true);
206
207 TEST ("bcaefigjhd", "bcaefigjdh", true);
208 TEST ("bcaefihdgj", "bcaefigjhd", true);
209
210 TEST ("hefdiacjbg", "hefdiacgjb", true);
211 TEST ("hefdiacjgb", "hefdiacjbg", true);
212
213 TEST ("aaaaaaaaaa", "aaaaaaaaaa", false);
214 TEST ("aaaaabbbbb", "bbbbbaaaaa", false);
215 TEST ("ababababab", "abababaabb", true);
216 TEST ("bbbbbaaaaa", "bbbbabaaaa", true);
217
218 TEST ("abcdefghij", "jihgfedcba", false);
219 TEST ("jihgfedcba", "jihgfedcab", true);
220 }
221 else {
222 TEST ("a", "a", false);
223 TEST ("aa", "aa", false);
224 TEST ("ab", "ba", true);
225 TEST ("ba", "ab", false);
226
227 TEST ("bcaefigjhd", "bcaefihdgj", true);
228 TEST ("bcaefigjdh", "bcaefigjhd", true);
229
230 TEST ("hefdiacjbg", "hefdiacjgb", true);
231 TEST ("hefdiacgjb", "hefdiacjbg", true);
232
233 TEST ("aaaaaaaaaa", "aaaaaaaaaa", false);
234 TEST ("aaaaabbbbb", "aaaababbbb", true);
235 TEST ("ababababab", "ababababba", true);
236 TEST ("bbbbbaaaaa", "aaaaabbbbb", false);
237
238 TEST ("abcdefghij", "abcdefghji", true);
239 TEST ("jihgfedcba", "abcdefghij", false);
240 }
241}
242
243
245/* extern */ int rw_opt_no_prev_permutation; // --no-prev_permutation
246/* extern */ int rw_opt_no_next_permutation; // --no-next_permutation
247/* extern */ int rw_opt_no_predicate; // --no-predicate
248/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
249/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
250
251
253template <class T, class Predicate>
254void test_permutations (const T*,
255 const Predicate* ppred,
256 bool prev)
257{
258 static const BidirIter<T> bidir_iter (0, 0, 0);
259 static const RandomAccessIter<T> rand_iter (0, 0, 0);
260
261 rw_info (0, 0, 0,
262 "template <class %s%{?}, class %s%{;}> "
263 "bool %s (%1$s, %1$s%{?}, %s%{;})",
264 "BidirectionalIterator", 0 != ppred, "Compare",
265 prev ? "prev_permutation" : "next_permutation",
266 0 != ppred, "Compare");
267
269 rw_note (0, 0, __LINE__, "BidirectionalIterator test disabled");
270 }
271 else {
272 test_permutations (bidir_iter, (T*)0, ppred, prev);
273 }
274
275 if (rw_opt_no_rnd_iter) {
276 rw_note (0, 0, __LINE__, "RandomAccessIterator test disabled");
277 }
278 else {
279 test_permutations (rand_iter, (T*)0, ppred, prev);
280 }
281}
282
283
285template <class T, class Predicate>
286void test_permutations (const T*,
287 const Predicate* ppred)
288{
290 rw_note (0, 0, __LINE__, "std::prev_permutation test disabled");
291 }
292 else {
293 test_permutations ((UserClass*)0, ppred, true);
294 }
295
297 rw_note (0, 0, __LINE__, "std::next_permutation test disabled");
298 }
299 else {
300 test_permutations ((UserClass*)0, ppred, false);
301 }
302}
303
304
306static int run_test (int, char*[])
307{
309
311 rw_note (0, 0, __LINE__, "predicate test disabled");
312 }
313 else {
315 }
316
317 return 0;
318}
319
320
322int main (int argc, char *argv[])
323{
324 return rw_test (argc, argv, __FILE__,
325 "lib.alg.permutation.generators",
326 0 /* no comment */,
327 run_test,
328 "|-no-prev_permutation# "
329 "|-no-next_permutation# "
330 "|-no-predicate# "
331 "|-no-BidirectionalIterator# "
332 "|-no-RandomAccessIterator#",
338}
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define y
Definition 17.names.cpp:141
#define line
Definition 17.names.cpp:490
#define res
Definition 17.names.cpp:531
#define last
Definition 17.names.cpp:487
#define x
Definition 17.names.cpp:140
volatile int result
const MyBuffer< char > nsrc[]
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define TEST(src, dst, res)
int rw_opt_no_rnd_iter
int rw_opt_no_bidir_iter
int rw_opt_no_predicate
void test_permutations(int line, const char *src, const char *dst, bool res, const BidirectIterator &it, const T *, const Predicate *ppred, bool prev)
int rw_opt_no_next_permutation
int rw_opt_no_prev_permutation
const char * type_name()
#define main
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
Definition json.h:5363
T * make_iter(T *cur, const T *, const T *, T *)
_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
static const char * name()
Less(int, int)
static conv_to_bool make(bool val)