]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/util/testsuite_character.h
* many: Replace uses of __GXX_EXPERIMENTAL_CXX0X__ with __cplusplus.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / util / testsuite_character.h
CommitLineData
5e93f39f 1// -*- C++ -*-
5305b1ae 2
5e93f39f
PR
3// Testing character type and state type with char_traits and codecvt
4// specializations for the C++ library testsuite.
5//
748086b7 6// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
fa52081d 7// Free Software Foundation, Inc.
5e93f39f
PR
8//
9// This file is part of the GNU ISO C++ Library. This library is free
10// software; you can redistribute it and/or modify it under the
11// terms of the GNU General Public License as published by the
748086b7 12// Free Software Foundation; either version 3, or (at your option)
5e93f39f
PR
13// any later version.
14//
15// This library is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License along
748086b7
JJ
21// with this library; see the file COPYING3. If not see
22// <http://www.gnu.org/licenses/>.
5e93f39f 23//
5e93f39f
PR
24
25#ifndef _GLIBCXX_TESTSUITE_CHARACTER_H
26#define _GLIBCXX_TESTSUITE_CHARACTER_H
27
5305b1ae 28#include <climits>
5e93f39f
PR
29#include <string> // for char_traits
30#include <locale> // for codecvt
f56fe8ff 31#include <algorithm> // for transform
5305b1ae 32#include <ext/pod_char_traits.h>
5e93f39f
PR
33
34namespace __gnu_test
35{
821503db 36 struct pod_int
5e93f39f 37 {
821503db 38 int value;
fa52081d 39
734f5023 40#if __cplusplus >= 201103L
fa52081d
PC
41 // For std::iota.
42 pod_int&
43 operator++()
44 {
45 ++value;
46 return *this;
47 }
48#endif
5e93f39f 49 };
fa52081d 50
4f99f3d0
BK
51 // For 20.1 requirements for instantiable type: equality comparable
52 // and less than comparable.
821503db
BK
53 inline bool
54 operator==(const pod_int& lhs, const pod_int& rhs)
55 { return lhs.value == rhs.value; }
56
ce345590 57 inline bool
821503db
BK
58 operator<(const pod_int& lhs, const pod_int& rhs)
59 { return lhs.value < rhs.value; }
ce345590 60
4f99f3d0
BK
61 // For 26 numeric algorithms requirements, need addable,
62 // subtractable, multiplicable.
63 inline pod_int
64 operator+(const pod_int& lhs, const pod_int& rhs)
65 {
66 pod_int ret = { lhs.value + rhs.value };
67 return ret;
68 }
69
70 inline pod_int
71 operator-(const pod_int& lhs, const pod_int& rhs)
72 {
73 pod_int ret = { lhs.value - rhs.value };
74 return ret;
75 }
76
77 inline pod_int
78 operator*(const pod_int& lhs, const pod_int& rhs)
79 {
80 pod_int ret = { lhs.value * rhs.value };
81 return ret;
82 }
83
821503db 84 struct pod_state
5e93f39f 85 {
821503db 86 unsigned long value;
5e93f39f 87 };
5305b1ae 88
821503db
BK
89 inline bool
90 operator==(const pod_state& lhs, const pod_state& rhs)
91 { return lhs.value == rhs.value; }
5305b1ae
BK
92
93 inline bool
821503db
BK
94 operator<(const pod_state& lhs, const pod_state& rhs)
95 { return lhs.value < rhs.value; }
5305b1ae 96
821503db
BK
97 // Alternate character types.
98 using __gnu_cxx::character;
99 typedef character<unsigned char, pod_int, pod_state> pod_char;
100 typedef character<unsigned char, unsigned int, pod_state> pod_uchar;
101 typedef character<unsigned short, unsigned int> pod_ushort;
a70c902e 102 typedef character<unsigned int, unsigned long> pod_uint;
9c12301f 103}
5e93f39f 104
3cbc7af0
BK
105namespace __gnu_cxx
106{
821503db
BK
107 // Specializations.
108 // pod_char
5e93f39f 109 template<>
821503db 110 template<typename V2>
9c12301f
MM
111 inline __gnu_test::pod_char::char_type
112 __gnu_test::pod_char::char_type::from(const V2& v)
5e93f39f 113 {
821503db
BK
114 char_type ret = { static_cast<value_type>(v.value) };
115 return ret;
5e93f39f
PR
116 }
117
821503db
BK
118 template<>
119 template<typename V2>
120 inline V2
9c12301f 121 __gnu_test::pod_char::char_type::to(const char_type& c)
5e93f39f 122 {
821503db
BK
123 V2 ret = { c.value };
124 return ret;
5e93f39f 125 }
821503db 126
821503db
BK
127 template<>
128 template<typename V2>
9c12301f
MM
129 inline __gnu_test::pod_uchar::char_type
130 __gnu_test::pod_uchar::char_type::from(const V2& v)
5e93f39f
PR
131 {
132 char_type ret;
821503db 133 ret.value = (v >> 5);
5e93f39f
PR
134 return ret;
135 }
136
821503db
BK
137 template<>
138 template<typename V2>
139 inline V2
9c12301f 140 __gnu_test::pod_uchar::char_type::to(const char_type& c)
821503db 141 { return static_cast<V2>(c.value << 5); }
799a6e36 142} // namespace __gnu_test
5e93f39f 143
821503db
BK
144namespace std
145{
5e93f39f
PR
146 // codecvt specialization
147 //
148 // The conversion performed by the specialization is not supposed to
149 // be useful, rather it has been designed to demonstrate the
150 // essential features of stateful conversions:
151 // * Number and value of bytes for each internal character depends on the
152 // state in addition to the character itself.
153 // * Unshift produces an unshift sequence and resets the state. On input
154 // the unshift sequence causes the state to be reset.
155 //
156 // The conversion for output is as follows:
157 // 1. Calculate the value tmp by xor-ing the state and the internal
158 // character
159 // 2. Split tmp into either two or three bytes depending on the value of
160 // state. Output those bytes.
161 // 3. tmp becomes the new value of state.
162 template<>
821503db
BK
163 class codecvt<__gnu_test::pod_uchar, char, __gnu_test::pod_state>
164 : public __codecvt_abstract_base<__gnu_test::pod_uchar, char,
165 __gnu_test::pod_state>
5e93f39f
PR
166 {
167 public:
821503db
BK
168 typedef codecvt_base::result result;
169 typedef __gnu_test::pod_uchar intern_type;
170 typedef char extern_type;
171 typedef __gnu_test::pod_state state_type;
172 typedef __codecvt_abstract_base<intern_type, extern_type, state_type>
173 base_type;
174
175 explicit codecvt(size_t refs = 0) : base_type(refs)
5e93f39f
PR
176 { }
177
5e93f39f
PR
178 static locale::id id;
179
180 protected:
181 ~codecvt()
182 { }
183
184 virtual result
185 do_out(state_type& state, const intern_type* from,
186 const intern_type* from_end, const intern_type*& from_next,
187 extern_type* to, extern_type* to_limit,
188 extern_type*& to_next) const
189 {
190 while (from < from_end && to < to_limit)
191 {
821503db
BK
192 unsigned char tmp = (state.value ^ from->value);
193 if (state.value & 0x8)
5e93f39f
PR
194 {
195 if (to >= to_limit - 2)
196 break;
197 *to++ = (tmp & 0x7);
198 *to++ = ((tmp >> 3) & 0x7);
199 *to++ = ((tmp >> 6) & 0x3);
200 }
201 else
202 {
203 if (to >= to_limit - 1)
204 break;
205 *to++ = (tmp & 0xf);
206 *to++ = ((tmp >> 4) & 0xf);
207 }
821503db 208 state.value = tmp;
5e93f39f
PR
209 ++from;
210 }
211
212 from_next = from;
213 to_next = to;
214 return (from < from_end) ? partial : ok;
215 }
216
217 virtual result
218 do_in(state_type& state, const extern_type* from,
219 const extern_type* from_end, const extern_type*& from_next,
220 intern_type* to, intern_type* to_limit,
221 intern_type*& to_next) const
222 {
223 while (from < from_end && to < to_limit)
224 {
225 unsigned char c = *from;
226 if (c & 0xc0)
227 {
228 // Unshift sequence
821503db 229 state.value &= c;
5e93f39f
PR
230 ++from;
231 continue;
232 }
233
234 unsigned char tmp;
821503db 235 if (state.value & 0x8)
5e93f39f
PR
236 {
237 if (from >= from_end - 2)
238 break;
239 tmp = (*from++ & 0x7);
240 tmp |= ((*from++ << 3) & 0x38);
241 tmp |= ((*from++ << 6) & 0xc0);
242 }
243 else
244 {
245 if (from >= from_end - 1)
246 break;
247 tmp = (*from++ & 0xf);
248 tmp |= ((*from++ << 4) & 0xf0);
249 }
821503db
BK
250 to->value = (tmp ^ state.value);
251 state.value = tmp;
5e93f39f
PR
252 ++to;
253 }
254
255 from_next = from;
256 to_next = to;
257 return (from < from_end) ? partial : ok;
258 }
259
260 virtual result
261 do_unshift(state_type& state, extern_type* to, extern_type* to_limit,
262 extern_type*& to_next) const
263 {
264 for (unsigned int i = 0; i < CHAR_BIT; ++i)
265 {
266 unsigned int mask = (1 << i);
821503db 267 if (state.value & mask)
5e93f39f
PR
268 {
269 if (to == to_limit)
270 {
271 to_next = to;
272 return partial;
273 }
274
821503db 275 state.value &= ~mask;
5e93f39f
PR
276 *to++ = static_cast<unsigned char>(~mask);
277 }
278 }
279
280 to_next = to;
821503db 281 return state.value == 0 ? ok : error;
5e93f39f
PR
282 }
283
284 virtual int
285 do_encoding() const throw()
286 { return -1; }
287
288 virtual bool
289 do_always_noconv() const throw()
290 { return false; }
291
292 virtual int
293 do_length(state_type& state, const extern_type* from,
294 const extern_type* end, size_t max) const
295 {
296 const extern_type* beg = from;
3531cf5e 297 while (from < end)
5e93f39f
PR
298 {
299 unsigned char c = *from;
300 if (c & 0xc0)
301 {
302 // Unshift sequence
821503db 303 state.value &= c;
5e93f39f
PR
304 ++from;
305 continue;
306 }
3531cf5e
DK
307
308 if (max == 0) break;
5e93f39f
PR
309
310 unsigned char tmp;
821503db 311 if (state.value & 0x8)
5e93f39f
PR
312 {
313 if (from >= end - 2)
314 break;
315 tmp = (*from++ & 0x7);
316 tmp |= ((*from++ << 3) & 0x38);
317 tmp |= ((*from++ << 6) & 0xc0);
318 }
319 else
320 {
321 if (from >= end - 1)
322 break;
323 tmp = (*from++ & 0xf);
324 tmp |= ((*from++ << 4) & 0xf0);
325 }
821503db 326 state.value = tmp;
5e93f39f
PR
327 --max;
328 }
329 return from - beg;
330 }
331
332 // Maximum 8 bytes unshift sequence followed by max 3 bytes for
333 // one character.
334 virtual int
335 do_max_length() const throw()
336 { return 11; }
337 };
338
5305b1ae 339 template<>
821503db
BK
340 class ctype<__gnu_test::pod_uchar>
341 : public __ctype_abstract_base<__gnu_test::pod_uchar>
5305b1ae 342 {
821503db
BK
343 public:
344 typedef __gnu_test::pod_uchar char_type;
5305b1ae 345
821503db
BK
346 explicit ctype(size_t refs = 0)
347 : __ctype_abstract_base<__gnu_test::pod_uchar>(refs) { }
5305b1ae 348
821503db 349 static locale::id id;
5305b1ae 350
821503db
BK
351 protected:
352 ~ctype()
353 { }
5305b1ae 354
821503db 355 virtual bool
8b5bc374 356 do_is(mask, char_type) const
821503db
BK
357 { return false; }
358
359 virtual const char_type*
360 do_is(const char_type* low, const char_type* high, mask* vec) const
5305b1ae 361 {
821503db
BK
362 fill_n(vec, high - low, mask());
363 return high;
5305b1ae
BK
364 }
365
821503db 366 virtual const char_type*
8b5bc374 367 do_scan_is(mask, const char_type*, const char_type* high) const
821503db
BK
368 { return high; }
369
370 virtual const char_type*
8b5bc374 371 do_scan_not(mask, const char_type* low, const char_type*) const
821503db
BK
372 { return low; }
373
374 virtual char_type
375 do_toupper(char_type c) const
376 { return c; }
5305b1ae 377
821503db 378 virtual const char_type*
8b5bc374 379 do_toupper(char_type*, const char_type* high) const
821503db
BK
380 { return high; }
381
382 virtual char_type
383 do_tolower(char_type c) const
384 { return c; }
385
386 virtual const char_type*
8b5bc374 387 do_tolower(char_type*, const char_type* high) const
821503db
BK
388 { return high; }
389
390 virtual char_type
391 do_widen(char c) const
392 { return __gnu_test::pod_uchar::from<char>(c); }
393
394 virtual const char*
395 do_widen(const char* low, const char* high, char_type* dest) const
5305b1ae 396 {
821503db
BK
397 transform(low, high, dest, &__gnu_test::pod_uchar::from<char>);
398 return high;
5305b1ae
BK
399 }
400
821503db
BK
401 virtual char
402 do_narrow(char_type, char dfault) const
403 { return dfault; }
404
405 virtual const char_type*
406 do_narrow(const char_type* low, const char_type* high,
407 char dfault, char* dest) const
5305b1ae 408 {
821503db
BK
409 fill_n(dest, high - low, dfault);
410 return high;
5305b1ae
BK
411 }
412 };
a70c902e
PC
413
414 // numpunct specializations
415 template<>
416 class numpunct<__gnu_test::pod_uint>
417 : public locale::facet
418 {
419 public:
420 typedef __gnu_test::pod_uint char_type;
421 typedef basic_string<char_type> string_type;
422
423 static locale::id id;
424
425 explicit
426 numpunct(size_t refs = 0)
427 : locale::facet(refs)
428 { }
429
430 char_type
431 decimal_point() const
432 { return this->do_decimal_point(); }
433
434 char_type
435 thousands_sep() const
436 { return this->do_thousands_sep(); }
437
438 string
439 grouping() const
440 { return this->do_grouping(); }
441
442 string_type
443 truename() const
444 { return this->do_truename(); }
445
446 string_type
447 falsename() const
448 { return this->do_falsename(); }
449
450 protected:
451 ~numpunct()
452 { }
453
454 virtual char_type
455 do_decimal_point() const
456 { return char_type(); }
457
458 virtual char_type
459 do_thousands_sep() const
460 { return char_type(); }
461
462 virtual string
463 do_grouping() const
464 { return string(); }
465
466 virtual string_type
467 do_truename() const
468 { return string_type(); }
469
470 virtual string_type
471 do_falsename() const
472 { return string_type(); }
473 };
474
475 template<>
476 class moneypunct<__gnu_test::pod_uint>
477 : public locale::facet, public money_base
478 {
479 public:
480 typedef __gnu_test::pod_uint char_type;
481 typedef basic_string<char_type> string_type;
482
483 static locale::id id;
484 static const bool intl = false;
485
486 explicit
487 moneypunct(size_t refs = 0)
488 : locale::facet(refs)
489 { }
490
491 char_type
492 decimal_point() const
493 { return this->do_decimal_point(); }
494
495 char_type
496 thousands_sep() const
497 { return this->do_thousands_sep(); }
498
499 string
500 grouping() const
501 { return this->do_grouping(); }
502
503 string_type
504 curr_symbol() const
505 { return this->do_curr_symbol(); }
506
507 string_type
508 positive_sign() const
509 { return this->do_positive_sign(); }
510
511 string_type
512 negative_sign() const
513 { return this->do_negative_sign(); }
514
515 int
516 frac_digits() const
517 { return this->do_frac_digits(); }
518
519 pattern
520 pos_format() const
521 { return this->do_pos_format(); }
522
523 pattern
524 neg_format() const
525 { return this->do_neg_format(); }
526
527 protected:
528 ~moneypunct()
529 { }
530
531 virtual char_type
532 do_decimal_point() const
533 { return char_type(); }
534
535 virtual char_type
536 do_thousands_sep() const
537 { return char_type(); }
538
539 virtual string
540 do_grouping() const
541 { return string(); }
542
543 virtual string_type
544 do_curr_symbol() const
545 { return string_type(); }
546
547 string_type
548 do_positive_sign() const
549 { return string_type(); }
550
551 string_type
552 do_negative_sign() const
553 { return string_type(); }
554
555 int
556 do_frac_digits() const
557 { return 0; }
558
559 pattern
560 do_pos_format() const
561 { return pattern(); }
562
563 pattern
564 do_neg_format() const
565 { return pattern(); }
566 };
5e93f39f
PR
567} // namespace std
568
569#endif // _GLIBCXX_TESTSUITE_CHARACTER_H
570