1132720Skan// POD character, std::char_traits specialization -*- C++ -*-
2132720Skan
3169691Skan// Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4132720Skan//
5132720Skan// This file is part of the GNU ISO C++ Library.  This library is free
6132720Skan// software; you can redistribute it and/or modify it under the
7132720Skan// terms of the GNU General Public License as published by the
8132720Skan// Free Software Foundation; either version 2, or (at your option)
9132720Skan// any later version.
10132720Skan
11132720Skan// This library is distributed in the hope that it will be useful,
12132720Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
13132720Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14132720Skan// GNU General Public License for more details.
15132720Skan
16132720Skan// You should have received a copy of the GNU General Public License along
17132720Skan// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19132720Skan// USA.
20132720Skan
21132720Skan// As a special exception, you may use this file as part of a free software
22132720Skan// library without restriction.  Specifically, if other files instantiate
23132720Skan// templates or use macros or inline functions from this file, or you compile
24132720Skan// this file and link it with other files to produce an executable, this
25132720Skan// file does not by itself cause the resulting executable to be covered by
26132720Skan// the GNU General Public License.  This exception does not however
27132720Skan// invalidate any other reasons why the executable file might be covered by
28132720Skan// the GNU General Public License.
29132720Skan
30169691Skan/** @file ext/pod_char_traits.h
31169691Skan *  This file is a GNU extension to the Standard C++ Library.
32169691Skan */
33169691Skan
34132720Skan// Gabriel Dos Reis <gdr@integrable-solutions.net>
35132720Skan// Benjamin Kosnik <bkoz@redhat.com>
36132720Skan
37132720Skan#ifndef _POD_CHAR_TRAITS_H
38132720Skan#define _POD_CHAR_TRAITS_H 1
39132720Skan
40132720Skan#include <string>
41132720Skan
42169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
43169691Skan
44169691Skan  // POD character abstraction.
45169691Skan  // NB: The char_type parameter is a subset of int_type, as to allow
46169691Skan  // int_type to properly hold the full range of char_type values as
47169691Skan  // well as EOF.
48169691Skan  /// @brief A POD class that serves as a character abstraction class.
49132720Skan  template<typename V, typename I, typename S = mbstate_t>
50132720Skan    struct character
51132720Skan    {
52169691Skan      typedef V				value_type;
53169691Skan      typedef I				int_type;
54169691Skan      typedef S				state_type;
55169691Skan      typedef character<V, I, S>	char_type;
56169691Skan
57132720Skan      value_type	value;
58169691Skan
59169691Skan      template<typename V2>
60169691Skan        static char_type
61169691Skan        from(const V2& v)
62169691Skan        {
63169691Skan	  char_type ret = { static_cast<value_type>(v) };
64169691Skan	  return ret;
65169691Skan	}
66169691Skan
67169691Skan      template<typename V2>
68169691Skan        static V2
69169691Skan        to(const char_type& c)
70169691Skan        {
71169691Skan	  V2 ret = { static_cast<V2>(c.value) };
72169691Skan	  return ret;
73169691Skan	}
74169691Skan
75132720Skan    };
76132720Skan
77169691Skan  template<typename V, typename I, typename S>
78132720Skan    inline bool
79169691Skan    operator==(const character<V, I, S>& lhs, const character<V, I, S>& rhs)
80132720Skan    { return lhs.value == rhs.value; }
81132720Skan
82169691Skan  template<typename V, typename I, typename S>
83132720Skan    inline bool
84169691Skan    operator<(const character<V, I, S>& lhs, const character<V, I, S>& rhs)
85132720Skan    { return lhs.value < rhs.value; }
86132720Skan
87169691Skan_GLIBCXX_END_NAMESPACE
88169691Skan
89169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
90169691Skan
91169691Skan  /// char_traits<__gnu_cxx::character> specialization.
92132720Skan  template<typename V, typename I, typename S>
93132720Skan    struct char_traits<__gnu_cxx::character<V, I, S> >
94132720Skan    {
95132720Skan      typedef __gnu_cxx::character<V, I, S>	char_type;
96132720Skan      typedef typename char_type::int_type	int_type;
97132720Skan      typedef typename char_type::state_type	state_type;
98132720Skan      typedef fpos<state_type>			pos_type;
99132720Skan      typedef streamoff				off_type;
100132720Skan
101132720Skan      static void
102132720Skan      assign(char_type& __c1, const char_type& __c2)
103132720Skan      { __c1 = __c2; }
104132720Skan
105132720Skan      static bool
106132720Skan      eq(const char_type& __c1, const char_type& __c2)
107132720Skan      { return __c1 == __c2; }
108132720Skan
109132720Skan      static bool
110132720Skan      lt(const char_type& __c1, const char_type& __c2)
111132720Skan      { return __c1 < __c2; }
112132720Skan
113132720Skan      static int
114132720Skan      compare(const char_type* __s1, const char_type* __s2, size_t __n)
115132720Skan      {
116132720Skan	for (size_t __i = 0; __i < __n; ++__i)
117132720Skan	  if (!eq(__s1[__i], __s2[__i]))
118132720Skan	    return lt(__s1[__i], __s2[__i]) ? -1 : 1;
119132720Skan	return 0;
120132720Skan      }
121132720Skan
122132720Skan      static size_t
123132720Skan      length(const char_type* __s)
124132720Skan      {
125132720Skan	const char_type* __p = __s;
126132720Skan	while (__p->value)
127132720Skan	  ++__p;
128132720Skan	return (__p - __s);
129132720Skan      }
130132720Skan
131132720Skan      static const char_type*
132132720Skan      find(const char_type* __s, size_t __n, const char_type& __a)
133132720Skan      {
134132720Skan	for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p)
135132720Skan	  if (*__p == __a)
136132720Skan	    return __p;
137132720Skan	return 0;
138132720Skan      }
139132720Skan
140132720Skan      static char_type*
141132720Skan      move(char_type* __s1, const char_type* __s2, size_t __n)
142169691Skan      {
143169691Skan	return static_cast<char_type*>(std::memmove(__s1, __s2,
144169691Skan						    __n * sizeof(char_type)));
145169691Skan      }
146132720Skan
147132720Skan      static char_type*
148132720Skan      copy(char_type* __s1, const char_type* __s2, size_t __n)
149169691Skan      {
150169691Skan	std::copy(__s2, __s2 + __n, __s1);
151169691Skan	return __s1;
152169691Skan      }
153132720Skan
154132720Skan      static char_type*
155132720Skan      assign(char_type* __s, size_t __n, char_type __a)
156132720Skan      {
157169691Skan	std::fill_n(__s, __n, __a);
158132720Skan        return __s;
159132720Skan      }
160132720Skan
161132720Skan      static char_type
162169691Skan      to_char_type(const int_type& __i)
163169691Skan      { return char_type::template from(__i); }
164132720Skan
165132720Skan      static int_type
166132720Skan      to_int_type(const char_type& __c)
167169691Skan      { return char_type::template to<int_type>(__c); }
168132720Skan
169132720Skan      static bool
170132720Skan      eq_int_type(const int_type& __c1, const int_type& __c2)
171132720Skan      { return __c1 == __c2; }
172132720Skan
173132720Skan      static int_type
174169691Skan      eof()
175169691Skan      {
176169691Skan	int_type __r = { -1 };
177169691Skan	return __r;
178169691Skan      }
179132720Skan
180132720Skan      static int_type
181132720Skan      not_eof(const int_type& __c)
182169691Skan      { return eq_int_type(__c, eof()) ? int_type() : __c; }
183132720Skan    };
184132720Skan
185169691Skan_GLIBCXX_END_NAMESPACE
186169691Skan
187132720Skan#endif
188