Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
21.string.access.cpp
Go to the documentation of this file.
1
29#include <string> // for string
30#include <cstdlib> // for free(), size_t
31#include <stdexcept> // for out_of_range
32
33#include <rw_strings.h> // for StringMembers
34#include <rw_driver.h> // for rw_test()
35#include <rw_allocator.h> // for UserAlloc
36#include <rw_char.h> // for rw_expand()
37
38
40// for convenience and brevity
41#define At(sig) StringIds::at_ ## sig
42#define OpIndex(sig) StringIds::op_index_ ## sig
43
44static const char* const exceptions[] = {
45 "unknown exception", "out_of_range", "length_error",
46 "bad_alloc", "exception"
47};
48
49
51// used to exercise
52// operator[] (size_type)
53static const StringTestCase
54op_index_size_test_cases [] = {
55
56#undef TEST
57#define TEST(str, off, res) { \
58 __LINE__, off, -1, -1, -1, -1, \
59 str, sizeof str - 1, \
60 0, 0, 0, res, 0 \
61 }
62
63 // +--------------------------------------- controlled sequence
64 // | +----------------- index
65 // | | +------------- expected result
66 // | | |
67 // V V V
68 TEST ("a", 0, 'a' ),
69
70 TEST ("<U0>", 0, '\0'),
71
72 TEST ("abc", 0, 'a' ),
73 TEST ("abc", 1, 'b' ),
74 TEST ("abc", 2, 'c' ),
75
76 TEST ("<U0>ab<U0><U0>c", 0, '\0'),
77
78 TEST ("a<U0>b<U0><U0>c", 0, 'a' ),
79 TEST ("a<U0>b<U0><U0>c", 1, '\0'),
80 TEST ("a<U0>b<U0><U0>c", 2, 'b' ),
81 TEST ("a<U0>b<U0><U0>c", 3, '\0'),
82 TEST ("a<U0>b<U0><U0>c", 4, '\0'),
83 TEST ("a<U0>b<U0><U0>c", 5, 'c' ),
84
85 TEST ("a<U0>bc<U0><U0>", 5, '\0'),
86
87 TEST ("x@4096", 0, 'x' ),
88 TEST ("x@4096", 2048, 'x' ),
89 TEST ("x@4096", 4095, 'x' ),
90
91 TEST ("last", 3, 't' )
92};
93
94
96// used to exercise
97// operator[] (size_type) const
98static const StringTestCase
99op_index_const_size_test_cases [] = {
100
101#undef TEST
102#define TEST(str, off, res) { \
103 __LINE__, off, -1, -1, -1, -1, \
104 str, sizeof str - 1, \
105 0, 0, 0, res, 0 \
106 }
107
108 // +--------------------------------------- controlled sequence
109 // | +----------------- index
110 // | | +------------- expected result
111 // | | |
112 // V V V
113 TEST ("a", 0, 'a' ),
114 TEST ("a", 1, NPOS),
115
116 TEST ("", 0, NPOS),
117
118 TEST ("<U0>", 0, '\0'),
119 TEST ("<U0>", 1, NPOS),
120
121 TEST ("abc", 0, 'a' ),
122 TEST ("abc", 1, 'b' ),
123 TEST ("abc", 2, 'c' ),
124 TEST ("abc", 3, NPOS),
125
126 TEST ("<U0>ab<U0><U0>c", 0, '\0'),
127
128 TEST ("a<U0>b<U0><U0>c", 0, 'a' ),
129 TEST ("a<U0>b<U0><U0>c", 1, '\0'),
130 TEST ("a<U0>b<U0><U0>c", 2, 'b' ),
131 TEST ("a<U0>b<U0><U0>c", 3, '\0'),
132 TEST ("a<U0>b<U0><U0>c", 4, '\0'),
133 TEST ("a<U0>b<U0><U0>c", 5, 'c' ),
134 TEST ("a<U0>b<U0><U0>c", 6, NPOS),
135
136 TEST ("a<U0>bc<U0><U0>", 5, '\0'),
137
138 TEST ("x@4096", 0, 'x' ),
139 TEST ("x@4096", 2048, 'x' ),
140 TEST ("x@4096", 4095, 'x' ),
141 TEST ("x@4096", 4096, NPOS),
142
143 TEST ("last", 3, 't' )
144};
145
146
148// used to exercise
149// at (size_type)
150// at (size_type) const
151static const StringTestCase
152at_size_test_cases [] = {
153
154#define at_const_size_test_cases at_size_test_cases
155
156#undef TEST
157#define TEST(str, off, res, bthrow) { \
158 __LINE__, off, -1, -1, -1, -1, \
159 str, sizeof str - 1, \
160 0, 0, 0, res, bthrow \
161 }
162
163 // +--------------------------------------- controlled sequence
164 // | +----------------- index
165 // | | +-------------- expected result
166 // | | | +----- exception info
167 // | | | | 0 - no exception
168 // | | | | 1 - out_of_range
169 // | | | |
170 // V V V V
171 TEST ("a", 0, 'a', 0),
172 TEST ("a", 1, NPOS, 1),
173
174 TEST ("", 0, NPOS, 1),
175
176 TEST ("<U0>", 0, '\0', 0),
177 TEST ("<U0>", 1, NPOS, 1),
178
179 TEST ("abc", 0, 'a', 0),
180 TEST ("abc", 1, 'b', 0),
181 TEST ("abc", 2, 'c', 0),
182 TEST ("abc", 3, NPOS, 1),
183
184 TEST ("<U0>ab<U0><U0>c", 0, '\0', 0),
185
186 TEST ("a<U0>b<U0><U0>c", 0, 'a', 0),
187 TEST ("a<U0>b<U0><U0>c", 1, '\0', 0),
188 TEST ("a<U0>b<U0><U0>c", 2, 'b', 0),
189 TEST ("a<U0>b<U0><U0>c", 3, '\0', 0),
190 TEST ("a<U0>b<U0><U0>c", 4, '\0', 0),
191 TEST ("a<U0>b<U0><U0>c", 5, 'c', 0),
192 TEST ("a<U0>b<U0><U0>c", 6, NPOS, 1),
193
194 TEST ("a<U0>bc<U0><U0>", 5, '\0', 0),
195
196 TEST ("x@4096", 0, 'x', 0),
197 TEST ("x@4096", 2048, 'x', 0),
198 TEST ("x@4096", 4095, 'x', 0),
199 TEST ("x@4096", 4096, NPOS, 1),
200
201 TEST ("last", 3, 't', 0)
202};
203
204
206template <class charT, class Traits, class Allocator>
208 const StringFunc &func,
209 const StringTestCase &tcase)
210{
211 typedef std::basic_string <charT, Traits, Allocator> String;
212 typedef typename String::size_type SizeT;
213
214 static const std::size_t BUFSIZE = 256;
215
216 static charT wstr_buf [BUFSIZE];
217 std::size_t str_len = sizeof wstr_buf / sizeof *wstr_buf;
218 charT* wstr = rw_expand (wstr_buf, tcase.str, tcase.str_len, &str_len);
219
220 // construct the string object
221 /* const */ String str (wstr, str_len);
222 const String const_str = str;
223
224 if (wstr != wstr_buf)
225 delete[] wstr;
226
227 wstr = 0;
228
229 // save the state of the string object before the call
230 // to detect wxception safety violations (changes to
231 // the state of the object after an exception)
232 const StringState str_state (rw_get_string_state (str));
233
234#ifndef _RWSTD_NO_EXCEPTIONS
235
236 // is some exception expected ?
237 const char* expected = 1 == tcase.bthrow ? exceptions[1] : 0;
238 const char* caught = 0;
239
240#endif // _RWSTD_NO_EXCEPTIONS
241
242 try {
243
244 const charT *pres = 0;
245
246 switch (func.which_) {
247
248 case OpIndex (size):
249 pres = &str [SizeT (tcase.off)];
250 break;
251
252 case OpIndex (const_size):
253 pres = &const_str [SizeT (tcase.off)];
254 break;
255
256 case At (size):
257 pres = &str.at (SizeT (tcase.off));
258 break;
259
260 case At (const_size):
261 pres = &const_str.at (SizeT (tcase.off));
262 break;
263
264 default:
265 RW_ASSERT (!"test logic error: unknown access overload");
266 return;
267 }
268
269 const char exp_res [2] = {
270 NPOS != tcase.nres ? char (tcase.nres) : char (),
271 char ()
272 };
273
274 const bool success = 1 == rw_match (exp_res, pres, 1);
275 rw_assert (success, 0, tcase.line,
276 "line %d. %{$FUNCALL} == %{#c}, got %{#c}",
277 __LINE__, tcase.nres, *pres);
278 }
279
280#ifndef _RWSTD_NO_EXCEPTIONS
281
282 catch (const std::out_of_range &ex) {
283 caught = exceptions [1];
284 rw_assert (caught == expected, 0, tcase.line,
285 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
286 "unexpectedly%{;} caught std::%s(%#s)",
287 __LINE__, 0 != expected, expected, caught, ex.what ());
288 }
289 catch (const std::exception &ex) {
290 caught = exceptions [4];
291 rw_assert (0, 0, tcase.line,
292 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
293 "unexpectedly%{;} caught std::%s(%#s)",
294 __LINE__, 0 != expected, expected, caught, ex.what ());
295 }
296 catch (...) {
297 caught = exceptions [0];
298 rw_assert (0, 0, tcase.line,
299 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
300 "unexpectedly%{;} caught %s",
301 __LINE__, 0 != expected, expected, caught);
302 }
303
304#endif // _RWSTD_NO_EXCEPTIONS
305
306 if (caught) {
307 // verify that an exception thrown during allocation
308 // didn't cause a change in the state of the object
310 __LINE__, tcase.line, caught);
311 }
312}
313
314
317
318int main (int argc, char** argv)
319{
320 static const StringTest
321 tests [] = {
322
323#undef TEST
324#define TEST(sig) { \
325 StringIds::sig, sig ## _test_cases, \
326 sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
327 }
328
329 TEST (op_index_size),
330 TEST (op_index_const_size),
331 TEST (at_size),
332 TEST (at_const_size)
333 };
334
335 const std::size_t test_count = sizeof tests / sizeof *tests;
336
337 return rw_run_string_test (argc, argv, __FILE__,
338 "lib.string.access",
339 test_access, tests, test_count);
340}
#define charT
Definition 17.names.cpp:456
#define At(sig)
void test_access(charT, Traits *, Allocator *, const StringFunc &func, const StringTestCase &tcase)
#define OpIndex(sig)
#define TEST(str, off, res)
std::char_traits< S > Traits
#define NPOS
#define main
int caught
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 _RWSTD_SIZE_T rw_match(const char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
StringState rw_get_string_state(const String &str)
Definition rw_strings.h:752
#define DEFINE_STRING_TEST_DISPATCH(fname)
Definition rw_strings.h:885
_TEST_EXPORT int rw_run_string_test(int, char **, const char *, const char *, StringTestFunc *, const StringTest *, _RWSTD_SIZE_T)
#define RW_ASSERT(expr)
int assert_equal(const StringState &, int, int, const char *) const
_RWSTD_SIZE_T str_len
Definition rw_strings.h:597
const char * str
Definition rw_strings.h:596
_RWSTD_SIZE_T nres
Definition rw_strings.h:603