Home | History | Annotate | Download | only in ext
      1 // POD character, std::char_traits specialization -*- C++ -*-
      2 
      3 // Copyright (C) 2002-2013 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 #pragma GCC system_header
     36 
     37 #include <string>
     38 
     39 namespace __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 V, typename I, typename S = std::mbstate_t>
     49     struct character
     50     {
     51       typedef V				value_type;
     52       typedef I				int_type;
     53       typedef S				state_type;
     54       typedef character<V, I, S>	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 V, typename I, typename S>
     77     inline bool
     78     operator==(const character<V, I, S>& lhs, const character<V, I, S>& rhs)
     79     { return lhs.value == rhs.value; }
     80 
     81   template<typename V, typename I, typename S>
     82     inline bool
     83     operator<(const character<V, I, S>& lhs, const character<V, I, S>& rhs)
     84     { return lhs.value < rhs.value; }
     85 
     86 _GLIBCXX_END_NAMESPACE_VERSION
     87 } // namespace
     88 
     89 namespace std _GLIBCXX_VISIBILITY(default)
     90 {
     91 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     92 
     93   /// char_traits<__gnu_cxx::character> specialization.
     94   template<typename V, typename I, typename S>
     95     struct char_traits<__gnu_cxx::character<V, I, S> >
     96     {
     97       typedef __gnu_cxx::character<V, I, S>	char_type;
     98       typedef typename char_type::int_type	int_type;
     99       typedef typename char_type::state_type	state_type;
    100       typedef fpos<state_type>			pos_type;
    101       typedef streamoff				off_type;
    102 
    103       static void
    104       assign(char_type& __c1, const char_type& __c2)
    105       { __c1 = __c2; }
    106 
    107       static bool
    108       eq(const char_type& __c1, const char_type& __c2)
    109       { return __c1 == __c2; }
    110 
    111       static bool
    112       lt(const char_type& __c1, const char_type& __c2)
    113       { return __c1 < __c2; }
    114 
    115       static int
    116       compare(const char_type* __s1, const char_type* __s2, size_t __n)
    117       {
    118 	for (size_t __i = 0; __i < __n; ++__i)
    119 	  if (!eq(__s1[__i], __s2[__i]))
    120 	    return lt(__s1[__i], __s2[__i]) ? -1 : 1;
    121 	return 0;
    122       }
    123 
    124       static size_t
    125       length(const char_type* __s)
    126       {
    127 	const char_type* __p = __s;
    128 	while (__p->value)
    129 	  ++__p;
    130 	return (__p - __s);
    131       }
    132 
    133       static const char_type*
    134       find(const char_type* __s, size_t __n, const char_type& __a)
    135       {
    136 	for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p)
    137 	  if (*__p == __a)
    138 	    return __p;
    139 	return 0;
    140       }
    141 
    142       static char_type*
    143       move(char_type* __s1, const char_type* __s2, size_t __n)
    144       {
    145 	return static_cast<char_type*>
    146 	  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)));
    147       }
    148 
    149       static char_type*
    150       copy(char_type* __s1, const char_type* __s2, size_t __n)
    151       {
    152 	std::copy(__s2, __s2 + __n, __s1);
    153 	return __s1;
    154       }
    155 
    156       static char_type*
    157       assign(char_type* __s, size_t __n, char_type __a)
    158       {
    159 	std::fill_n(__s, __n, __a);
    160         return __s;
    161       }
    162 
    163       static char_type
    164       to_char_type(const int_type& __i)
    165       { return char_type::template from(__i); }
    166 
    167       static int_type
    168       to_int_type(const char_type& __c)
    169       { return char_type::template to<int_type>(__c); }
    170 
    171       static bool
    172       eq_int_type(const int_type& __c1, const int_type& __c2)
    173       { return __c1 == __c2; }
    174 
    175       static int_type
    176       eof()
    177       {
    178 	int_type __r = { -1 };
    179 	return __r;
    180       }
    181 
    182       static int_type
    183       not_eof(const int_type& __c)
    184       { return eq_int_type(__c, eof()) ? int_type() : __c; }
    185     };
    186 
    187 _GLIBCXX_END_NAMESPACE_VERSION
    188 } // namespace
    189 
    190 #endif
    191