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