1    	// Character Traits for use by standard string and iostream -*- C++ -*-
2    	
3    	// Copyright (C) 1997-2013 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_H
35   	#define _CHAR_TRAITS_H 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   	
43   	namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
44   	{
45   	_GLIBCXX_BEGIN_NAMESPACE_VERSION
46   	
47   	  /**
48   	   *  @brief  Mapping from character type to associated types.
49   	   *
50   	   *  @note This is an implementation class for the generic version
51   	   *  of char_traits.  It defines int_type, off_type, pos_type, and
52   	   *  state_type.  By default these are unsigned long, streamoff,
53   	   *  streampos, and mbstate_t.  Users who need a different set of
54   	   *  types, but who don't need to change the definitions of any function
55   	   *  defined in char_traits, can specialize __gnu_cxx::_Char_types
56   	   *  while leaving __gnu_cxx::char_traits alone. */
57   	  template<typename _CharT>
58   	    struct _Char_types
59   	    {
60   	      typedef unsigned long   int_type;
61   	      typedef std::streampos  pos_type;
62   	      typedef std::streamoff  off_type;
63   	      typedef std::mbstate_t  state_type;
64   	    };
65   	
66   	
67   	  /**
68   	   *  @brief  Base class used to implement std::char_traits.
69   	   *
70   	   *  @note For any given actual character type, this definition is
71   	   *  probably wrong.  (Most of the member functions are likely to be
72   	   *  right, but the int_type and state_type typedefs, and the eof()
73   	   *  member function, are likely to be wrong.)  The reason this class
74   	   *  exists is so users can specialize it.  Classes in namespace std
75   	   *  may not be specialized for fundamental types, but classes in
76   	   *  namespace __gnu_cxx may be.
77   	   *
78   	   *  See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
79   	   *  for advice on how to make use of this class for @a unusual character
80   	   *  types. Also, check out include/ext/pod_char_traits.h.  
81   	   */
82   	  template<typename _CharT>
83   	    struct char_traits
84   	    {
85   	      typedef _CharT                                    char_type;
86   	      typedef typename _Char_types<_CharT>::int_type    int_type;
87   	      typedef typename _Char_types<_CharT>::pos_type    pos_type;
88   	      typedef typename _Char_types<_CharT>::off_type    off_type;
89   	      typedef typename _Char_types<_CharT>::state_type  state_type;
90   	
91   	      static void
92   	      assign(char_type& __c1, const char_type& __c2)
93   	      { __c1 = __c2; }
94   	
95   	      static _GLIBCXX_CONSTEXPR bool
96   	      eq(const char_type& __c1, const char_type& __c2)
97   	      { return __c1 == __c2; }
98   	
99   	      static _GLIBCXX_CONSTEXPR bool
100  	      lt(const char_type& __c1, const char_type& __c2)
101  	      { return __c1 < __c2; }
102  	
103  	      static int
104  	      compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
105  	
106  	      static std::size_t
107  	      length(const char_type* __s);
108  	
109  	      static const char_type*
110  	      find(const char_type* __s, std::size_t __n, const char_type& __a);
111  	
112  	      static char_type*
113  	      move(char_type* __s1, const char_type* __s2, std::size_t __n);
114  	
115  	      static char_type*
116  	      copy(char_type* __s1, const char_type* __s2, std::size_t __n);
117  	
118  	      static char_type*
119  	      assign(char_type* __s, std::size_t __n, char_type __a);
120  	
121  	      static _GLIBCXX_CONSTEXPR char_type
122  	      to_char_type(const int_type& __c)
123  	      { return static_cast<char_type>(__c); }
124  	
125  	      static _GLIBCXX_CONSTEXPR int_type
126  	      to_int_type(const char_type& __c)
127  	      { return static_cast<int_type>(__c); }
128  	
129  	      static _GLIBCXX_CONSTEXPR bool
130  	      eq_int_type(const int_type& __c1, const int_type& __c2)
131  	      { return __c1 == __c2; }
132  	
133  	      static _GLIBCXX_CONSTEXPR int_type
134  	      eof()
135  	      { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
136  	
137  	      static _GLIBCXX_CONSTEXPR int_type
138  	      not_eof(const int_type& __c)
139  	      { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
140  	    };
141  	
142  	  template<typename _CharT>
143  	    int
144  	    char_traits<_CharT>::
145  	    compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
146  	    {
147  	      for (std::size_t __i = 0; __i < __n; ++__i)
148  		if (lt(__s1[__i], __s2[__i]))
149  		  return -1;
150  		else if (lt(__s2[__i], __s1[__i]))
151  		  return 1;
152  	      return 0;
153  	    }
154  	
155  	  template<typename _CharT>
156  	    std::size_t
157  	    char_traits<_CharT>::
158  	    length(const char_type* __p)
159  	    {
160  	      std::size_t __i = 0;
161  	      while (!eq(__p[__i], char_type()))
162  	        ++__i;
163  	      return __i;
164  	    }
165  	
166  	  template<typename _CharT>
167  	    const typename char_traits<_CharT>::char_type*
168  	    char_traits<_CharT>::
169  	    find(const char_type* __s, std::size_t __n, const char_type& __a)
170  	    {
171  	      for (std::size_t __i = 0; __i < __n; ++__i)
172  	        if (eq(__s[__i], __a))
173  	          return __s + __i;
174  	      return 0;
175  	    }
176  	
177  	  template<typename _CharT>
178  	    typename char_traits<_CharT>::char_type*
179  	    char_traits<_CharT>::
180  	    move(char_type* __s1, const char_type* __s2, std::size_t __n)
181  	    {
182  	      return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
183  							    __n * sizeof(char_type)));
184  	    }
185  	
186  	  template<typename _CharT>
187  	    typename char_traits<_CharT>::char_type*
188  	    char_traits<_CharT>::
189  	    copy(char_type* __s1, const char_type* __s2, std::size_t __n)
190  	    {
191  	      // NB: Inline std::copy so no recursive dependencies.
192  	      std::copy(__s2, __s2 + __n, __s1);
193  	      return __s1;
194  	    }
195  	
196  	  template<typename _CharT>
197  	    typename char_traits<_CharT>::char_type*
198  	    char_traits<_CharT>::
199  	    assign(char_type* __s, std::size_t __n, char_type __a)
200  	    {
201  	      // NB: Inline std::fill_n so no recursive dependencies.
202  	      std::fill_n(__s, __n, __a);
203  	      return __s;
204  	    }
205  	
206  	_GLIBCXX_END_NAMESPACE_VERSION
207  	} // namespace
208  	
209  	namespace std _GLIBCXX_VISIBILITY(default)
210  	{
211  	_GLIBCXX_BEGIN_NAMESPACE_VERSION
212  	
213  	  // 21.1
214  	  /**
215  	   *  @brief  Basis for explicit traits specializations.
216  	   *
217  	   *  @note  For any given actual character type, this definition is
218  	   *  probably wrong.  Since this is just a thin wrapper around
219  	   *  __gnu_cxx::char_traits, it is possible to achieve a more
220  	   *  appropriate definition by specializing __gnu_cxx::char_traits.
221  	   *
222  	   *  See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
223  	   *  for advice on how to make use of this class for @a unusual character
224  	   *  types. Also, check out include/ext/pod_char_traits.h.
225  	  */
226  	  template<class _CharT>
227  	    struct char_traits : public __gnu_cxx::char_traits<_CharT>
228  	    { };
229  	
230  	
231  	  /// 21.1.3.1  char_traits specializations
232  	  template<>
233  	    struct char_traits<char>
234  	    {
235  	      typedef char              char_type;
236  	      typedef int               int_type;
237  	      typedef streampos         pos_type;
238  	      typedef streamoff         off_type;
239  	      typedef mbstate_t         state_type;
240  	
241  	      static void
242  	      assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
243  	      { __c1 = __c2; }
244  	
245  	      static _GLIBCXX_CONSTEXPR bool
246  	      eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
247  	      { return __c1 == __c2; }
248  	
249  	      static _GLIBCXX_CONSTEXPR bool
250  	      lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
251  	      { return __c1 < __c2; }
252  	
253  	      static int
254  	      compare(const char_type* __s1, const char_type* __s2, size_t __n)
255  	      { return __builtin_memcmp(__s1, __s2, __n); }
256  	
257  	      static size_t
258  	      length(const char_type* __s)
259  	      { return __builtin_strlen(__s); }
260  	
261  	      static const char_type*
262  	      find(const char_type* __s, size_t __n, const char_type& __a)
263  	      { return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); }
264  	
265  	      static char_type*
266  	      move(char_type* __s1, const char_type* __s2, size_t __n)
267  	      { return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); }
268  	
269  	      static char_type*
270  	      copy(char_type* __s1, const char_type* __s2, size_t __n)
271  	      { return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); }
272  	
273  	      static char_type*
274  	      assign(char_type* __s, size_t __n, char_type __a)
275  	      { return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); }
276  	
277  	      static _GLIBCXX_CONSTEXPR char_type
278  	      to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
279  	      { return static_cast<char_type>(__c); }
280  	
281  	      // To keep both the byte 0xff and the eof symbol 0xffffffff
282  	      // from ending up as 0xffffffff.
283  	      static _GLIBCXX_CONSTEXPR int_type
284  	      to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
285  	      { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
286  	
287  	      static _GLIBCXX_CONSTEXPR bool
288  	      eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
289  	      { return __c1 == __c2; }
290  	
291  	      static _GLIBCXX_CONSTEXPR int_type
292  	      eof() _GLIBCXX_NOEXCEPT
293  	      { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
294  	
295  	      static _GLIBCXX_CONSTEXPR int_type
296  	      not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
297  	      { return (__c == eof()) ? 0 : __c; }
298  	  };
299  	
300  	
301  	#ifdef _GLIBCXX_USE_WCHAR_T
302  	  /// 21.1.3.2  char_traits specializations
303  	  template<>
304  	    struct char_traits<wchar_t>
305  	    {
306  	      typedef wchar_t           char_type;
307  	      typedef wint_t            int_type;
308  	      typedef streamoff         off_type;
309  	      typedef wstreampos        pos_type;
310  	      typedef mbstate_t         state_type;
311  	
312  	      static void
313  	      assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
314  	      { __c1 = __c2; }
315  	
316  	      static _GLIBCXX_CONSTEXPR bool
317  	      eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
318  	      { return __c1 == __c2; }
319  	
320  	      static _GLIBCXX_CONSTEXPR bool
321  	      lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
322  	      { return __c1 < __c2; }
323  	
324  	      static int
325  	      compare(const char_type* __s1, const char_type* __s2, size_t __n)
326  	      { return wmemcmp(__s1, __s2, __n); }
327  	
328  	      static size_t
329  	      length(const char_type* __s)
330  	      { return wcslen(__s); }
331  	
332  	      static const char_type*
333  	      find(const char_type* __s, size_t __n, const char_type& __a)
334  	      { return wmemchr(__s, __a, __n); }
335  	
336  	      static char_type*
337  	      move(char_type* __s1, const char_type* __s2, size_t __n)
338  	      { return wmemmove(__s1, __s2, __n); }
339  	
340  	      static char_type*
341  	      copy(char_type* __s1, const char_type* __s2, size_t __n)
342  	      { return wmemcpy(__s1, __s2, __n); }
343  	
344  	      static char_type*
345  	      assign(char_type* __s, size_t __n, char_type __a)
346  	      { return wmemset(__s, __a, __n); }
347  	
348  	      static _GLIBCXX_CONSTEXPR char_type
349  	      to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
350  	      { return char_type(__c); }
351  	
352  	      static _GLIBCXX_CONSTEXPR int_type
353  	      to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
354  	      { return int_type(__c); }
355  	
356  	      static _GLIBCXX_CONSTEXPR bool
357  	      eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
358  	      { return __c1 == __c2; }
359  	
360  	      static _GLIBCXX_CONSTEXPR int_type
361  	      eof() _GLIBCXX_NOEXCEPT
362  	      { return static_cast<int_type>(WEOF); }
363  	
364  	      static _GLIBCXX_CONSTEXPR int_type
365  	      not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
366  	      { return eq_int_type(__c, eof()) ? 0 : __c; }
367  	  };
368  	#endif //_GLIBCXX_USE_WCHAR_T
369  	
370  	_GLIBCXX_END_NAMESPACE_VERSION
371  	} // namespace
372  	
373  	#if ((__cplusplus >= 201103L) \
374  	     && defined(_GLIBCXX_USE_C99_STDINT_TR1))
375  	
376  	#include <cstdint>
377  	
378  	namespace std _GLIBCXX_VISIBILITY(default)
379  	{
380  	_GLIBCXX_BEGIN_NAMESPACE_VERSION
381  	
382  	  template<>
383  	    struct char_traits<char16_t>
384  	    {
385  	      typedef char16_t          char_type;
386  	      typedef uint_least16_t    int_type;
387  	      typedef streamoff         off_type;
388  	      typedef u16streampos      pos_type;
389  	      typedef mbstate_t         state_type;
390  	
391  	      static void
392  	      assign(char_type& __c1, const char_type& __c2) noexcept
393  	      { __c1 = __c2; }
394  	
395  	      static constexpr bool
396  	      eq(const char_type& __c1, const char_type& __c2) noexcept
397  	      { return __c1 == __c2; }
398  	
399  	      static constexpr bool
400  	      lt(const char_type& __c1, const char_type& __c2) noexcept
401  	      { return __c1 < __c2; }
402  	
403  	      static int
404  	      compare(const char_type* __s1, const char_type* __s2, size_t __n)
405  	      {
406  		for (size_t __i = 0; __i < __n; ++__i)
407  		  if (lt(__s1[__i], __s2[__i]))
408  		    return -1;
409  		  else if (lt(__s2[__i], __s1[__i]))
410  		    return 1;
411  		return 0;
412  	      }
413  	
414  	      static size_t
415  	      length(const char_type* __s)
416  	      {
417  		size_t __i = 0;
418  		while (!eq(__s[__i], char_type()))
419  		  ++__i;
420  		return __i;
421  	      }
422  	
423  	      static const char_type*
424  	      find(const char_type* __s, size_t __n, const char_type& __a)
425  	      {
426  		for (size_t __i = 0; __i < __n; ++__i)
427  		  if (eq(__s[__i], __a))
428  		    return __s + __i;
429  		return 0;
430  	      }
431  	
432  	      static char_type*
433  	      move(char_type* __s1, const char_type* __s2, size_t __n)
434  	      {
435  		return (static_cast<char_type*>
436  			(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
437  	      }
438  	
439  	      static char_type*
440  	      copy(char_type* __s1, const char_type* __s2, size_t __n)
441  	      {
442  		return (static_cast<char_type*>
443  			(__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
444  	      }
445  	
446  	      static char_type*
447  	      assign(char_type* __s, size_t __n, char_type __a)
448  	      {
449  		for (size_t __i = 0; __i < __n; ++__i)
450  		  assign(__s[__i], __a);
451  		return __s;
452  	      }
453  	
454  	      static constexpr char_type
455  	      to_char_type(const int_type& __c) noexcept
456  	      { return char_type(__c); }
457  	
458  	      static constexpr int_type
459  	      to_int_type(const char_type& __c) noexcept
460  	      { return int_type(__c); }
461  	
462  	      static constexpr bool
463  	      eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
464  	      { return __c1 == __c2; }
465  	
466  	      static constexpr int_type
467  	      eof() noexcept
468  	      { return static_cast<int_type>(-1); }
469  	
470  	      static constexpr int_type
471  	      not_eof(const int_type& __c) noexcept
472  	      { return eq_int_type(__c, eof()) ? 0 : __c; }
473  	    };
474  	
475  	  template<>
476  	    struct char_traits<char32_t>
477  	    {
478  	      typedef char32_t          char_type;
479  	      typedef uint_least32_t    int_type;
480  	      typedef streamoff         off_type;
481  	      typedef u32streampos      pos_type;
482  	      typedef mbstate_t         state_type;
483  	
484  	      static void
485  	      assign(char_type& __c1, const char_type& __c2) noexcept
486  	      { __c1 = __c2; }
487  	
488  	      static constexpr bool
489  	      eq(const char_type& __c1, const char_type& __c2) noexcept
490  	      { return __c1 == __c2; }
491  	
492  	      static constexpr bool
493  	      lt(const char_type& __c1, const char_type& __c2) noexcept
494  	      { return __c1 < __c2; }
495  	
496  	      static int
497  	      compare(const char_type* __s1, const char_type* __s2, size_t __n)
498  	      {
499  		for (size_t __i = 0; __i < __n; ++__i)
500  		  if (lt(__s1[__i], __s2[__i]))
501  		    return -1;
502  		  else if (lt(__s2[__i], __s1[__i]))
503  		    return 1;
504  		return 0;
505  	      }
506  	
507  	      static size_t
508  	      length(const char_type* __s)
509  	      {
510  		size_t __i = 0;
511  		while (!eq(__s[__i], char_type()))
512  		  ++__i;
513  		return __i;
514  	      }
515  	
516  	      static const char_type*
517  	      find(const char_type* __s, size_t __n, const char_type& __a)
518  	      {
519  		for (size_t __i = 0; __i < __n; ++__i)
520  		  if (eq(__s[__i], __a))
521  		    return __s + __i;
522  		return 0;
523  	      }
524  	
525  	      static char_type*
526  	      move(char_type* __s1, const char_type* __s2, size_t __n)
527  	      {
528  		return (static_cast<char_type*>
529  			(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
530  	      }
531  	
532  	      static char_type*
533  	      copy(char_type* __s1, const char_type* __s2, size_t __n)
534  	      { 
535  		return (static_cast<char_type*>
536  			(__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
537  	      }
538  	
539  	      static char_type*
540  	      assign(char_type* __s, size_t __n, char_type __a)
541  	      {
542  		for (size_t __i = 0; __i < __n; ++__i)
543  		  assign(__s[__i], __a);
544  		return __s;
545  	      }
546  	
547  	      static constexpr char_type
548  	      to_char_type(const int_type& __c) noexcept
549  	      { return char_type(__c); }
550  	
551  	      static constexpr int_type
552  	      to_int_type(const char_type& __c) noexcept
553  	      { return int_type(__c); }
554  	
555  	      static constexpr bool
556  	      eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
557  	      { return __c1 == __c2; }
558  	
559  	      static constexpr int_type
560  	      eof() noexcept
561  	      { return static_cast<int_type>(-1); }
562  	
563  	      static constexpr int_type
564  	      not_eof(const int_type& __c) noexcept
565  	      { return eq_int_type(__c, eof()) ? 0 : __c; }
566  	    };
567  	
568  	_GLIBCXX_END_NAMESPACE_VERSION
569  	} // namespace
570  	
571  	#endif 
572  	
573  	#endif // _CHAR_TRAITS_H
574