// POD character, std::char_traits specialization -*- C++ -*-

// Copyright (C) 2002, 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file ext/pod_char_traits.h
 *  This file is a GNU extension to the Standard C++ Library.
 */

// Gabriel Dos Reis <gdr@integrable-solutions.net>
// Benjamin Kosnik <bkoz@redhat.com>

#ifndef _POD_CHAR_TRAITS_H
#define _POD_CHAR_TRAITS_H 1

#include <string>

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  // POD character abstraction.
  // NB: The char_type parameter is a subset of int_type, as to allow
  // int_type to properly hold the full range of char_type values as
  // well as EOF.
  /// @brief A POD class that serves as a character abstraction class.
  template<typename V, typename I, typename S = std::mbstate_t>
    struct character
    {
      typedef V				value_type;
      typedef I				int_type;
      typedef S				state_type;
      typedef character<V, I, S>	char_type;

      value_type	value;

      template<typename V2>
        static char_type
        from(const V2& v)
        {
	  char_type ret = { static_cast<value_type>(v) };
	  return ret;
	}

      template<typename V2>
        static V2
        to(const char_type& c)
        {
	  V2 ret = { static_cast<V2>(c.value) };
	  return ret;
	}

    };

  template<typename V, typename I, typename S>
    inline bool
    operator==(const character<V, I, S>& lhs, const character<V, I, S>& rhs)
    { return lhs.value == rhs.value; }

  template<typename V, typename I, typename S>
    inline bool
    operator<(const character<V, I, S>& lhs, const character<V, I, S>& rhs)
    { return lhs.value < rhs.value; }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /// char_traits<__gnu_cxx::character> specialization.
  template<typename V, typename I, typename S>
    struct char_traits<__gnu_cxx::character<V, I, S> >
    {
      typedef __gnu_cxx::character<V, I, S>	char_type;
      typedef typename char_type::int_type	int_type;
      typedef typename char_type::state_type	state_type;
      typedef fpos<state_type>			pos_type;
      typedef streamoff				off_type;

      static void
      assign(char_type& __c1, const char_type& __c2)
      { __c1 = __c2; }

      static bool
      eq(const char_type& __c1, const char_type& __c2)
      { return __c1 == __c2; }

      static bool
      lt(const char_type& __c1, const char_type& __c2)
      { return __c1 < __c2; }

      static int
      compare(const char_type* __s1, const char_type* __s2, size_t __n)
      {
	for (size_t __i = 0; __i < __n; ++__i)
	  if (!eq(__s1[__i], __s2[__i]))
	    return lt(__s1[__i], __s2[__i]) ? -1 : 1;
	return 0;
      }

      static size_t
      length(const char_type* __s)
      {
	const char_type* __p = __s;
	while (__p->value)
	  ++__p;
	return (__p - __s);
      }

      static const char_type*
      find(const char_type* __s, size_t __n, const char_type& __a)
      {
	for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p)
	  if (*__p == __a)
	    return __p;
	return 0;
      }

      static char_type*
      move(char_type* __s1, const char_type* __s2, size_t __n)
      { 
	return static_cast<char_type*>
	  (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)));
      }

      static char_type*
      copy(char_type* __s1, const char_type* __s2, size_t __n)
      {
	std::copy(__s2, __s2 + __n, __s1);
	return __s1;
      }

      static char_type*
      assign(char_type* __s, size_t __n, char_type __a)
      {
	std::fill_n(__s, __n, __a);
        return __s;
      }

      static char_type
      to_char_type(const int_type& __i)
      { return char_type::template from(__i); }

      static int_type
      to_int_type(const char_type& __c)
      { return char_type::template to<int_type>(__c); }

      static bool
      eq_int_type(const int_type& __c1, const int_type& __c2)
      { return __c1 == __c2; }

      static int_type
      eof() 
      {
	int_type __r = { -1 };
	return __r;
      }

      static int_type
      not_eof(const int_type& __c)
      { return eq_int_type(__c, eof()) ? int_type() : __c; }
    };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif
