Merge branch 'master' of ssh://crater.dragonflybsd.org/repository/git/dragonfly
[dragonfly.git] / contrib / gcc-3.4 / libstdc++-v3 / include / bits / char_traits.h
1 // Character Traits for use by standard string and iostream -*- C++ -*-
2
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 //
32 // ISO C++ 14882: 21  Strings library
33 //
34
35 /** @file char_traits.h
36  *  This is an internal header file, included by other library headers.
37  *  You should not attempt to use it directly.
38  */
39
40 #ifndef _CHAR_TRAITS_H
41 #define _CHAR_TRAITS_H 1
42
43 #pragma GCC system_header
44
45 #include <cstring>            // For memmove, memset, memchr
46 #include <bits/stl_algobase.h>// For copy, lexicographical_compare, fill_n
47 #include <bits/postypes.h>    // For streampos
48
49 namespace __gnu_cxx
50 {
51   /**
52    *  @brief  Mapping from character type to associated types.
53    *
54    *
55    *  @note This is an implementation class for the generic version
56    *  of char_traits.  It defines int_type, off_type, pos_type, and
57    *  state_type.  By default these are unsigned long, streamoff,
58    *  streampos, and mbstate_t.  Users who need a different set of
59    *  types, but who don't need to change the definitions of any function
60    *  defined in char_traits, can specialize __gnu_cxx::_Char_types
61    *  while leaving __gnu_cxx::char_traits alone. */
62   template <class _CharT>
63     struct _Char_types
64     {
65       typedef unsigned long   int_type;
66       typedef std::streampos  pos_type;
67       typedef std::streamoff  off_type;
68       typedef std::mbstate_t  state_type;
69     };
70
71
72   /**
73    *  @brief  Base class used to implement std::char_traits.
74    *
75    *  @note For any given actual character type, this definition is
76    *  probably wrong.  (Most of the member functions are likely to be
77    *  right, but the int_type and state_type typedefs, and the eof()
78    *  member function, are likely to be wrong.)  The reason this class
79    *  exists is so users can specialize it.  Classes in namespace std
80    *  may not be specialized for fundamentl types, but classes in
81    *  namespace __gnu_cxx may be.
82    *
83    *  See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5
84    *  for advice on how to make use of this class for "unusual" character
85    *  types. Also, check out include/ext/pod_char_traits.h.  */
86   template<typename _CharT>
87     struct char_traits
88     {
89       typedef _CharT                                    char_type;
90       typedef typename _Char_types<_CharT>::int_type    int_type;
91       typedef typename _Char_types<_CharT>::pos_type    pos_type;
92       typedef typename _Char_types<_CharT>::off_type    off_type;
93       typedef typename _Char_types<_CharT>::state_type  state_type;
94
95       static void
96       assign(char_type& __c1, const char_type& __c2)
97       { __c1 = __c2; }
98
99       static bool
100       eq(const char_type& __c1, const char_type& __c2)
101       { return __c1 == __c2; }
102
103       static bool
104       lt(const char_type& __c1, const char_type& __c2)
105       { return __c1 < __c2; }
106
107       static int
108       compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
109
110       static std::size_t
111       length(const char_type* __s);
112
113       static const char_type*
114       find(const char_type* __s, std::size_t __n, const char_type& __a);
115
116       static char_type*
117       move(char_type* __s1, const char_type* __s2, std::size_t __n);
118
119       static char_type*
120       copy(char_type* __s1, const char_type* __s2, std::size_t __n);
121
122       static char_type*
123       assign(char_type* __s, std::size_t __n, char_type __a);
124
125       static char_type
126       to_char_type(const int_type& __c)
127       { return static_cast<char_type>(__c); }
128
129       static int_type
130       to_int_type(const char_type& __c)
131       { return static_cast<int_type>(__c); }
132
133       static bool
134       eq_int_type(const int_type& __c1, const int_type& __c2)
135       { return __c1 == __c2; }
136
137       static int_type
138       eof()
139       { return static_cast<int_type>(EOF); }
140
141       static int_type
142       not_eof(const int_type& __c)
143       { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
144     };
145
146   template<typename _CharT>
147     int
148     char_traits<_CharT>::
149     compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
150     {
151       for (size_t __i = 0; __i < __n; ++__i)
152         if (lt(__s1[__i], __s2[__i]))
153           return -1;
154         else if (lt(__s2[__i], __s1[__i]))
155           return 1;
156       return 0;
157     }
158
159   template<typename _CharT>
160     std::size_t
161     char_traits<_CharT>::
162     length(const char_type* __p)
163     {
164       std::size_t __i = 0;
165       while (!eq(__p[__i], char_type()))
166         ++__i;
167       return __i;
168     }
169
170   template<typename _CharT>
171     const typename char_traits<_CharT>::char_type*
172     char_traits<_CharT>::
173     find(const char_type* __s, std::size_t __n, const char_type& __a)
174     {
175       for (std::size_t __i = 0; __i < __n; ++__i)
176         if (eq(__s[__i], __a))
177           return __s + __i;
178       return 0;
179     }
180
181   template<typename _CharT>
182     typename char_traits<_CharT>::char_type*
183     char_traits<_CharT>::
184     move(char_type* __s1, const char_type* __s2, std::size_t __n)
185     {
186       return static_cast<_CharT*>(std::memmove(__s1, __s2,
187                                                __n * sizeof(char_type)));
188     }
189
190   template<typename _CharT>
191     typename char_traits<_CharT>::char_type*
192     char_traits<_CharT>::
193     copy(char_type* __s1, const char_type* __s2, std::size_t __n)
194     {
195       std::copy(__s2, __s2 + __n, __s1);
196       return __s1;
197     }
198
199   template<typename _CharT>
200     typename char_traits<_CharT>::char_type*
201     char_traits<_CharT>::
202     assign(char_type* __s, std::size_t __n, char_type __a)
203     {
204       std::fill_n(__s, __n, __a);
205       return __s;
206     }
207 }
208
209 namespace std
210 {
211   // 21.1
212   /**
213    *  @brief  Basis for explicit traits specializations.
214    *
215    *  @note  For any given actual character type, this definition is
216    *  probably wrong.  Since this is just a thin wrapper around
217    *  __gnu_cxx::char_traits, it is possible to achieve a more
218    *  appropriate definition by specializing __gnu_cxx::char_traits.
219    *
220    *  See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5
221    *  for advice on how to make use of this class for "unusual" character
222    *  types. Also, check out include/ext/pod_char_traits.h.
223   */
224   template<class _CharT>
225     struct char_traits
226     : public __gnu_cxx::char_traits<_CharT>
227     { };
228
229
230   /// 21.1.3.1  char_traits specializations
231   template<>
232     struct char_traits<char>
233     {
234       typedef char              char_type;
235       typedef int               int_type;
236       typedef streampos         pos_type;
237       typedef streamoff         off_type;
238       typedef mbstate_t         state_type;
239
240       static void
241       assign(char_type& __c1, const char_type& __c2)
242       { __c1 = __c2; }
243
244       static bool
245       eq(const char_type& __c1, const char_type& __c2)
246       { return __c1 == __c2; }
247
248       static bool
249       lt(const char_type& __c1, const char_type& __c2)
250       { return __c1 < __c2; }
251
252       static int
253       compare(const char_type* __s1, const char_type* __s2, size_t __n)
254       { return memcmp(__s1, __s2, __n); }
255
256       static size_t
257       length(const char_type* __s)
258       { return strlen(__s); }
259
260       static const char_type*
261       find(const char_type* __s, size_t __n, const char_type& __a)
262       { return static_cast<const char_type*>(memchr(__s, __a, __n)); }
263
264       static char_type*
265       move(char_type* __s1, const char_type* __s2, size_t __n)
266       { return static_cast<char_type*>(memmove(__s1, __s2, __n)); }
267
268       static char_type*
269       copy(char_type* __s1, const char_type* __s2, size_t __n)
270       { return static_cast<char_type*>(memcpy(__s1, __s2, __n)); }
271
272       static char_type*
273       assign(char_type* __s, size_t __n, char_type __a)
274       { return static_cast<char_type*>(memset(__s, __a, __n)); }
275
276       static char_type
277       to_char_type(const int_type& __c)
278       { return static_cast<char_type>(__c); }
279
280       // To keep both the byte 0xff and the eof symbol 0xffffffff
281       // from ending up as 0xffffffff.
282       static int_type
283       to_int_type(const char_type& __c)
284       { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
285
286       static bool
287       eq_int_type(const int_type& __c1, const int_type& __c2)
288       { return __c1 == __c2; }
289
290       static int_type
291       eof() { return static_cast<int_type>(EOF); }
292
293       static int_type
294       not_eof(const int_type& __c)
295       { return (__c == eof()) ? 0 : __c; }
296   };
297
298
299 #ifdef _GLIBCXX_USE_WCHAR_T
300   /// 21.1.3.2  char_traits specializations
301   template<>
302     struct char_traits<wchar_t>
303     {
304       typedef wchar_t           char_type;
305       typedef wint_t            int_type;
306       typedef streamoff         off_type;
307       typedef wstreampos        pos_type;
308       typedef mbstate_t         state_type;
309
310       static void
311       assign(char_type& __c1, const char_type& __c2)
312       { __c1 = __c2; }
313
314       static bool
315       eq(const char_type& __c1, const char_type& __c2)
316       { return __c1 == __c2; }
317
318       static bool
319       lt(const char_type& __c1, const char_type& __c2)
320       { return __c1 < __c2; }
321
322       static int
323       compare(const char_type* __s1, const char_type* __s2, size_t __n)
324       { return wmemcmp(__s1, __s2, __n); }
325
326       static size_t
327       length(const char_type* __s)
328       { return wcslen(__s); }
329
330       static const char_type*
331       find(const char_type* __s, size_t __n, const char_type& __a)
332       { return wmemchr(__s, __a, __n); }
333
334       static char_type*
335       move(char_type* __s1, const char_type* __s2, size_t __n)
336       { return wmemmove(__s1, __s2, __n); }
337
338       static char_type*
339       copy(char_type* __s1, const char_type* __s2, size_t __n)
340       { return wmemcpy(__s1, __s2, __n); }
341
342       static char_type*
343       assign(char_type* __s, size_t __n, char_type __a)
344       { return wmemset(__s, __a, __n); }
345
346       static char_type
347       to_char_type(const int_type& __c) { return char_type(__c); }
348
349       static int_type
350       to_int_type(const char_type& __c) { return int_type(__c); }
351
352       static bool
353       eq_int_type(const int_type& __c1, const int_type& __c2)
354       { return __c1 == __c2; }
355
356       static int_type
357       eof() { return static_cast<int_type>(WEOF); }
358
359       static int_type
360       not_eof(const int_type& __c)
361       { return eq_int_type(__c, eof()) ? 0 : __c; }
362   };
363 #endif //_GLIBCXX_USE_WCHAR_T
364
365   template<typename _CharT, typename _Traits>
366     struct _Char_traits_match
367     {
368       _CharT _M_c;
369       _Char_traits_match(_CharT const& __c) : _M_c(__c) { }
370
371       bool
372       operator()(_CharT const& __a) { return _Traits::eq(_M_c, __a); }
373     };
374 } // namespace std
375
376 #endif