Bug Summary

File:usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/char_traits.h
Warning:line 107, column 21
The left operand of '==' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ustream.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D HAVE_GCC_ATOMICS=0 -D _REENTRANT -D U_HAVE_ELF_H=1 -D U_HAVE_STRTOD_L=1 -D U_HAVE_XLOCALE_H=0 -D U_HAVE_STRING_VIEW=1 -I . -I ../common -I ../i18n -D U_ATTRIBUTE_DEPRECATED= -D U_IO_IMPLEMENTATION -D PIC -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wwrite-strings -Wno-long-long -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/io -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ ustream.cpp

ustream.cpp

1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3/*
4**********************************************************************
5* Copyright (C) 2001-2016, International Business Machines
6* Corporation and others. All Rights Reserved.
7**********************************************************************
8* FILE NAME : ustream.cpp
9*
10* Modification History:
11*
12* Date Name Description
13* 06/25/2001 grhoten Move iostream from unistr.h to here
14******************************************************************************
15*/
16
17#include "unicode/utypes.h"
18
19#if !UCONFIG_NO_CONVERSION0
20
21#include "unicode/uobject.h"
22#include "unicode/ustream.h"
23#include "unicode/ucnv.h"
24#include "unicode/uchar.h"
25#include "unicode/utf16.h"
26#include "ustr_cnv.h"
27#include "cmemory.h"
28#include <string.h>
29
30// console IO
31
32#define STD_NAMESPACEstd:: std::
33
34#define STD_OSTREAMstd:: ostream STD_NAMESPACEstd:: ostream
35#define STD_ISTREAMstd:: istream STD_NAMESPACEstd:: istream
36
37U_NAMESPACE_BEGINnamespace icu_67 {
38
39U_IO_API__attribute__((visibility("default"))) STD_OSTREAMstd:: ostream & U_EXPORT2
40operator<<(STD_OSTREAMstd:: ostream& stream, const UnicodeString& str)
41{
42 if(str.length() > 0) {
1
Assuming the condition is true
2
Taking true branch
43 char buffer[200];
44 UConverter *converter;
45 UErrorCode errorCode = U_ZERO_ERROR;
46
47 // use the default converter to convert chunks of text
48 converter = u_getDefaultConverteru_getDefaultConverter_67(&errorCode);
49 if(U_SUCCESS(errorCode)) {
3
Taking true branch
50 const UChar *us = str.getBuffer();
51 const UChar *uLimit = us + str.length();
52 char *s, *sLimit = buffer + (sizeof(buffer) - 1);
53 do {
54 errorCode = U_ZERO_ERROR;
55 s = buffer;
56 ucnv_fromUnicodeucnv_fromUnicode_67(converter, &s, sLimit, &us, uLimit, 0, FALSE0, &errorCode);
57 *s = 0;
58
59 // write this chunk
60 if(s > buffer) {
4
Assuming 's' is > 'buffer'
5
Taking true branch
61 stream << buffer;
6
Calling 'operator<<<std::char_traits<char>>'
62 }
63 } while(errorCode == U_BUFFER_OVERFLOW_ERROR);
64 u_releaseDefaultConverteru_releaseDefaultConverter_67(converter);
65 }
66 }
67
68/* stream.flush();*/
69 return stream;
70}
71
72U_IO_API__attribute__((visibility("default"))) STD_ISTREAMstd:: istream & U_EXPORT2
73operator>>(STD_ISTREAMstd:: istream& stream, UnicodeString& str)
74{
75 // This is like ICU status checking.
76 if (stream.fail()) {
77 return stream;
78 }
79
80 /* ipfx should eat whitespace when ios::skipws is set */
81 UChar uBuffer[16];
82 char buffer[16];
83 int32_t idx = 0;
84 UConverter *converter;
85 UErrorCode errorCode = U_ZERO_ERROR;
86
87 // use the default converter to convert chunks of text
88 converter = u_getDefaultConverteru_getDefaultConverter_67(&errorCode);
89 if(U_SUCCESS(errorCode)) {
90 UChar *us = uBuffer;
91 const UChar *uLimit = uBuffer + UPRV_LENGTHOF(uBuffer)(int32_t)(sizeof(uBuffer)/sizeof((uBuffer)[0]));
92 const char *s, *sLimit;
93 char ch;
94 UChar ch32;
95 UBool initialWhitespace = TRUE1;
96 UBool continueReading = TRUE1;
97
98 /* We need to consume one byte at a time to see what is considered whitespace. */
99 while (continueReading) {
100 ch = stream.get();
101 if (stream.eof()) {
102 // The EOF is only set after the get() of an unavailable byte.
103 if (!initialWhitespace) {
104 stream.clear(stream.eofbit);
105 }
106 continueReading = FALSE0;
107 }
108 sLimit = &ch + (int)continueReading;
109 us = uBuffer;
110 s = &ch;
111 errorCode = U_ZERO_ERROR;
112 /*
113 Since we aren't guaranteed to see the state before this call,
114 this code won't work on stateful encodings like ISO-2022 or an EBCDIC stateful encoding.
115 We flush on the last byte to ensure that we output truncated multibyte characters.
116 */
117 ucnv_toUnicodeucnv_toUnicode_67(converter, &us, uLimit, &s, sLimit, 0, !continueReading, &errorCode);
118 if(U_FAILURE(errorCode)) {
119 /* Something really bad happened. setstate() isn't always an available API */
120 stream.clear(stream.failbit);
121 goto STOP_READING;
122 }
123 /* Was the character consumed? */
124 if (us != uBuffer) {
125 /* Reminder: ibm-1390 & JISX0213 can output 2 Unicode code points */
126 int32_t uBuffSize = static_cast<int32_t>(us-uBuffer);
127 int32_t uBuffIdx = 0;
128 while (uBuffIdx < uBuffSize) {
129 U16_NEXT(uBuffer, uBuffIdx, uBuffSize, ch32)do { (ch32)=(uBuffer)[(uBuffIdx)++]; if((((ch32)&0xfffffc00
)==0xd800)) { uint16_t __c2; if((uBuffIdx)!=(uBuffSize) &&
(((__c2=(uBuffer)[(uBuffIdx)])&0xfffffc00)==0xdc00)) { ++
(uBuffIdx); (ch32)=(((UChar32)((ch32))<<10UL)+(UChar32)
(__c2)-((0xd800<<10UL)+0xdc00-0x10000)); } } } while (0
)
;
130 if (u_isWhitespaceu_isWhitespace_67(ch32)) {
131 if (!initialWhitespace) {
132 buffer[idx++] = ch;
133 while (idx > 0) {
134 stream.putback(buffer[--idx]);
135 }
136 goto STOP_READING;
137 }
138 /* else skip intialWhitespace */
139 }
140 else {
141 if (initialWhitespace) {
142 /*
143 When initialWhitespace is TRUE, we haven't appended any
144 character yet. This is where we truncate the string,
145 to avoid modifying the string before we know if we can
146 actually read from the stream.
147 */
148 str.truncate(0);
149 initialWhitespace = FALSE0;
150 }
151 str.append(ch32);
152 }
153 }
154 idx = 0;
155 }
156 else {
157 buffer[idx++] = ch;
158 }
159 }
160STOP_READING:
161 u_releaseDefaultConverteru_releaseDefaultConverter_67(converter);
162 }
163
164/* stream.flush();*/
165 return stream;
166}
167
168U_NAMESPACE_END}
169
170#endif

/usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/ostream

1// Output streams -*- C++ -*-
2
3// Copyright (C) 1997-2020 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/ostream
26 * This is a Standard C++ Library header.
27 */
28
29//
30// ISO C++ 14882: 27.6.2 Output streams
31//
32
33#ifndef _GLIBCXX_OSTREAM1
34#define _GLIBCXX_OSTREAM1 1
35
36#pragma GCC system_header
37
38#include <ios>
39#include <bits/ostream_insert.h>
40
41namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
42{
43_GLIBCXX_BEGIN_NAMESPACE_VERSION
44
45 /**
46 * @brief Template class basic_ostream.
47 * @ingroup io
48 *
49 * @tparam _CharT Type of character stream.
50 * @tparam _Traits Traits for character type, defaults to
51 * char_traits<_CharT>.
52 *
53 * This is the base class for all output streams. It provides text
54 * formatting of all builtin types, and communicates with any class
55 * derived from basic_streambuf to do the actual output.
56 */
57 template<typename _CharT, typename _Traits>
58 class basic_ostream : virtual public basic_ios<_CharT, _Traits>
59 {
60 public:
61 // Types (inherited from basic_ios):
62 typedef _CharT char_type;
63 typedef typename _Traits::int_type int_type;
64 typedef typename _Traits::pos_type pos_type;
65 typedef typename _Traits::off_type off_type;
66 typedef _Traits traits_type;
67
68 // Non-standard Types:
69 typedef basic_streambuf<_CharT, _Traits> __streambuf_type;
70 typedef basic_ios<_CharT, _Traits> __ios_type;
71 typedef basic_ostream<_CharT, _Traits> __ostream_type;
72 typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> >
73 __num_put_type;
74 typedef ctype<_CharT> __ctype_type;
75
76 /**
77 * @brief Base constructor.
78 *
79 * This ctor is almost never called by the user directly, rather from
80 * derived classes' initialization lists, which pass a pointer to
81 * their own stream buffer.
82 */
83 explicit
84 basic_ostream(__streambuf_type* __sb)
85 { this->init(__sb); }
86
87 /**
88 * @brief Base destructor.
89 *
90 * This does very little apart from providing a virtual base dtor.
91 */
92 virtual
93 ~basic_ostream() { }
94
95 /// Safe prefix/suffix operations.
96 class sentry;
97 friend class sentry;
98
99 //@{
100 /**
101 * @brief Interface for manipulators.
102 *
103 * Manipulators such as @c std::endl and @c std::hex use these
104 * functions in constructs like "std::cout << std::endl". For more
105 * information, see the iomanip header.
106 */
107 __ostream_type&
108 operator<<(__ostream_type& (*__pf)(__ostream_type&))
109 {
110 // _GLIBCXX_RESOLVE_LIB_DEFECTS
111 // DR 60. What is a formatted input function?
112 // The inserters for manipulators are *not* formatted output functions.
113 return __pf(*this);
114 }
115
116 __ostream_type&
117 operator<<(__ios_type& (*__pf)(__ios_type&))
118 {
119 // _GLIBCXX_RESOLVE_LIB_DEFECTS
120 // DR 60. What is a formatted input function?
121 // The inserters for manipulators are *not* formatted output functions.
122 __pf(*this);
123 return *this;
124 }
125
126 __ostream_type&
127 operator<<(ios_base& (*__pf) (ios_base&))
128 {
129 // _GLIBCXX_RESOLVE_LIB_DEFECTS
130 // DR 60. What is a formatted input function?
131 // The inserters for manipulators are *not* formatted output functions.
132 __pf(*this);
133 return *this;
134 }
135 //@}
136
137 //@{
138 /**
139 * @name Inserters
140 *
141 * All the @c operator<< functions (aka <em>formatted output
142 * functions</em>) have some common behavior. Each starts by
143 * constructing a temporary object of type std::basic_ostream::sentry.
144 * This can have several effects, concluding with the setting of a
145 * status flag; see the sentry documentation for more.
146 *
147 * If the sentry status is good, the function tries to generate
148 * whatever data is appropriate for the type of the argument.
149 *
150 * If an exception is thrown during insertion, ios_base::badbit
151 * will be turned on in the stream's error state without causing an
152 * ios_base::failure to be thrown. The original exception will then
153 * be rethrown.
154 */
155
156 //@{
157 /**
158 * @brief Integer arithmetic inserters
159 * @param __n A variable of builtin integral type.
160 * @return @c *this if successful
161 *
162 * These functions use the stream's current locale (specifically, the
163 * @c num_get facet) to perform numeric formatting.
164 */
165 __ostream_type&
166 operator<<(long __n)
167 { return _M_insert(__n); }
168
169 __ostream_type&
170 operator<<(unsigned long __n)
171 { return _M_insert(__n); }
172
173 __ostream_type&
174 operator<<(bool __n)
175 { return _M_insert(__n); }
176
177 __ostream_type&
178 operator<<(short __n);
179
180 __ostream_type&
181 operator<<(unsigned short __n)
182 {
183 // _GLIBCXX_RESOLVE_LIB_DEFECTS
184 // 117. basic_ostream uses nonexistent num_put member functions.
185 return _M_insert(static_cast<unsigned long>(__n));
186 }
187
188 __ostream_type&
189 operator<<(int __n);
190
191 __ostream_type&
192 operator<<(unsigned int __n)
193 {
194 // _GLIBCXX_RESOLVE_LIB_DEFECTS
195 // 117. basic_ostream uses nonexistent num_put member functions.
196 return _M_insert(static_cast<unsigned long>(__n));
197 }
198
199#ifdef _GLIBCXX_USE_LONG_LONG1
200 __ostream_type&
201 operator<<(long long __n)
202 { return _M_insert(__n); }
203
204 __ostream_type&
205 operator<<(unsigned long long __n)
206 { return _M_insert(__n); }
207#endif
208 //@}
209
210 //@{
211 /**
212 * @brief Floating point arithmetic inserters
213 * @param __f A variable of builtin floating point type.
214 * @return @c *this if successful
215 *
216 * These functions use the stream's current locale (specifically, the
217 * @c num_get facet) to perform numeric formatting.
218 */
219 __ostream_type&
220 operator<<(double __f)
221 { return _M_insert(__f); }
222
223 __ostream_type&
224 operator<<(float __f)
225 {
226 // _GLIBCXX_RESOLVE_LIB_DEFECTS
227 // 117. basic_ostream uses nonexistent num_put member functions.
228 return _M_insert(static_cast<double>(__f));
229 }
230
231 __ostream_type&
232 operator<<(long double __f)
233 { return _M_insert(__f); }
234 //@}
235
236 /**
237 * @brief Pointer arithmetic inserters
238 * @param __p A variable of pointer type.
239 * @return @c *this if successful
240 *
241 * These functions use the stream's current locale (specifically, the
242 * @c num_get facet) to perform numeric formatting.
243 */
244 __ostream_type&
245 operator<<(const void* __p)
246 { return _M_insert(__p); }
247
248#if __cplusplus201703L >= 201703L
249 __ostream_type&
250 operator<<(nullptr_t)
251 { return *this << "nullptr"; }
252#endif
253
254 /**
255 * @brief Extracting from another streambuf.
256 * @param __sb A pointer to a streambuf
257 *
258 * This function behaves like one of the basic arithmetic extractors,
259 * in that it also constructs a sentry object and has the same error
260 * handling behavior.
261 *
262 * If @p __sb is NULL, the stream will set failbit in its error state.
263 *
264 * Characters are extracted from @p __sb and inserted into @c *this
265 * until one of the following occurs:
266 *
267 * - the input stream reaches end-of-file,
268 * - insertion into the output sequence fails (in this case, the
269 * character that would have been inserted is not extracted), or
270 * - an exception occurs while getting a character from @p __sb, which
271 * sets failbit in the error state
272 *
273 * If the function inserts no characters, failbit is set.
274 */
275 __ostream_type&
276 operator<<(__streambuf_type* __sb);
277 //@}
278
279 //@{
280 /**
281 * @name Unformatted Output Functions
282 *
283 * All the unformatted output functions have some common behavior.
284 * Each starts by constructing a temporary object of type
285 * std::basic_ostream::sentry. This has several effects, concluding
286 * with the setting of a status flag; see the sentry documentation
287 * for more.
288 *
289 * If the sentry status is good, the function tries to generate
290 * whatever data is appropriate for the type of the argument.
291 *
292 * If an exception is thrown during insertion, ios_base::badbit
293 * will be turned on in the stream's error state. If badbit is on in
294 * the stream's exceptions mask, the exception will be rethrown
295 * without completing its actions.
296 */
297
298 /**
299 * @brief Simple insertion.
300 * @param __c The character to insert.
301 * @return *this
302 *
303 * Tries to insert @p __c.
304 *
305 * @note This function is not overloaded on signed char and
306 * unsigned char.
307 */
308 __ostream_type&
309 put(char_type __c);
310
311 /**
312 * @brief Core write functionality, without sentry.
313 * @param __s The array to insert.
314 * @param __n Maximum number of characters to insert.
315 */
316 void
317 _M_write(const char_type* __s, streamsize __n)
318 {
319 const streamsize __put = this->rdbuf()->sputn(__s, __n);
320 if (__put != __n)
321 this->setstate(ios_base::badbit);
322 }
323
324 /**
325 * @brief Character string insertion.
326 * @param __s The array to insert.
327 * @param __n Maximum number of characters to insert.
328 * @return *this
329 *
330 * Characters are copied from @p __s and inserted into the stream until
331 * one of the following happens:
332 *
333 * - @p __n characters are inserted
334 * - inserting into the output sequence fails (in this case, badbit
335 * will be set in the stream's error state)
336 *
337 * @note This function is not overloaded on signed char and
338 * unsigned char.
339 */
340 __ostream_type&
341 write(const char_type* __s, streamsize __n);
342 //@}
343
344 /**
345 * @brief Synchronizing the stream buffer.
346 * @return *this
347 *
348 * If @c rdbuf() is a null pointer, changes nothing.
349 *
350 * Otherwise, calls @c rdbuf()->pubsync(), and if that returns -1,
351 * sets badbit.
352 */
353 __ostream_type&
354 flush();
355
356 /**
357 * @brief Getting the current write position.
358 * @return A file position object.
359 *
360 * If @c fail() is not false, returns @c pos_type(-1) to indicate
361 * failure. Otherwise returns @c rdbuf()->pubseekoff(0,cur,out).
362 */
363 pos_type
364 tellp();
365
366 /**
367 * @brief Changing the current write position.
368 * @param __pos A file position object.
369 * @return *this
370 *
371 * If @c fail() is not true, calls @c rdbuf()->pubseekpos(pos). If
372 * that function fails, sets failbit.
373 */
374 __ostream_type&
375 seekp(pos_type);
376
377 /**
378 * @brief Changing the current write position.
379 * @param __off A file offset object.
380 * @param __dir The direction in which to seek.
381 * @return *this
382 *
383 * If @c fail() is not true, calls @c rdbuf()->pubseekoff(off,dir).
384 * If that function fails, sets failbit.
385 */
386 __ostream_type&
387 seekp(off_type, ios_base::seekdir);
388
389 protected:
390 basic_ostream()
391 { this->init(0); }
392
393#if __cplusplus201703L >= 201103L
394 // Non-standard constructor that does not call init()
395 basic_ostream(basic_iostream<_CharT, _Traits>&) { }
396
397 basic_ostream(const basic_ostream&) = delete;
398
399 basic_ostream(basic_ostream&& __rhs)
400 : __ios_type()
401 { __ios_type::move(__rhs); }
402
403 // 27.7.3.3 Assign/swap
404
405 basic_ostream& operator=(const basic_ostream&) = delete;
406
407 basic_ostream&
408 operator=(basic_ostream&& __rhs)
409 {
410 swap(__rhs);
411 return *this;
412 }
413
414 void
415 swap(basic_ostream& __rhs)
416 { __ios_type::swap(__rhs); }
417#endif
418
419 template<typename _ValueT>
420 __ostream_type&
421 _M_insert(_ValueT __v);
422 };
423
424 /**
425 * @brief Performs setup work for output streams.
426 *
427 * Objects of this class are created before all of the standard
428 * inserters are run. It is responsible for <em>exception-safe prefix and
429 * suffix operations</em>.
430 */
431 template <typename _CharT, typename _Traits>
432 class basic_ostream<_CharT, _Traits>::sentry
433 {
434 // Data Members.
435 bool _M_ok;
436 basic_ostream<_CharT, _Traits>& _M_os;
437
438 public:
439 /**
440 * @brief The constructor performs preparatory work.
441 * @param __os The output stream to guard.
442 *
443 * If the stream state is good (@a __os.good() is true), then if the
444 * stream is tied to another output stream, @c is.tie()->flush()
445 * is called to synchronize the output sequences.
446 *
447 * If the stream state is still good, then the sentry state becomes
448 * true (@a okay).
449 */
450 explicit
451 sentry(basic_ostream<_CharT, _Traits>& __os);
452
453#pragma GCC diagnostic push
454#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
455 /**
456 * @brief Possibly flushes the stream.
457 *
458 * If @c ios_base::unitbuf is set in @c os.flags(), and
459 * @c std::uncaught_exception() is true, the sentry destructor calls
460 * @c flush() on the output stream.
461 */
462 ~sentry()
463 {
464 // XXX MT
465 if (bool(_M_os.flags() & ios_base::unitbuf) && !uncaught_exception())
466 {
467 // Can't call flush directly or else will get into recursive lock.
468 if (_M_os.rdbuf() && _M_os.rdbuf()->pubsync() == -1)
469 _M_os.setstate(ios_base::badbit);
470 }
471 }
472#pragma GCC diagnostic pop
473
474 /**
475 * @brief Quick status checking.
476 * @return The sentry state.
477 *
478 * For ease of use, sentries may be converted to booleans. The
479 * return value is that of the sentry state (true == okay).
480 */
481#if __cplusplus201703L >= 201103L
482 explicit
483#endif
484 operator bool() const
485 { return _M_ok; }
486 };
487
488 //@{
489 /**
490 * @brief Character inserters
491 * @param __out An output stream.
492 * @param __c A character.
493 * @return out
494 *
495 * Behaves like one of the formatted arithmetic inserters described in
496 * std::basic_ostream. After constructing a sentry object with good
497 * status, this function inserts a single character and any required
498 * padding (as determined by [22.2.2.2.2]). @c __out.width(0) is then
499 * called.
500 *
501 * If @p __c is of type @c char and the character type of the stream is not
502 * @c char, the character is widened before insertion.
503 */
504 template<typename _CharT, typename _Traits>
505 inline basic_ostream<_CharT, _Traits>&
506 operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
507 { return __ostream_insert(__out, &__c, 1); }
508
509 template<typename _CharT, typename _Traits>
510 inline basic_ostream<_CharT, _Traits>&
511 operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)
512 { return (__out << __out.widen(__c)); }
513
514 // Specialization
515 template<typename _Traits>
516 inline basic_ostream<char, _Traits>&
517 operator<<(basic_ostream<char, _Traits>& __out, char __c)
518 { return __ostream_insert(__out, &__c, 1); }
519
520 // Signed and unsigned
521 template<typename _Traits>
522 inline basic_ostream<char, _Traits>&
523 operator<<(basic_ostream<char, _Traits>& __out, signed char __c)
524 { return (__out << static_cast<char>(__c)); }
525
526 template<typename _Traits>
527 inline basic_ostream<char, _Traits>&
528 operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)
529 { return (__out << static_cast<char>(__c)); }
530
531#if __cplusplus201703L > 201703L
532 // The following deleted overloads prevent formatting character values as
533 // numeric values.
534
535#ifdef _GLIBCXX_USE_WCHAR_T1
536 template<typename _Traits>
537 basic_ostream<char, _Traits>&
538 operator<<(basic_ostream<char, _Traits>&, wchar_t) = delete;
539#endif // _GLIBCXX_USE_WCHAR_T
540
541#ifdef _GLIBCXX_USE_CHAR8_T
542 template<typename _Traits>
543 basic_ostream<char, _Traits>&
544 operator<<(basic_ostream<char, _Traits>&, char8_t) = delete;
545#endif
546
547 template<typename _Traits>
548 basic_ostream<char, _Traits>&
549 operator<<(basic_ostream<char, _Traits>&, char16_t) = delete;
550
551 template<typename _Traits>
552 basic_ostream<char, _Traits>&
553 operator<<(basic_ostream<char, _Traits>&, char32_t) = delete;
554
555#ifdef _GLIBCXX_USE_WCHAR_T1
556#ifdef _GLIBCXX_USE_CHAR8_T
557 template<typename _Traits>
558 basic_ostream<wchar_t, _Traits>&
559 operator<<(basic_ostream<wchar_t, _Traits>&, char8_t) = delete;
560#endif // _GLIBCXX_USE_CHAR8_T
561
562 template<typename _Traits>
563 basic_ostream<wchar_t, _Traits>&
564 operator<<(basic_ostream<wchar_t, _Traits>&, char16_t) = delete;
565
566 template<typename _Traits>
567 basic_ostream<wchar_t, _Traits>&
568 operator<<(basic_ostream<wchar_t, _Traits>&, char32_t) = delete;
569#endif // _GLIBCXX_USE_WCHAR_T
570#endif // C++20
571 //@}
572
573 //@{
574 /**
575 * @brief String inserters
576 * @param __out An output stream.
577 * @param __s A character string.
578 * @return out
579 * @pre @p __s must be a non-NULL pointer
580 *
581 * Behaves like one of the formatted arithmetic inserters described in
582 * std::basic_ostream. After constructing a sentry object with good
583 * status, this function inserts @c traits::length(__s) characters starting
584 * at @p __s, widened if necessary, followed by any required padding (as
585 * determined by [22.2.2.2.2]). @c __out.width(0) is then called.
586 */
587 template<typename _CharT, typename _Traits>
588 inline basic_ostream<_CharT, _Traits>&
589 operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)
590 {
591 if (!__s)
592 __out.setstate(ios_base::badbit);
593 else
594 __ostream_insert(__out, __s,
595 static_cast<streamsize>(_Traits::length(__s)));
596 return __out;
597 }
598
599 template<typename _CharT, typename _Traits>
600 basic_ostream<_CharT, _Traits> &
601 operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s);
602
603 // Partial specializations
604 template<typename _Traits>
605 inline basic_ostream<char, _Traits>&
606 operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
607 {
608 if (!__s
6.1
'__s' is non-null
6.1
'__s' is non-null
6.1
'__s' is non-null
)
7
Taking false branch
609 __out.setstate(ios_base::badbit);
610 else
611 __ostream_insert(__out, __s,
612 static_cast<streamsize>(_Traits::length(__s)));
8
Calling 'char_traits::length'
613 return __out;
614 }
615
616 // Signed and unsigned
617 template<typename _Traits>
618 inline basic_ostream<char, _Traits>&
619 operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)
620 { return (__out << reinterpret_cast<const char*>(__s)); }
621
622 template<typename _Traits>
623 inline basic_ostream<char, _Traits> &
624 operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)
625 { return (__out << reinterpret_cast<const char*>(__s)); }
626
627#if __cplusplus201703L > 201703L
628 // The following deleted overloads prevent formatting strings as
629 // pointer values.
630
631#ifdef _GLIBCXX_USE_WCHAR_T1
632 template<typename _Traits>
633 basic_ostream<char, _Traits>&
634 operator<<(basic_ostream<char, _Traits>&, const wchar_t*) = delete;
635#endif // _GLIBCXX_USE_WCHAR_T
636
637#ifdef _GLIBCXX_USE_CHAR8_T
638 template<typename _Traits>
639 basic_ostream<char, _Traits>&
640 operator<<(basic_ostream<char, _Traits>&, const char8_t*) = delete;
641#endif // _GLIBCXX_USE_CHAR8_T
642
643 template<typename _Traits>
644 basic_ostream<char, _Traits>&
645 operator<<(basic_ostream<char, _Traits>&, const char16_t*) = delete;
646
647 template<typename _Traits>
648 basic_ostream<char, _Traits>&
649 operator<<(basic_ostream<char, _Traits>&, const char32_t*) = delete;
650
651#ifdef _GLIBCXX_USE_WCHAR_T1
652#ifdef _GLIBCXX_USE_CHAR8_T
653 template<typename _Traits>
654 basic_ostream<wchar_t, _Traits>&
655 operator<<(basic_ostream<wchar_t, _Traits>&, const char8_t*) = delete;
656#endif
657
658 template<typename _Traits>
659 basic_ostream<wchar_t, _Traits>&
660 operator<<(basic_ostream<wchar_t, _Traits>&, const char16_t*) = delete;
661
662 template<typename _Traits>
663 basic_ostream<wchar_t, _Traits>&
664 operator<<(basic_ostream<wchar_t, _Traits>&, const char32_t*) = delete;
665#endif // _GLIBCXX_USE_WCHAR_T
666#endif // C++20
667 //@}
668
669 // Standard basic_ostream manipulators
670
671 /**
672 * @brief Write a newline and flush the stream.
673 *
674 * This manipulator is often mistakenly used when a simple newline is
675 * desired, leading to poor buffering performance. See
676 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering
677 * for more on this subject.
678 */
679 template<typename _CharT, typename _Traits>
680 inline basic_ostream<_CharT, _Traits>&
681 endl(basic_ostream<_CharT, _Traits>& __os)
682 { return flush(__os.put(__os.widen('\n'))); }
683
684 /**
685 * @brief Write a null character into the output sequence.
686 *
687 * <em>Null character</em> is @c CharT() by definition. For CharT
688 * of @c char, this correctly writes the ASCII @c NUL character
689 * string terminator.
690 */
691 template<typename _CharT, typename _Traits>
692 inline basic_ostream<_CharT, _Traits>&
693 ends(basic_ostream<_CharT, _Traits>& __os)
694 { return __os.put(_CharT()); }
695
696 /**
697 * @brief Flushes the output stream.
698 *
699 * This manipulator simply calls the stream's @c flush() member function.
700 */
701 template<typename _CharT, typename _Traits>
702 inline basic_ostream<_CharT, _Traits>&
703 flush(basic_ostream<_CharT, _Traits>& __os)
704 { return __os.flush(); }
705
706#if __cplusplus201703L >= 201103L
707 template<typename _Ch, typename _Up>
708 basic_ostream<_Ch, _Up>&
709 __is_convertible_to_basic_ostream_test(basic_ostream<_Ch, _Up>*);
710
711 template<typename _Tp, typename = void>
712 struct __is_convertible_to_basic_ostream_impl
713 {
714 using __ostream_type = void;
715 };
716
717 template<typename _Tp>
718 using __do_is_convertible_to_basic_ostream_impl =
719 decltype(__is_convertible_to_basic_ostream_test
720 (declval<typename remove_reference<_Tp>::type*>()));
721
722 template<typename _Tp>
723 struct __is_convertible_to_basic_ostream_impl
724 <_Tp,
725 __void_t<__do_is_convertible_to_basic_ostream_impl<_Tp>>>
726 {
727 using __ostream_type =
728 __do_is_convertible_to_basic_ostream_impl<_Tp>;
729 };
730
731 template<typename _Tp>
732 struct __is_convertible_to_basic_ostream
733 : __is_convertible_to_basic_ostream_impl<_Tp>
734 {
735 public:
736 using type = __not_<is_void<
737 typename __is_convertible_to_basic_ostream_impl<_Tp>::__ostream_type>>;
738 constexpr static bool value = type::value;
739 };
740
741 template<typename _Ostream, typename _Tp, typename = void>
742 struct __is_insertable : false_type {};
743
744 template<typename _Ostream, typename _Tp>
745 struct __is_insertable<_Ostream, _Tp,
746 __void_t<decltype(declval<_Ostream&>()
747 << declval<const _Tp&>())>>
748 : true_type {};
749
750 template<typename _Ostream>
751 using __rvalue_ostream_type =
752 typename __is_convertible_to_basic_ostream<
753 _Ostream>::__ostream_type;
754
755 /**
756 * @brief Generic inserter for rvalue stream
757 * @param __os An input stream.
758 * @param __x A reference to the object being inserted.
759 * @return os
760 *
761 * This is just a forwarding function to allow insertion to
762 * rvalue streams since they won't bind to the inserter functions
763 * that take an lvalue reference.
764 */
765 template<typename _Ostream, typename _Tp>
766 inline
767 typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,
768 __is_convertible_to_basic_ostream<_Ostream>,
769 __is_insertable<
770 __rvalue_ostream_type<_Ostream>,
771 const _Tp&>>::value,
772 __rvalue_ostream_type<_Ostream>>::type
773 operator<<(_Ostream&& __os, const _Tp& __x)
774 {
775 __rvalue_ostream_type<_Ostream> __ret_os = __os;
776 __ret_os << __x;
777 return __ret_os;
778 }
779#endif // C++11
780
781_GLIBCXX_END_NAMESPACE_VERSION
782} // namespace std
783
784#include <bits/ostream.tcc>
785
786#endif /* _GLIBCXX_OSTREAM */

/usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/char_traits.h

1// Character Traits for use by standard string and iostream -*- C++ -*-
2
3// Copyright (C) 1997-2020 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/char_traits.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{string}
28 */
29
30//
31// ISO C++ 14882: 21 Strings library
32//
33
34#ifndef _CHAR_TRAITS_H1
35#define _CHAR_TRAITS_H1 1
36
37#pragma GCC system_header
38
39#include <bits/stl_algobase.h> // std::copy, std::fill_n
40#include <bits/postypes.h> // For streampos
41#include <cwchar> // For WEOF, wmemmove, wmemset, etc.
42#if __cplusplus201703L > 201703L
43# include <compare>
44#endif
45
46#ifndef _GLIBCXX_ALWAYS_INLINEinline __attribute__((__always_inline__))
47# define _GLIBCXX_ALWAYS_INLINEinline __attribute__((__always_inline__)) inline __attribute__((__always_inline__))
48#endif
49
50namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
51{
52_GLIBCXX_BEGIN_NAMESPACE_VERSION
53
54 /**
55 * @brief Mapping from character type to associated types.
56 *
57 * @note This is an implementation class for the generic version
58 * of char_traits. It defines int_type, off_type, pos_type, and
59 * state_type. By default these are unsigned long, streamoff,
60 * streampos, and mbstate_t. Users who need a different set of
61 * types, but who don't need to change the definitions of any function
62 * defined in char_traits, can specialize __gnu_cxx::_Char_types
63 * while leaving __gnu_cxx::char_traits alone. */
64 template<typename _CharT>
65 struct _Char_types
66 {
67 typedef unsigned long int_type;
68 typedef std::streampos pos_type;
69 typedef std::streamoff off_type;
70 typedef std::mbstate_t state_type;
71 };
72
73
74 /**
75 * @brief Base class used to implement std::char_traits.
76 *
77 * @note For any given actual character type, this definition is
78 * probably wrong. (Most of the member functions are likely to be
79 * right, but the int_type and state_type typedefs, and the eof()
80 * member function, are likely to be wrong.) The reason this class
81 * exists is so users can specialize it. Classes in namespace std
82 * may not be specialized for fundamental types, but classes in
83 * namespace __gnu_cxx may be.
84 *
85 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
86 * for advice on how to make use of this class for @a unusual character
87 * types. Also, check out include/ext/pod_char_traits.h.
88 */
89 template<typename _CharT>
90 struct char_traits
91 {
92 typedef _CharT char_type;
93 typedef typename _Char_types<_CharT>::int_type int_type;
94 typedef typename _Char_types<_CharT>::pos_type pos_type;
95 typedef typename _Char_types<_CharT>::off_type off_type;
96 typedef typename _Char_types<_CharT>::state_type state_type;
97#if __cpp_lib_three_way_comparison
98 using comparison_category = std::strong_ordering;
99#endif
100
101 static _GLIBCXX14_CONSTEXPRconstexpr void
102 assign(char_type& __c1, const char_type& __c2)
103 { __c1 = __c2; }
104
105 static _GLIBCXX_CONSTEXPRconstexpr bool
106 eq(const char_type& __c1, const char_type& __c2)
107 { return __c1 == __c2; }
15
The left operand of '==' is a garbage value
108
109 static _GLIBCXX_CONSTEXPRconstexpr bool
110 lt(const char_type& __c1, const char_type& __c2)
111 { return __c1 < __c2; }
112
113 static _GLIBCXX14_CONSTEXPRconstexpr int
114 compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
115
116 static _GLIBCXX14_CONSTEXPRconstexpr std::size_t
117 length(const char_type* __s);
118
119 static _GLIBCXX14_CONSTEXPRconstexpr const char_type*
120 find(const char_type* __s, std::size_t __n, const char_type& __a);
121
122 static _GLIBCXX20_CONSTEXPR char_type*
123 move(char_type* __s1, const char_type* __s2, std::size_t __n);
124
125 static _GLIBCXX20_CONSTEXPR char_type*
126 copy(char_type* __s1, const char_type* __s2, std::size_t __n);
127
128 static _GLIBCXX20_CONSTEXPR char_type*
129 assign(char_type* __s, std::size_t __n, char_type __a);
130
131 static _GLIBCXX_CONSTEXPRconstexpr char_type
132 to_char_type(const int_type& __c)
133 { return static_cast<char_type>(__c); }
134
135 static _GLIBCXX_CONSTEXPRconstexpr int_type
136 to_int_type(const char_type& __c)
137 { return static_cast<int_type>(__c); }
138
139 static _GLIBCXX_CONSTEXPRconstexpr bool
140 eq_int_type(const int_type& __c1, const int_type& __c2)
141 { return __c1 == __c2; }
142
143 static _GLIBCXX_CONSTEXPRconstexpr int_type
144 eof()
145 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF-1); }
146
147 static _GLIBCXX_CONSTEXPRconstexpr int_type
148 not_eof(const int_type& __c)
149 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
150 };
151
152 template<typename _CharT>
153 _GLIBCXX14_CONSTEXPRconstexpr int
154 char_traits<_CharT>::
155 compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
156 {
157 for (std::size_t __i = 0; __i < __n; ++__i)
158 if (lt(__s1[__i], __s2[__i]))
159 return -1;
160 else if (lt(__s2[__i], __s1[__i]))
161 return 1;
162 return 0;
163 }
164
165 template<typename _CharT>
166 _GLIBCXX14_CONSTEXPRconstexpr std::size_t
167 char_traits<_CharT>::
168 length(const char_type* __p)
169 {
170 std::size_t __i = 0;
12
'__i' initialized to 0
171 while (!eq(__p[__i], char_type()))
13
Passing value via 1st parameter '__c1'
14
Calling 'char_traits::eq'
172 ++__i;
173 return __i;
174 }
175
176 template<typename _CharT>
177 _GLIBCXX14_CONSTEXPRconstexpr const typename char_traits<_CharT>::char_type*
178 char_traits<_CharT>::
179 find(const char_type* __s, std::size_t __n, const char_type& __a)
180 {
181 for (std::size_t __i = 0; __i < __n; ++__i)
182 if (eq(__s[__i], __a))
183 return __s + __i;
184 return 0;
185 }
186
187 template<typename _CharT>
188 _GLIBCXX20_CONSTEXPR
189 typename char_traits<_CharT>::char_type*
190 char_traits<_CharT>::
191 move(char_type* __s1, const char_type* __s2, std::size_t __n)
192 {
193 if (__n == 0)
194 return __s1;
195#ifdef __cpp_lib_is_constant_evaluated
196 if (std::is_constant_evaluated())
197 {
198 if (__s1 > __s2 && __s1 < __s2 + __n)
199 std::copy_backward(__s2, __s2 + __n, __s1);
200 else
201 std::copy(__s2, __s2 + __n, __s1);
202 return __s1;
203 }
204#endif
205 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
206 __n * sizeof(char_type)));
207 }
208
209 template<typename _CharT>
210 _GLIBCXX20_CONSTEXPR
211 typename char_traits<_CharT>::char_type*
212 char_traits<_CharT>::
213 copy(char_type* __s1, const char_type* __s2, std::size_t __n)
214 {
215 // NB: Inline std::copy so no recursive dependencies.
216 std::copy(__s2, __s2 + __n, __s1);
217 return __s1;
218 }
219
220 template<typename _CharT>
221 _GLIBCXX20_CONSTEXPR
222 typename char_traits<_CharT>::char_type*
223 char_traits<_CharT>::
224 assign(char_type* __s, std::size_t __n, char_type __a)
225 {
226 // NB: Inline std::fill_n so no recursive dependencies.
227 std::fill_n(__s, __n, __a);
228 return __s;
229 }
230
231_GLIBCXX_END_NAMESPACE_VERSION
232} // namespace
233
234namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
235{
236_GLIBCXX_BEGIN_NAMESPACE_VERSION
237
238#if __cplusplus201703L >= 201703L
239#define __cpp_lib_constexpr_char_traits201611 201611
240
241 /**
242 * @brief Determine whether the characters of a NULL-terminated
243 * string are known at compile time.
244 * @param __s The string.
245 *
246 * Assumes that _CharT is a built-in character type.
247 */
248 template<typename _CharT>
249 static _GLIBCXX_ALWAYS_INLINEinline __attribute__((__always_inline__)) constexpr bool
250 __constant_string_p(const _CharT* __s)
251 {
252#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED1
253 (void) __s;
254 // In constexpr contexts all strings should be constant.
255 return __builtin_is_constant_evaluated();
256#else
257 while (__builtin_constant_p(*__s) && *__s)
258 __s++;
259 return __builtin_constant_p(*__s);
260#endif
261 }
262
263 /**
264 * @brief Determine whether the characters of a character array are
265 * known at compile time.
266 * @param __a The character array.
267 * @param __n Number of characters.
268 *
269 * Assumes that _CharT is a built-in character type.
270 */
271 template<typename _CharT>
272 static _GLIBCXX_ALWAYS_INLINEinline __attribute__((__always_inline__)) constexpr bool
273 __constant_char_array_p(const _CharT* __a, size_t __n)
274 {
275#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED1
276 (void) __a;
277 (void) __n;
278 // In constexpr contexts all character arrays should be constant.
279 return __builtin_is_constant_evaluated();
280#else
281 size_t __i = 0;
282 while (__i < __n && __builtin_constant_p(__a[__i]))
283 __i++;
284 return __i == __n;
285#endif
286 }
287#endif
288
289 // 21.1
290 /**
291 * @brief Basis for explicit traits specializations.
292 *
293 * @note For any given actual character type, this definition is
294 * probably wrong. Since this is just a thin wrapper around
295 * __gnu_cxx::char_traits, it is possible to achieve a more
296 * appropriate definition by specializing __gnu_cxx::char_traits.
297 *
298 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
299 * for advice on how to make use of this class for @a unusual character
300 * types. Also, check out include/ext/pod_char_traits.h.
301 */
302 template<class _CharT>
303 struct char_traits : public __gnu_cxx::char_traits<_CharT>
304 { };
305
306
307 /// 21.1.3.1 char_traits specializations
308 template<>
309 struct char_traits<char>
310 {
311 typedef char char_type;
312 typedef int int_type;
313 typedef streampos pos_type;
314 typedef streamoff off_type;
315 typedef mbstate_t state_type;
316#if __cpp_lib_three_way_comparison
317 using comparison_category = strong_ordering;
318#endif
319
320 static _GLIBCXX17_CONSTEXPRconstexpr void
321 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
322 { __c1 = __c2; }
323
324 static _GLIBCXX_CONSTEXPRconstexpr bool
325 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
326 { return __c1 == __c2; }
327
328 static _GLIBCXX_CONSTEXPRconstexpr bool
329 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
330 {
331 // LWG 467.
332 return (static_cast<unsigned char>(__c1)
333 < static_cast<unsigned char>(__c2));
334 }
335
336 static _GLIBCXX17_CONSTEXPRconstexpr int
337 compare(const char_type* __s1, const char_type* __s2, size_t __n)
338 {
339 if (__n == 0)
340 return 0;
341#if __cplusplus201703L >= 201703L
342 if (__builtin_constant_p(__n)
343 && __constant_char_array_p(__s1, __n)
344 && __constant_char_array_p(__s2, __n))
345 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
346#endif
347 return __builtin_memcmp(__s1, __s2, __n);
348 }
349
350 static _GLIBCXX17_CONSTEXPRconstexpr size_t
351 length(const char_type* __s)
352 {
353#if __cplusplus201703L >= 201703L
354 if (__constant_string_p(__s))
9
Assuming the condition is true
10
Taking true branch
355 return __gnu_cxx::char_traits<char_type>::length(__s);
11
Calling 'char_traits::length'
356#endif
357 return __builtin_strlen(__s);
358 }
359
360 static _GLIBCXX17_CONSTEXPRconstexpr const char_type*
361 find(const char_type* __s, size_t __n, const char_type& __a)
362 {
363 if (__n == 0)
364 return 0;
365#if __cplusplus201703L >= 201703L
366 if (__builtin_constant_p(__n)
367 && __builtin_constant_p(__a)
368 && __constant_char_array_p(__s, __n))
369 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
370#endif
371 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
372 }
373
374 static _GLIBCXX20_CONSTEXPR char_type*
375 move(char_type* __s1, const char_type* __s2, size_t __n)
376 {
377 if (__n == 0)
378 return __s1;
379#ifdef __cpp_lib_is_constant_evaluated
380 if (std::is_constant_evaluated())
381 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
382#endif
383 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
384 }
385
386 static _GLIBCXX20_CONSTEXPR char_type*
387 copy(char_type* __s1, const char_type* __s2, size_t __n)
388 {
389 if (__n == 0)
390 return __s1;
391#ifdef __cpp_lib_is_constant_evaluated
392 if (std::is_constant_evaluated())
393 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
394#endif
395 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
396 }
397
398 static _GLIBCXX20_CONSTEXPR char_type*
399 assign(char_type* __s, size_t __n, char_type __a)
400 {
401 if (__n == 0)
402 return __s;
403#ifdef __cpp_lib_is_constant_evaluated
404 if (std::is_constant_evaluated())
405 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
406#endif
407 return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
408 }
409
410 static _GLIBCXX_CONSTEXPRconstexpr char_type
411 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPTnoexcept
412 { return static_cast<char_type>(__c); }
413
414 // To keep both the byte 0xff and the eof symbol 0xffffffff
415 // from ending up as 0xffffffff.
416 static _GLIBCXX_CONSTEXPRconstexpr int_type
417 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPTnoexcept
418 { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
419
420 static _GLIBCXX_CONSTEXPRconstexpr bool
421 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
422 { return __c1 == __c2; }
423
424 static _GLIBCXX_CONSTEXPRconstexpr int_type
425 eof() _GLIBCXX_NOEXCEPTnoexcept
426 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF-1); }
427
428 static _GLIBCXX_CONSTEXPRconstexpr int_type
429 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPTnoexcept
430 { return (__c == eof()) ? 0 : __c; }
431 };
432
433
434#ifdef _GLIBCXX_USE_WCHAR_T1
435 /// 21.1.3.2 char_traits specializations
436 template<>
437 struct char_traits<wchar_t>
438 {
439 typedef wchar_t char_type;
440 typedef wint_t int_type;
441 typedef streamoff off_type;
442 typedef wstreampos pos_type;
443 typedef mbstate_t state_type;
444#if __cpp_lib_three_way_comparison
445 using comparison_category = strong_ordering;
446#endif
447
448 static _GLIBCXX17_CONSTEXPRconstexpr void
449 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
450 { __c1 = __c2; }
451
452 static _GLIBCXX_CONSTEXPRconstexpr bool
453 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
454 { return __c1 == __c2; }
455
456 static _GLIBCXX_CONSTEXPRconstexpr bool
457 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
458 { return __c1 < __c2; }
459
460 static _GLIBCXX17_CONSTEXPRconstexpr int
461 compare(const char_type* __s1, const char_type* __s2, size_t __n)
462 {
463 if (__n == 0)
464 return 0;
465#if __cplusplus201703L >= 201703L
466 if (__builtin_constant_p(__n)
467 && __constant_char_array_p(__s1, __n)
468 && __constant_char_array_p(__s2, __n))
469 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
470#endif
471 return wmemcmp(__s1, __s2, __n);
472 }
473
474 static _GLIBCXX17_CONSTEXPRconstexpr size_t
475 length(const char_type* __s)
476 {
477#if __cplusplus201703L >= 201703L
478 if (__constant_string_p(__s))
479 return __gnu_cxx::char_traits<char_type>::length(__s);
480#endif
481 return wcslen(__s);
482 }
483
484 static _GLIBCXX17_CONSTEXPRconstexpr const char_type*
485 find(const char_type* __s, size_t __n, const char_type& __a)
486 {
487 if (__n == 0)
488 return 0;
489#if __cplusplus201703L >= 201703L
490 if (__builtin_constant_p(__n)
491 && __builtin_constant_p(__a)
492 && __constant_char_array_p(__s, __n))
493 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
494#endif
495 return wmemchr(__s, __a, __n);
496 }
497
498 static _GLIBCXX20_CONSTEXPR char_type*
499 move(char_type* __s1, const char_type* __s2, size_t __n)
500 {
501 if (__n == 0)
502 return __s1;
503#ifdef __cpp_lib_is_constant_evaluated
504 if (std::is_constant_evaluated())
505 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
506#endif
507 return wmemmove(__s1, __s2, __n);
508 }
509
510 static _GLIBCXX20_CONSTEXPR char_type*
511 copy(char_type* __s1, const char_type* __s2, size_t __n)
512 {
513 if (__n == 0)
514 return __s1;
515#ifdef __cpp_lib_is_constant_evaluated
516 if (std::is_constant_evaluated())
517 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
518#endif
519 return wmemcpy(__s1, __s2, __n);
520 }
521
522 static _GLIBCXX20_CONSTEXPR char_type*
523 assign(char_type* __s, size_t __n, char_type __a)
524 {
525 if (__n == 0)
526 return __s;
527#ifdef __cpp_lib_is_constant_evaluated
528 if (std::is_constant_evaluated())
529 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
530#endif
531 return wmemset(__s, __a, __n);
532 }
533
534 static _GLIBCXX_CONSTEXPRconstexpr char_type
535 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPTnoexcept
536 { return char_type(__c); }
537
538 static _GLIBCXX_CONSTEXPRconstexpr int_type
539 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPTnoexcept
540 { return int_type(__c); }
541
542 static _GLIBCXX_CONSTEXPRconstexpr bool
543 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
544 { return __c1 == __c2; }
545
546 static _GLIBCXX_CONSTEXPRconstexpr int_type
547 eof() _GLIBCXX_NOEXCEPTnoexcept
548 { return static_cast<int_type>(WEOF(0xffffffffu)); }
549
550 static _GLIBCXX_CONSTEXPRconstexpr int_type
551 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPTnoexcept
552 { return eq_int_type(__c, eof()) ? 0 : __c; }
553 };
554#endif //_GLIBCXX_USE_WCHAR_T
555
556#ifdef _GLIBCXX_USE_CHAR8_T
557 template<>
558 struct char_traits<char8_t>
559 {
560 typedef char8_t char_type;
561 typedef unsigned int int_type;
562 typedef u8streampos pos_type;
563 typedef streamoff off_type;
564 typedef mbstate_t state_type;
565#if __cpp_lib_three_way_comparison
566 using comparison_category = strong_ordering;
567#endif
568
569 static _GLIBCXX17_CONSTEXPRconstexpr void
570 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
571 { __c1 = __c2; }
572
573 static _GLIBCXX_CONSTEXPRconstexpr bool
574 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
575 { return __c1 == __c2; }
576
577 static _GLIBCXX_CONSTEXPRconstexpr bool
578 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
579 { return __c1 < __c2; }
580
581 static _GLIBCXX17_CONSTEXPRconstexpr int
582 compare(const char_type* __s1, const char_type* __s2, size_t __n)
583 {
584 if (__n == 0)
585 return 0;
586#if __cplusplus201703L > 201402
587 if (__builtin_constant_p(__n)
588 && __constant_char_array_p(__s1, __n)
589 && __constant_char_array_p(__s2, __n))
590 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
591#endif
592 return __builtin_memcmp(__s1, __s2, __n);
593 }
594
595 static _GLIBCXX17_CONSTEXPRconstexpr size_t
596 length(const char_type* __s)
597 {
598#if __cplusplus201703L > 201402
599 if (__constant_string_p(__s))
600 return __gnu_cxx::char_traits<char_type>::length(__s);
601#endif
602 size_t __i = 0;
603 while (!eq(__s[__i], char_type()))
604 ++__i;
605 return __i;
606 }
607
608 static _GLIBCXX17_CONSTEXPRconstexpr const char_type*
609 find(const char_type* __s, size_t __n, const char_type& __a)
610 {
611 if (__n == 0)
612 return 0;
613#if __cplusplus201703L > 201402
614 if (__builtin_constant_p(__n)
615 && __builtin_constant_p(__a)
616 && __constant_char_array_p(__s, __n))
617 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
618#endif
619 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
620 }
621
622 static _GLIBCXX20_CONSTEXPR char_type*
623 move(char_type* __s1, const char_type* __s2, size_t __n)
624 {
625 if (__n == 0)
626 return __s1;
627#ifdef __cpp_lib_is_constant_evaluated
628 if (std::is_constant_evaluated())
629 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
630#endif
631 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
632 }
633
634 static _GLIBCXX20_CONSTEXPR char_type*
635 copy(char_type* __s1, const char_type* __s2, size_t __n)
636 {
637 if (__n == 0)
638 return __s1;
639#ifdef __cpp_lib_is_constant_evaluated
640 if (std::is_constant_evaluated())
641 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
642#endif
643 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
644 }
645
646 static _GLIBCXX20_CONSTEXPR char_type*
647 assign(char_type* __s, size_t __n, char_type __a)
648 {
649 if (__n == 0)
650 return __s;
651#ifdef __cpp_lib_is_constant_evaluated
652 if (std::is_constant_evaluated())
653 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
654#endif
655 return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
656 }
657
658 static _GLIBCXX_CONSTEXPRconstexpr char_type
659 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPTnoexcept
660 { return char_type(__c); }
661
662 static _GLIBCXX_CONSTEXPRconstexpr int_type
663 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPTnoexcept
664 { return int_type(__c); }
665
666 static _GLIBCXX_CONSTEXPRconstexpr bool
667 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPTnoexcept
668 { return __c1 == __c2; }
669
670 static _GLIBCXX_CONSTEXPRconstexpr int_type
671 eof() _GLIBCXX_NOEXCEPTnoexcept
672 { return static_cast<int_type>(-1); }
673
674 static _GLIBCXX_CONSTEXPRconstexpr int_type
675 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPTnoexcept
676 { return eq_int_type(__c, eof()) ? 0 : __c; }
677 };
678#endif //_GLIBCXX_USE_CHAR8_T
679
680_GLIBCXX_END_NAMESPACE_VERSION
681} // namespace
682
683#if __cplusplus201703L >= 201103L
684
685#include <cstdint>
686
687namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
688{
689_GLIBCXX_BEGIN_NAMESPACE_VERSION
690
691 template<>
692 struct char_traits<char16_t>
693 {
694 typedef char16_t char_type;
695#ifdef _GLIBCXX_USE_C99_STDINT_TR11
696 typedef uint_least16_t int_type;
697#elif defined __UINT_LEAST16_TYPE__unsigned short
698 typedef __UINT_LEAST16_TYPE__unsigned short int_type;
699#else
700 typedef make_unsigned<char16_t>::type int_type;
701#endif
702 typedef streamoff off_type;
703 typedef u16streampos pos_type;
704 typedef mbstate_t state_type;
705#if __cpp_lib_three_way_comparison
706 using comparison_category = strong_ordering;
707#endif
708
709 static _GLIBCXX17_CONSTEXPRconstexpr void
710 assign(char_type& __c1, const char_type& __c2) noexcept
711 { __c1 = __c2; }
712
713 static constexpr bool
714 eq(const char_type& __c1, const char_type& __c2) noexcept
715 { return __c1 == __c2; }
716
717 static constexpr bool
718 lt(const char_type& __c1, const char_type& __c2) noexcept
719 { return __c1 < __c2; }
720
721 static _GLIBCXX17_CONSTEXPRconstexpr int
722 compare(const char_type* __s1, const char_type* __s2, size_t __n)
723 {
724 for (size_t __i = 0; __i < __n; ++__i)
725 if (lt(__s1[__i], __s2[__i]))
726 return -1;
727 else if (lt(__s2[__i], __s1[__i]))
728 return 1;
729 return 0;
730 }
731
732 static _GLIBCXX17_CONSTEXPRconstexpr size_t
733 length(const char_type* __s)
734 {
735 size_t __i = 0;
736 while (!eq(__s[__i], char_type()))
737 ++__i;
738 return __i;
739 }
740
741 static _GLIBCXX17_CONSTEXPRconstexpr const char_type*
742 find(const char_type* __s, size_t __n, const char_type& __a)
743 {
744 for (size_t __i = 0; __i < __n; ++__i)
745 if (eq(__s[__i], __a))
746 return __s + __i;
747 return 0;
748 }
749
750 static _GLIBCXX20_CONSTEXPR char_type*
751 move(char_type* __s1, const char_type* __s2, size_t __n)
752 {
753 if (__n == 0)
754 return __s1;
755#ifdef __cpp_lib_is_constant_evaluated
756 if (std::is_constant_evaluated())
757 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
758#endif
759 return (static_cast<char_type*>
760 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
761 }
762
763 static _GLIBCXX20_CONSTEXPR char_type*
764 copy(char_type* __s1, const char_type* __s2, size_t __n)
765 {
766 if (__n == 0)
767 return __s1;
768#ifdef __cpp_lib_is_constant_evaluated
769 if (std::is_constant_evaluated())
770 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
771#endif
772 return (static_cast<char_type*>
773 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
774 }
775
776 static _GLIBCXX20_CONSTEXPR char_type*
777 assign(char_type* __s, size_t __n, char_type __a)
778 {
779 for (size_t __i = 0; __i < __n; ++__i)
780 assign(__s[__i], __a);
781 return __s;
782 }
783
784 static constexpr char_type
785 to_char_type(const int_type& __c) noexcept
786 { return char_type(__c); }
787
788 static constexpr int_type
789 to_int_type(const char_type& __c) noexcept
790 { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
791
792 static constexpr bool
793 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
794 { return __c1 == __c2; }
795
796 static constexpr int_type
797 eof() noexcept
798 { return static_cast<int_type>(-1); }
799
800 static constexpr int_type
801 not_eof(const int_type& __c) noexcept
802 { return eq_int_type(__c, eof()) ? 0 : __c; }
803 };
804
805 template<>
806 struct char_traits<char32_t>
807 {
808 typedef char32_t char_type;
809#ifdef _GLIBCXX_USE_C99_STDINT_TR11
810 typedef uint_least32_t int_type;
811#elif defined __UINT_LEAST32_TYPE__unsigned int
812 typedef __UINT_LEAST32_TYPE__unsigned int int_type;
813#else
814 typedef make_unsigned<char32_t>::type int_type;
815#endif
816 typedef streamoff off_type;
817 typedef u32streampos pos_type;
818 typedef mbstate_t state_type;
819#if __cpp_lib_three_way_comparison
820 using comparison_category = strong_ordering;
821#endif
822
823 static _GLIBCXX17_CONSTEXPRconstexpr void
824 assign(char_type& __c1, const char_type& __c2) noexcept
825 { __c1 = __c2; }
826
827 static constexpr bool
828 eq(const char_type& __c1, const char_type& __c2) noexcept
829 { return __c1 == __c2; }
830
831 static constexpr bool
832 lt(const char_type& __c1, const char_type& __c2) noexcept
833 { return __c1 < __c2; }
834
835 static _GLIBCXX17_CONSTEXPRconstexpr int
836 compare(const char_type* __s1, const char_type* __s2, size_t __n)
837 {
838 for (size_t __i = 0; __i < __n; ++__i)
839 if (lt(__s1[__i], __s2[__i]))
840 return -1;
841 else if (lt(__s2[__i], __s1[__i]))
842 return 1;
843 return 0;
844 }
845
846 static _GLIBCXX17_CONSTEXPRconstexpr size_t
847 length(const char_type* __s)
848 {
849 size_t __i = 0;
850 while (!eq(__s[__i], char_type()))
851 ++__i;
852 return __i;
853 }
854
855 static _GLIBCXX17_CONSTEXPRconstexpr const char_type*
856 find(const char_type* __s, size_t __n, const char_type& __a)
857 {
858 for (size_t __i = 0; __i < __n; ++__i)
859 if (eq(__s[__i], __a))
860 return __s + __i;
861 return 0;
862 }
863
864 static _GLIBCXX20_CONSTEXPR char_type*
865 move(char_type* __s1, const char_type* __s2, size_t __n)
866 {
867 if (__n == 0)
868 return __s1;
869#ifdef __cpp_lib_is_constant_evaluated
870 if (std::is_constant_evaluated())
871 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
872#endif
873 return (static_cast<char_type*>
874 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
875 }
876
877 static _GLIBCXX20_CONSTEXPR char_type*
878 copy(char_type* __s1, const char_type* __s2, size_t __n)
879 {
880 if (__n == 0)
881 return __s1;
882#ifdef __cpp_lib_is_constant_evaluated
883 if (std::is_constant_evaluated())
884 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
885#endif
886 return (static_cast<char_type*>
887 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
888 }
889
890 static _GLIBCXX20_CONSTEXPR char_type*
891 assign(char_type* __s, size_t __n, char_type __a)
892 {
893 for (size_t __i = 0; __i < __n; ++__i)
894 assign(__s[__i], __a);
895 return __s;
896 }
897
898 static constexpr char_type
899 to_char_type(const int_type& __c) noexcept
900 { return char_type(__c); }
901
902 static constexpr int_type
903 to_int_type(const char_type& __c) noexcept
904 { return int_type(__c); }
905
906 static constexpr bool
907 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
908 { return __c1 == __c2; }
909
910 static constexpr int_type
911 eof() noexcept
912 { return static_cast<int_type>(-1); }
913
914 static constexpr int_type
915 not_eof(const int_type& __c) noexcept
916 { return eq_int_type(__c, eof()) ? 0 : __c; }
917 };
918
919#if __cpp_lib_three_way_comparison
920 namespace __detail
921 {
922 template<typename _ChTraits>
923 constexpr auto
924 __char_traits_cmp_cat(int __cmp) noexcept
925 {
926 if constexpr (requires { typename _ChTraits::comparison_category; })
927 {
928 using _Cat = typename _ChTraits::comparison_category;
929 static_assert( !is_void_v<common_comparison_category_t<_Cat>> );
930 return static_cast<_Cat>(__cmp <=> 0);
931 }
932 else
933 return static_cast<weak_ordering>(__cmp <=> 0);
934 }
935 } // namespace __detail
936#endif // C++20
937
938_GLIBCXX_END_NAMESPACE_VERSION
939} // namespace
940
941#endif // C++11
942
943#endif // _CHAR_TRAITS_H