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