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