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