Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
rw_char.h
Go to the documentation of this file.
1
29#ifndef RW_CHAR_INCLUDED
30#define RW_CHAR_INCLUDED
31
32
33// avoid dependencies on any library headers
34// to prevent the pollution of the namespace(s)
35#include <rw/_traits.h>
36#include <rw_testdefs.h>
37
38
39struct UserChar // user-defined character type (must be POD)
40{
41#if !defined (_RWSTD_NO_LONG_DOUBLE) \
42 && !defined (__SUNPRO_CC) || __SUNPRO_CC > 0x540
43 long double f; // exercise correct alignment
44#else
45 // cannot use long double with SunPro due to a compiler
46 // bug that prevents assignments of UserChar() (PR #28328)
47 double f;
48#endif // _RWSTD_NO_LONG_DOUBLE
49
50 unsigned char c; // underlying character representation
51
52 static UserChar eos () {
53 // use UserChar::eos() instead of UserChar() to work around broken
54 // compilers (e.g., MSVC 6) that do not zero out POD structs
55 // on default construction
56 const UserChar tmp = { 0, 0 };
57 return tmp;
58 }
59
60 // definition of a POD-struct (9, p4):
61 // A POD-struct is an aggregate class that has no non-static data
62 // members of type pointer to member, non-POD-struct, non-POD-union
63 // (or array of such types) or reference, and has no user-defined
64 // copy assign-ment operator and no user-defined destructor.
65
66 // definition of an aggregate (8.5.1, p1):
67 // An aggregate is an array or a class (clause 9) with no user-declared
68 // constructors (12.1), no private or protected non-static data members
69 // (clause 11), no base classes (clause 10), and no virtual functions
70 // (10.3).
71};
72
73
75{
76 const UserChar ch = { 0.0, c };
77 return ch;
78}
79
80inline char make_char (char c, char*)
81{
82 return c;
83}
84
85#ifndef _RWSTD_NO_WCHAR_T
86
87inline wchar_t make_char (char c, wchar_t*)
88{
89 typedef unsigned char UChar;
90 return wchar_t (UChar (c));
91}
92
93#endif // _RWSTD_NO_WCHAR_T
94
96// 21.1.2, p2 of C++ 03:
97//
98// typedef INT_T int_type;
99//
100// -2- Requires: For a certain character container type char_type, a related
101// container type INT_T shall be a type or class which can represent all
102// of the valid characters converted from the corresponding char_type
103// values, as well as an end-of-file value, eof(). The type int_type
104// represents a character container type which can hold end-of-file to
105// be used as a return type of the iostream class member functions.224)
106// ____________
107// Footnote 224: If eof() can be held in char_type then some iostreams
108// operations may give surprising results.
109
111{
112 void* ptr_; // to check validity
113 int i_; // underlying int representation
114
115 // valid values are 0 through 256 with 256 representing EOF
116public:
117
118 // default ctor creates a valid object but assigns it an invalid
119 // value so that the only legal operations on it are assignment
120 // and copy
121 UserInt (): ptr_ (&i_ /* valid */), i_ (-1 /* invalid */) { /* empty */ }
122
124 : ptr_ (&i_), i_ (rhs.i_) {
125 // verify rhs is valid
126 // const_cast used to avoid MSVC 7.0 error C2446:
127 // '==' : no conversion from 'const int *' to 'void *const '
128 RW_ASSERT (_RWSTD_CONST_CAST (const void*, rhs.ptr_) == &rhs.i_);
129 RW_ASSERT (-1 <= rhs.i_ && rhs.i_ < 257); // i may be invalid
130 }
131
132 // (almost) assignable; i.e., returns void instead of UserInt&
133 // for extra robustness
134 void operator= (const UserInt &rhs) {
135 RW_ASSERT (ptr_ == &i_); // verify *this is valid
136 // verify rhs is valid
137 RW_ASSERT (_RWSTD_CONST_CAST (const void*, rhs.ptr_) == &rhs.i_);
138 RW_ASSERT (-1 <= i_ && i_ < 257); // i may be invalid
139 RW_ASSERT (-1 < rhs.i_ && rhs.i_ < 257); // rhs.i must ve valid
140
141 i_ = rhs.i_;
142 }
143
144 static UserInt eof () {
145 UserInt tmp;
146 tmp.i_ = 256; // EOF
147 return tmp;
148 }
149
150 static UserInt from_char (const UserChar &c) {
151 UserInt tmp;
152 tmp.i_ = int (c.c);
153 return tmp;
154 }
155
156 UserChar to_char () const {
157 // working around an Intel C++ 9.1 bug #380635
158 /* const */ UserChar tmp /* = { 0, i_ }*/;
159 tmp.f = 0;
160 tmp.c = (unsigned char)(i_);
161 return tmp;
162 }
163
165 RW_ASSERT (ptr_ == &i_); // verify *this is valid
166 RW_ASSERT (-1 <= i_ == i_ < 257); // i may be invalid
167
168 i_ = _RWSTD_INT_MIN; // invalidate
169 ptr_ = &ptr_; // invalidate
170 }
171
172 bool equal (const UserInt &rhs) const {
173 // verify *this is valid
174 RW_ASSERT (_RWSTD_CONST_CAST (const void*, ptr_) == &i_);
175 // verify rhs is valid
176 RW_ASSERT (_RWSTD_CONST_CAST (const void*, rhs.ptr_) == &rhs.i_);
177 RW_ASSERT (-1 < i_ && i_ < 257); // i must ve valid
178 RW_ASSERT (-1 < rhs.i_ && rhs.i_ < 257); // rhs.i must be valid
179
180 return i_ == rhs.i_;
181 }
182};
183
184
185// user-defined character traits template
186// (declared but not defined)
187template <class charT>
188struct UserTraits;
189
190
192{
193 enum {
197 n_funs
198 };
199};
200
201
202// required specialization on char
204struct _TEST_EXPORT UserTraits<char>: std::char_traits<char>
205{
206 typedef std::char_traits<char> Base;
207 typedef Base::char_type char_type;
208 typedef Base::int_type int_type;
210
211 // avoid any dependency on the library
212 typedef int off_type; // std::streamoff
213 typedef int state_type; // std::mbstate_t
214 typedef std::fpos<state_type> pos_type; // std::fpos<state_type>
215
216 static void
217 assign (char_type&, const char_type&);
218
219 static bool
220 eq (const char_type&, const char_type&);
221
222 static bool
223 lt (const char_type&, const char_type&);
224
225 static int
226 compare (const char_type*, const char_type*, _RWSTD_SIZE_T);
227
228 static _RWSTD_SIZE_T
229 length (const char_type*);
230
231 static const char_type*
232 find (const char_type*, _RWSTD_SIZE_T, const char_type&);
233
234 static char_type*
235 copy (char_type*, const char_type*, _RWSTD_SIZE_T);
236
237 static char_type*
238 move (char_type*, const char_type*, _RWSTD_SIZE_T);
239
240 static char_type*
241 assign (char_type*, _RWSTD_SIZE_T, char_type);
242
243 static int_type
244 not_eof (const int_type&);
245
246 static char_type
247 to_char_type (const int_type&);
248
249 static int_type
250 to_int_type (const char_type&);
251
252 static bool
253 eq_int_type (const int_type&, const int_type&);
254
255 static int_type
256 eof ();
257
258 static _RWSTD_SIZE_T n_calls_ [];
259
261
262private:
263
264 // not defined to detect bad assumptions made by the library
265 UserTraits ();
266 ~UserTraits ();
267 void operator= (UserTraits&);
268};
269
270
271#ifndef _RWSTD_NO_WCHAR_T
272
273// required specialization on wchar_t
275struct _TEST_EXPORT UserTraits<wchar_t>: std::char_traits<wchar_t>
276{
277 typedef std::char_traits<wchar_t> Base;
278 typedef Base::char_type char_type;
279 typedef Base::int_type int_type;
281
282 // avoid any dependency on the library
283 typedef int off_type; // std::streamoff
284 typedef int state_type; // std::mbstate_t
285 typedef std::fpos<state_type> pos_type; // std::fpos<state_type>
286
287 static void
288 assign (char_type&, const char_type&);
289
290 static bool
291 eq (const char_type&, const char_type&);
292
293 static bool
294 lt (const char_type&, const char_type&);
295
296 static int
297 compare (const char_type*, const char_type*, _RWSTD_SIZE_T);
298
299 static _RWSTD_SIZE_T
300 length (const char_type*);
301
302 static const char_type*
303 find (const char_type*, _RWSTD_SIZE_T, const char_type&);
304
305 static char_type*
306 copy (char_type*, const char_type*, _RWSTD_SIZE_T);
307
308 static char_type*
309 move (char_type*, const char_type*, _RWSTD_SIZE_T);
310
311 static char_type*
312 assign (char_type*, _RWSTD_SIZE_T, char_type);
313
314 static int_type
315 not_eof (const int_type&);
316
317 static char_type
318 to_char_type (const int_type&);
319
320 static int_type
321 to_int_type (const char_type&);
322
323 static bool
324 eq_int_type (const int_type&, const int_type&);
325
326 static int_type
327 eof ();
328
329 static _RWSTD_SIZE_T n_calls_ [];
330
332
333private:
334
335 // not defined to detect bad assumptions made by the library
336 UserTraits ();
337 ~UserTraits ();
338 void operator= (UserTraits&);
339};
340
341#endif // _RWSTD_NO_WCHAR_T
342
343
345struct _TEST_EXPORT UserTraits<UserChar> // user-defined character traits
346{
348
351
352 // avoid any dependency on the library
353 typedef int off_type; // std::streamoff
354 typedef int state_type; // std::mbstate_t
355 typedef std::fpos<state_type> pos_type; // std::fpos<state_type>
356
357 // accesses to the char_type::f member may trigger a SIGBUS
358 // on some architectures (e.g., PA or SPARC) if the member
359 // isn't appropriately aligned
360
361 static void assign (char_type&, const char_type&);
362
363 static bool eq (const char_type&, const char_type&);
364
365 static bool lt (const char_type&, const char_type&);
366
367 static int
368 compare (const char_type*, const char_type*, _RWSTD_SIZE_T);
369
370 static _RWSTD_SIZE_T length (const char_type*);
371
372 static const char_type*
373 find (const char_type*, _RWSTD_SIZE_T, const char_type&);
374
375 static char_type*
376 copy (char_type*, const char_type*, _RWSTD_SIZE_T);
377
378 static char_type*
379 move (char_type*, const char_type*, _RWSTD_SIZE_T);
380
381 static char_type*
382 assign (char_type*, _RWSTD_SIZE_T, char_type);
383
384 static int_type not_eof (const int_type&);
385
386 static char_type to_char_type (const int_type&);
387
388 static int_type to_int_type (const char_type&);
389
390 static bool eq_int_type (const int_type&, const int_type&);
391
392 static int_type eof ();
393
394 static _RWSTD_SIZE_T n_calls_ [];
395
396private:
397
398 // not defined to detect bad assumptions made by the library
399 UserTraits ();
400 ~UserTraits ();
401 void operator= (UserTraits&);
402};
403
404
405// rw_widen() widens successive elements of src into the buffer dst
406// when (dst != 0) the last character in the buffer is guaranteed to be NUL,
407// regardless of the value of str [len]
408// when (len == SIZE_MAX && src != 0), computes len as if by evaluating
409// len = strlen(src)
410// when (src == 0 && len < SIZE_MAX), initializes the first len elements
411// of dst to NUL (i.e., such a call is the equivalent of calling
412// memset(dst, 0, len * sizeof *dst))
413// returns dst
414_TEST_EXPORT char*
415rw_widen (char* /* dst */,
416 const char* /* src */,
417 _RWSTD_SIZE_T /* len */ = _RWSTD_SIZE_MAX);
418
419// rw_expand() interprets string src as a sequence of directives and
420// widens the result of their processing into the provided buffer dst
421// when (dst != 0), otherwise into a dynamically allocated buffer of
422// sufficient size
423// each directive consists of a character C, optionally followed by
424// the '@' sign followed by a non-negative decimal number N; the result
425// of the processing of a directive is N consecutive copies of the
426// character C where (N = 1) when the '@' is absent
427// when (dst_len != 0) the function sets *dst_len to the number of
428// produced characters not counting the terminating NUL
429// the function returns the dynamically allocated buffer; the caller
430// must deallocate the buffer using the delete expression
431_TEST_EXPORT char*
432rw_expand (char* /* dst */,
433 const char* /* src */,
434 _RWSTD_SIZE_T /* src_len */ = _RWSTD_SIZE_MAX,
435 _RWSTD_SIZE_T* /* dst_len */ = 0);
436
437
438// rw_narrow() narrows successive elements of src into the buffer dst
439// (see rw_widen() for details)
440_TEST_EXPORT char*
441rw_narrow (char* /* dst */,
442 const char* /* src */,
443 _RWSTD_SIZE_T /* len */ = _RWSTD_SIZE_MAX);
444
445// rw_match() compares up to len successive elements of s1 and s2 for
446// equality until it finds a pair that do not compare equal or until
447// len comparisons has been made
448// if (len == SIZE_MAX) is true elements are compared until the first
449// mismatch is found or until the NUL character is encountered
450// returns the number of matching elements
451_TEST_EXPORT _RWSTD_SIZE_T
452rw_match (const char* /* s1 */,
453 const char* /* s2 */,
454 _RWSTD_SIZE_T /* len */ = _RWSTD_SIZE_MAX);
455
456#ifndef _RWSTD_WCHAR_T
457
458_TEST_EXPORT wchar_t*
459rw_widen (wchar_t*, const char*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX);
460
461_TEST_EXPORT wchar_t*
462rw_expand (wchar_t* /* dst */,
463 const char* /* src */,
464 _RWSTD_SIZE_T /* src_len */ = _RWSTD_SIZE_MAX,
465 _RWSTD_SIZE_T* /* dst_len */ = 0);
466
467_TEST_EXPORT char*
468rw_narrow (char*, const wchar_t*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX);
469
470_TEST_EXPORT _RWSTD_SIZE_T
471rw_match (const char*, const wchar_t*,
472 _RWSTD_SIZE_T = _RWSTD_SIZE_MAX);
473
474#endif // _RWSTD_WCHAR_T
475
477rw_widen (UserChar*, const char*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX);
478
480rw_expand (UserChar* /* dst */,
481 const char* /* src */,
482 _RWSTD_SIZE_T /* src_len */ = _RWSTD_SIZE_MAX,
483 _RWSTD_SIZE_T* /* dst_len */ = 0);
484
485_TEST_EXPORT char*
486rw_narrow (char*, const UserChar*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX);
487
488_TEST_EXPORT _RWSTD_SIZE_T
489rw_match (const char*, const UserChar*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX);
490
491
492// accessors to n_calls array, if present
493template <class charT>
494inline _RWSTD_SIZE_T*
495rw_get_call_counters (std::char_traits<charT>*, charT*)
496{
497 return 0;
498}
499
500template <class charT>
501inline _RWSTD_SIZE_T*
503{
505}
506
507
508static const struct _TEST_EXPORT UserCharFmatInit {
509 UserCharFmatInit ();
510} _rw_user_char_fmat_init;
511
512#endif // RW_CHAR_INCLUDED
#define rhs
Definition 17.names.cpp:536
#define i_
Definition 17.names.cpp:180
#define c
Definition 17.names.cpp:111
#define charT
Definition 17.names.cpp:456
#define tmp
Definition 17.names.cpp:553
#define _RWSTD_SPECIALIZED_CLASS
unsigned short wchar_t
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
UserInt()
Definition rw_char.h:121
UserChar to_char() const
Definition rw_char.h:156
static UserInt from_char(const UserChar &c)
Definition rw_char.h:150
UserInt(const UserInt &rhs)
Definition rw_char.h:123
static UserInt eof()
Definition rw_char.h:144
bool equal(const UserInt &rhs) const
Definition rw_char.h:172
void operator=(const UserInt &rhs)
Definition rw_char.h:134
~UserInt()
Definition rw_char.h:164
UserChar make_char(char c, UserChar *)
Definition rw_char.h:74
_TEST_EXPORT char * rw_expand(char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX, _RWSTD_SIZE_T *=0)
_TEST_EXPORT char * rw_narrow(char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX)
_TEST_EXPORT char * rw_widen(char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX)
_RWSTD_SIZE_T * rw_get_call_counters(std::char_traits< charT > *, charT *)
Definition rw_char.h:495
_TEST_EXPORT _RWSTD_SIZE_T rw_match(const char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX)
#define _TEST_EXPORT
Definition rw_testdefs.h:55
#define RW_ASSERT(expr)
unsigned char UChar
Definition collate.cpp:122
unsigned char c
Definition rw_char.h:50
static UserChar eos()
Definition rw_char.h:52
long double f
Definition rw_char.h:43
std::fpos< state_type > pos_type
Definition rw_char.h:355
TraitsMemFunc MemFun
Definition rw_char.h:347
static char_type * assign(char_type *, _RWSTD_SIZE_T, char_type)
static char_type * assign(char_type *, _RWSTD_SIZE_T, char_type)
TraitsMemFunc MemFun
Definition rw_char.h:209
std::char_traits< char > Base
Definition rw_char.h:206
std::fpos< state_type > pos_type
Definition rw_char.h:214
static int_type eof_
Definition rw_char.h:260
Base::int_type int_type
Definition rw_char.h:208
Base::char_type char_type
Definition rw_char.h:207
static char_type * assign(char_type *, _RWSTD_SIZE_T, char_type)
std::fpos< state_type > pos_type
Definition rw_char.h:285
Base::int_type int_type
Definition rw_char.h:279
TraitsMemFunc MemFun
Definition rw_char.h:280
std::char_traits< wchar_t > Base
Definition rw_char.h:277
Base::char_type char_type
Definition rw_char.h:278
static int_type eof_
Definition rw_char.h:331