3 // Testing character type and state type with char_traits and codecvt
4 // specializations for the C++ library testsuite.
6 // Copyright (C) 2003, 2005 Free Software Foundation, Inc.
8 // This file is part of the GNU ISO C++ Library. This library is free
9 // software; you can redistribute it and/or modify it under the
10 // terms of the GNU General Public License as published by the
11 // Free Software Foundation; either version 2, or (at your option)
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License along
20 // with this library; see the file COPYING. If not, write to the Free
21 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
24 // As a special exception, you may use this file as part of a free software
25 // library without restriction. Specifically, if other files instantiate
26 // templates or use macros or inline functions from this file, or you compile
27 // this file and link it with other files to produce an executable, this
28 // file does not by itself cause the resulting executable to be covered by
29 // the GNU General Public License. This exception does not however
30 // invalidate any other reasons why the executable file might be covered by
31 // the GNU General Public License.
33 #ifndef _GLIBCXX_TESTSUITE_CHARACTER_H
34 #define _GLIBCXX_TESTSUITE_CHARACTER_H
37 #include <string> // for char_traits
38 #include <locale> // for codecvt
39 #include <ext/pod_char_traits.h>
49 operator==(const pod_int
& lhs
, const pod_int
& rhs
)
50 { return lhs
.value
== rhs
.value
; }
53 operator<(const pod_int
& lhs
, const pod_int
& rhs
)
54 { return lhs
.value
< rhs
.value
; }
62 operator==(const pod_state
& lhs
, const pod_state
& rhs
)
63 { return lhs
.value
== rhs
.value
; }
66 operator<(const pod_state
& lhs
, const pod_state
& rhs
)
67 { return lhs
.value
< rhs
.value
; }
69 // Alternate character types.
70 using __gnu_cxx::character
;
71 typedef character
<unsigned char, pod_int
, pod_state
> pod_char
;
72 typedef character
<unsigned char, unsigned int, pod_state
> pod_uchar
;
73 typedef character
<unsigned short, unsigned int> pod_ushort
;
74 typedef character
<unsigned int, unsigned long> pod_uint
;
82 inline __gnu_test::pod_char::char_type
83 __gnu_test::pod_char::char_type::from(const V2
& v
)
85 char_type ret
= { static_cast<value_type
>(v
.value
) };
92 __gnu_test::pod_char::char_type::to(const char_type
& c
)
100 inline __gnu_test::pod_uchar::char_type
101 __gnu_test::pod_uchar::char_type::from(const V2
& v
)
104 ret
.value
= (v
>> 5);
109 template<typename V2
>
111 __gnu_test::pod_uchar::char_type::to(const char_type
& c
)
112 { return static_cast<V2
>(c
.value
<< 5); }
113 }; // namespace __gnu_test
117 // codecvt specialization
119 // The conversion performed by the specialization is not supposed to
120 // be useful, rather it has been designed to demonstrate the
121 // essential features of stateful conversions:
122 // * Number and value of bytes for each internal character depends on the
123 // state in addition to the character itself.
124 // * Unshift produces an unshift sequence and resets the state. On input
125 // the unshift sequence causes the state to be reset.
127 // The conversion for output is as follows:
128 // 1. Calculate the value tmp by xor-ing the state and the internal
130 // 2. Split tmp into either two or three bytes depending on the value of
131 // state. Output those bytes.
132 // 3. tmp becomes the new value of state.
134 class codecvt
<__gnu_test::pod_uchar
, char, __gnu_test::pod_state
>
135 : public __codecvt_abstract_base
<__gnu_test::pod_uchar
, char,
136 __gnu_test::pod_state
>
139 typedef codecvt_base::result result
;
140 typedef __gnu_test::pod_uchar intern_type
;
141 typedef char extern_type
;
142 typedef __gnu_test::pod_state state_type
;
143 typedef __codecvt_abstract_base
<intern_type
, extern_type
, state_type
>
146 explicit codecvt(size_t refs
= 0) : base_type(refs
)
149 static locale::id id
;
156 do_out(state_type
& state
, const intern_type
* from
,
157 const intern_type
* from_end
, const intern_type
*& from_next
,
158 extern_type
* to
, extern_type
* to_limit
,
159 extern_type
*& to_next
) const
161 while (from
< from_end
&& to
< to_limit
)
163 unsigned char tmp
= (state
.value
^ from
->value
);
164 if (state
.value
& 0x8)
166 if (to
>= to_limit
- 2)
169 *to
++ = ((tmp
>> 3) & 0x7);
170 *to
++ = ((tmp
>> 6) & 0x3);
174 if (to
>= to_limit
- 1)
177 *to
++ = ((tmp
>> 4) & 0xf);
185 return (from
< from_end
) ? partial
: ok
;
189 do_in(state_type
& state
, const extern_type
* from
,
190 const extern_type
* from_end
, const extern_type
*& from_next
,
191 intern_type
* to
, intern_type
* to_limit
,
192 intern_type
*& to_next
) const
194 while (from
< from_end
&& to
< to_limit
)
196 unsigned char c
= *from
;
206 if (state
.value
& 0x8)
208 if (from
>= from_end
- 2)
210 tmp
= (*from
++ & 0x7);
211 tmp
|= ((*from
++ << 3) & 0x38);
212 tmp
|= ((*from
++ << 6) & 0xc0);
216 if (from
>= from_end
- 1)
218 tmp
= (*from
++ & 0xf);
219 tmp
|= ((*from
++ << 4) & 0xf0);
221 to
->value
= (tmp
^ state
.value
);
228 return (from
< from_end
) ? partial
: ok
;
232 do_unshift(state_type
& state
, extern_type
* to
, extern_type
* to_limit
,
233 extern_type
*& to_next
) const
235 for (unsigned int i
= 0; i
< CHAR_BIT
; ++i
)
237 unsigned int mask
= (1 << i
);
238 if (state
.value
& mask
)
246 state
.value
&= ~mask
;
247 *to
++ = static_cast<unsigned char>(~mask
);
252 return state
.value
== 0 ? ok
: error
;
256 do_encoding() const throw()
260 do_always_noconv() const throw()
264 do_length(state_type
& state
, const extern_type
* from
,
265 const extern_type
* end
, size_t max
) const
267 const extern_type
* beg
= from
;
268 while (from
< end
&& max
)
270 unsigned char c
= *from
;
280 if (state
.value
& 0x8)
284 tmp
= (*from
++ & 0x7);
285 tmp
|= ((*from
++ << 3) & 0x38);
286 tmp
|= ((*from
++ << 6) & 0xc0);
292 tmp
= (*from
++ & 0xf);
293 tmp
|= ((*from
++ << 4) & 0xf0);
301 // Maximum 8 bytes unshift sequence followed by max 3 bytes for
304 do_max_length() const throw()
309 class ctype
<__gnu_test::pod_uchar
>
310 : public __ctype_abstract_base
<__gnu_test::pod_uchar
>
313 typedef __gnu_test::pod_uchar char_type
;
315 explicit ctype(size_t refs
= 0)
316 : __ctype_abstract_base
<__gnu_test::pod_uchar
>(refs
) { }
318 static locale::id id
;
325 do_is(mask
, char_type
) const
328 virtual const char_type
*
329 do_is(const char_type
* low
, const char_type
* high
, mask
* vec
) const
331 fill_n(vec
, high
- low
, mask());
335 virtual const char_type
*
336 do_scan_is(mask
, const char_type
*, const char_type
* high
) const
339 virtual const char_type
*
340 do_scan_not(mask
, const char_type
* low
, const char_type
*) const
344 do_toupper(char_type c
) const
347 virtual const char_type
*
348 do_toupper(char_type
*, const char_type
* high
) const
352 do_tolower(char_type c
) const
355 virtual const char_type
*
356 do_tolower(char_type
*, const char_type
* high
) const
360 do_widen(char c
) const
361 { return __gnu_test::pod_uchar::from
<char>(c
); }
364 do_widen(const char* low
, const char* high
, char_type
* dest
) const
366 transform(low
, high
, dest
, &__gnu_test::pod_uchar::from
<char>);
371 do_narrow(char_type
, char dfault
) const
374 virtual const char_type
*
375 do_narrow(const char_type
* low
, const char_type
* high
,
376 char dfault
, char* dest
) const
378 fill_n(dest
, high
- low
, dfault
);
383 // numpunct specializations
385 class numpunct
<__gnu_test::pod_uint
>
386 : public locale::facet
389 typedef __gnu_test::pod_uint char_type
;
390 typedef basic_string
<char_type
> string_type
;
392 static locale::id id
;
395 numpunct(size_t refs
= 0)
396 : locale::facet(refs
)
400 decimal_point() const
401 { return this->do_decimal_point(); }
404 thousands_sep() const
405 { return this->do_thousands_sep(); }
409 { return this->do_grouping(); }
413 { return this->do_truename(); }
417 { return this->do_falsename(); }
424 do_decimal_point() const
425 { return char_type(); }
428 do_thousands_sep() const
429 { return char_type(); }
437 { return string_type(); }
441 { return string_type(); }
445 class moneypunct
<__gnu_test::pod_uint
>
446 : public locale::facet
, public money_base
449 typedef __gnu_test::pod_uint char_type
;
450 typedef basic_string
<char_type
> string_type
;
452 static locale::id id
;
453 static const bool intl
= false;
456 moneypunct(size_t refs
= 0)
457 : locale::facet(refs
)
461 decimal_point() const
462 { return this->do_decimal_point(); }
465 thousands_sep() const
466 { return this->do_thousands_sep(); }
470 { return this->do_grouping(); }
474 { return this->do_curr_symbol(); }
477 positive_sign() const
478 { return this->do_positive_sign(); }
481 negative_sign() const
482 { return this->do_negative_sign(); }
486 { return this->do_frac_digits(); }
490 { return this->do_pos_format(); }
494 { return this->do_neg_format(); }
501 do_decimal_point() const
502 { return char_type(); }
505 do_thousands_sep() const
506 { return char_type(); }
513 do_curr_symbol() const
514 { return string_type(); }
517 do_positive_sign() const
518 { return string_type(); }
521 do_negative_sign() const
522 { return string_type(); }
525 do_frac_digits() const
529 do_pos_format() const
530 { return pattern(); }
533 do_neg_format() const
534 { return pattern(); }
538 #endif // _GLIBCXX_TESTSUITE_CHARACTER_H