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