1// POD character, std::char_traits specialization -*- C++ -*-
2
3// Copyright (C) 2002-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 ext/pod_char_traits.h
26 *  This file is a GNU extension to the Standard C++ Library.
27 */
28
29// Gabriel Dos Reis <gdr@integrable-solutions.net>
30// Benjamin Kosnik <bkoz@redhat.com>
31
32#ifndef _POD_CHAR_TRAITS_H
33#define _POD_CHAR_TRAITS_H 1
34
35#pragma GCC system_header
36
37#include <string>
38
39namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
40{
41_GLIBCXX_BEGIN_NAMESPACE_VERSION
42
43  // POD character abstraction.
44  // NB: The char_type parameter is a subset of int_type, as to allow
45  // int_type to properly hold the full range of char_type values as
46  // well as EOF.
47  /// @brief A POD class that serves as a character abstraction class.
48  template<typename _Value, typename _Int, typename _St = std::mbstate_t>
49    struct character
50    {
51      typedef _Value				value_type;
52      typedef _Int				int_type;
53      typedef _St				state_type;
54      typedef character<_Value, _Int, _St>	char_type;
55
56      value_type	value;
57
58      template<typename V2>
59        static char_type
60        from(const V2& v)
61        {
62	  char_type ret = { static_cast<value_type>(v) };
63	  return ret;
64	}
65
66      template<typename V2>
67        static V2
68        to(const char_type& c)
69        {
70	  V2 ret = { static_cast<V2>(c.value) };
71	  return ret;
72	}
73
74    };
75
76  template<typename _Value, typename _Int, typename _St>
77    inline bool
78    operator==(const character<_Value, _Int, _St>& lhs,
79	       const character<_Value, _Int, _St>& rhs)
80    { return lhs.value == rhs.value; }
81
82  template<typename _Value, typename _Int, typename _St>
83    inline bool
84    operator<(const character<_Value, _Int, _St>& lhs,
85	      const character<_Value, _Int, _St>& rhs)
86    { return lhs.value < rhs.value; }
87
88_GLIBCXX_END_NAMESPACE_VERSION
89} // namespace
90
91namespace std _GLIBCXX_VISIBILITY(default)
92{
93_GLIBCXX_BEGIN_NAMESPACE_VERSION
94
95  /// char_traits<__gnu_cxx::character> specialization.
96  template<typename _Value, typename _Int, typename _St>
97    struct char_traits<__gnu_cxx::character<_Value, _Int, _St> >
98    {
99      typedef __gnu_cxx::character<_Value, _Int, _St>	char_type;
100      typedef typename char_type::int_type		int_type;
101      typedef typename char_type::state_type		state_type;
102      typedef fpos<state_type>				pos_type;
103      typedef streamoff					off_type;
104
105      static void
106      assign(char_type& __c1, const char_type& __c2)
107      { __c1 = __c2; }
108
109      static bool
110      eq(const char_type& __c1, const char_type& __c2)
111      { return __c1 == __c2; }
112
113      static bool
114      lt(const char_type& __c1, const char_type& __c2)
115      { return __c1 < __c2; }
116
117      static int
118      compare(const char_type* __s1, const char_type* __s2, size_t __n)
119      {
120	for (size_t __i = 0; __i < __n; ++__i)
121	  if (!eq(__s1[__i], __s2[__i]))
122	    return lt(__s1[__i], __s2[__i]) ? -1 : 1;
123	return 0;
124      }
125
126      static size_t
127      length(const char_type* __s)
128      {
129	const char_type* __p = __s;
130	while (__p->value)
131	  ++__p;
132	return (__p - __s);
133      }
134
135      static const char_type*
136      find(const char_type* __s, size_t __n, const char_type& __a)
137      {
138	for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p)
139	  if (*__p == __a)
140	    return __p;
141	return 0;
142      }
143
144      static char_type*
145      move(char_type* __s1, const char_type* __s2, size_t __n)
146      {
147	if (__n == 0)
148	  return __s1;
149	return static_cast<char_type*>
150	  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)));
151      }
152
153      static char_type*
154      copy(char_type* __s1, const char_type* __s2, size_t __n)
155      {
156	if (__n == 0)
157	  return __s1;
158	std::copy(__s2, __s2 + __n, __s1);
159	return __s1;
160      }
161
162      static char_type*
163      assign(char_type* __s, size_t __n, char_type __a)
164      {
165	std::fill_n(__s, __n, __a);
166        return __s;
167      }
168
169      static char_type
170      to_char_type(const int_type& __i)
171      { return char_type::template from(__i); }
172
173      static int_type
174      to_int_type(const char_type& __c)
175      { return char_type::template to<int_type>(__c); }
176
177      static bool
178      eq_int_type(const int_type& __c1, const int_type& __c2)
179      { return __c1 == __c2; }
180
181      static int_type
182      eof()
183      {
184	int_type __r = { static_cast<typename __gnu_cxx::__conditional_type
185			 <std::__is_integer<int_type>::__value,
186			 int_type, int>::__type>(-1) };
187	return __r;
188      }
189
190      static int_type
191      not_eof(const int_type& __c)
192      { return eq_int_type(__c, eof()) ? int_type() : __c; }
193    };
194
195_GLIBCXX_END_NAMESPACE_VERSION
196} // namespace
197
198#endif
199