// -*- C++ -*-

// Testing character type and state type with char_traits and codecvt
// specializations for the C++ library testsuite.
//
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 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.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.
//

#ifndef _GLIBCXX_TESTSUITE_CHARACTER_H
#define _GLIBCXX_TESTSUITE_CHARACTER_H

#include <climits>
#include <string> // for char_traits
#include <locale> // for codecvt
#include <algorithm> // for transform
#include <ext/pod_char_traits.h>

namespace __gnu_test
{  
  struct pod_int
  {
    int value;

#ifdef __GXX_EXPERIMENTAL_CXX0X__
    // For std::iota.
    pod_int&
    operator++()
    {
      ++value;
      return *this;
    }
#endif
  };

  // For 20.1 requirements for instantiable type: equality comparable
  // and less than comparable.
  inline bool
  operator==(const pod_int& lhs, const pod_int& rhs)
  { return lhs.value == rhs.value; }
  
  inline bool
  operator<(const pod_int& lhs, const pod_int& rhs)
  { return lhs.value < rhs.value; }

  // For 26 numeric algorithms requirements, need addable,
  // subtractable, multiplicable.
  inline pod_int
  operator+(const pod_int& lhs, const pod_int& rhs)
  {
    pod_int ret = { lhs.value + rhs.value };
    return ret;
  }

  inline pod_int
  operator-(const pod_int& lhs, const pod_int& rhs)
  { 
    pod_int ret = { lhs.value - rhs.value };
    return ret;
  }

  inline pod_int
  operator*(const pod_int& lhs, const pod_int& rhs)
  { 
    pod_int ret = { lhs.value * rhs.value };
    return ret;
  }

  struct pod_state
  {
    unsigned long value;
  };

  inline bool
  operator==(const pod_state& lhs, const pod_state& rhs)
  { return lhs.value == rhs.value; }

  inline bool
  operator<(const pod_state& lhs, const pod_state& rhs)
  { return lhs.value < rhs.value; }

  // Alternate character types.
  using __gnu_cxx::character;
  typedef character<unsigned char, pod_int, pod_state>  	pod_char;
  typedef character<unsigned char, unsigned int, pod_state>  	pod_uchar;
  typedef character<unsigned short, unsigned int>	   	pod_ushort;
  typedef character<unsigned int, unsigned long>	   	pod_uint;  
}

namespace __gnu_cxx 
{
  // Specializations.
  // pod_char
  template<>
    template<typename V2>
      inline __gnu_test::pod_char::char_type
      __gnu_test::pod_char::char_type::from(const V2& v)
      {
	char_type ret = { static_cast<value_type>(v.value) };
	return ret;
      }

  template<>
    template<typename V2>
      inline V2
      __gnu_test::pod_char::char_type::to(const char_type& c)
      {
	V2 ret = { c.value };
	return ret;
      }
  
  template<>
    template<typename V2>
      inline __gnu_test::pod_uchar::char_type
      __gnu_test::pod_uchar::char_type::from(const V2& v)
      {
	char_type ret;
	ret.value = (v >> 5);
	return ret;
      }

  template<>
    template<typename V2>
      inline V2
      __gnu_test::pod_uchar::char_type::to(const char_type& c)
      { return static_cast<V2>(c.value << 5); }
} // namespace __gnu_test

namespace std
{
  // codecvt specialization
  //
  // The conversion performed by the specialization is not supposed to
  // be useful, rather it has been designed to demonstrate the
  // essential features of stateful conversions:
  // * Number and value of bytes for each internal character depends on the
  //   state in addition to the character itself.
  // * Unshift produces an unshift sequence and resets the state. On input
  //   the unshift sequence causes the state to be reset.
  //
  // The conversion for output is as follows:
  // 1. Calculate the value tmp by xor-ing the state and the internal
  //    character
  // 2. Split tmp into either two or three bytes depending on the value of
  //    state. Output those bytes.
  // 3. tmp becomes the new value of state.
  template<>
    class codecvt<__gnu_test::pod_uchar, char, __gnu_test::pod_state>
    : public __codecvt_abstract_base<__gnu_test::pod_uchar, char, 
				     __gnu_test::pod_state>
    {
    public:
      typedef codecvt_base::result	result;
      typedef __gnu_test::pod_uchar 	intern_type;
      typedef char 			extern_type;
      typedef __gnu_test::pod_state 	state_type;
      typedef __codecvt_abstract_base<intern_type, extern_type, state_type>
      base_type;

      explicit codecvt(size_t refs = 0) : base_type(refs)
      { }

      static locale::id id;

    protected:
      ~codecvt()
      { }

      virtual result
      do_out(state_type& state, const intern_type* from,
	     const intern_type* from_end, const intern_type*& from_next,
	     extern_type* to, extern_type* to_limit,
	     extern_type*& to_next) const
      {
	while (from < from_end && to < to_limit)
	  {
	    unsigned char tmp = (state.value ^ from->value);
	    if (state.value & 0x8)
	      {
		if (to >= to_limit - 2)
		  break;
		*to++ = (tmp & 0x7);
		*to++ = ((tmp >> 3) & 0x7);
		*to++ = ((tmp >> 6) & 0x3);
	      }
	    else
	      {
		if (to >= to_limit - 1)
		  break;
		*to++ = (tmp & 0xf);
		*to++ = ((tmp >> 4) & 0xf);
	      }
	    state.value = tmp;
	    ++from;
	  }

	from_next = from;
	to_next = to;
	return (from < from_end) ? partial : ok;
      }

      virtual result
      do_in(state_type& state, const extern_type* from,
	    const extern_type* from_end, const extern_type*& from_next,
	    intern_type* to, intern_type* to_limit,
	    intern_type*& to_next) const
      {
	while (from < from_end && to < to_limit)
	  {
	    unsigned char c = *from;
	    if (c & 0xc0)
	      {
		// Unshift sequence
		state.value &= c;
		++from;
		continue;
	      }

	    unsigned char tmp;
	    if (state.value & 0x8)
	      {
		if (from >= from_end - 2)
		  break;
		tmp = (*from++ & 0x7);
		tmp |= ((*from++ << 3) & 0x38);
		tmp |= ((*from++ << 6) & 0xc0);
	      }
	    else
	      {
		if (from >= from_end - 1)
		  break;
		tmp = (*from++ & 0xf);
		tmp |= ((*from++ << 4) & 0xf0);
	      }
	    to->value = (tmp ^ state.value);
	    state.value = tmp;
	    ++to;
	  }

	from_next = from;
	to_next = to;
	return (from < from_end) ? partial : ok;
      }

      virtual result
      do_unshift(state_type& state, extern_type* to, extern_type* to_limit,
		 extern_type*& to_next) const
      {
	for (unsigned int i = 0; i < CHAR_BIT; ++i)
	  {
	    unsigned int mask = (1 << i);
	    if (state.value & mask)
	      {
		if (to == to_limit)
		  {
		    to_next = to;
		    return partial;
		  }

		state.value &= ~mask;
		*to++ = static_cast<unsigned char>(~mask);
	      }
	  }

	to_next = to;
	return state.value == 0 ? ok : error;
      }

      virtual int
      do_encoding() const throw()
      { return -1; }

      virtual bool
      do_always_noconv() const throw()
      { return false; }

      virtual int
      do_length(state_type& state, const extern_type* from,
		const extern_type* end, size_t max) const
      {
	const extern_type* beg = from;
	while (from < end && max)
	  {
	    unsigned char c = *from;
	    if (c & 0xc0)
	      {
		// Unshift sequence
		state.value &= c;
		++from;
		continue;
	      }

	    unsigned char tmp;
	    if (state.value & 0x8)
	      {
		if (from >= end - 2)
		  break;
		tmp = (*from++ & 0x7);
		tmp |= ((*from++ << 3) & 0x38);
		tmp |= ((*from++ << 6) & 0xc0);
	      }
	    else
	      {
		if (from >= end - 1)
		  break;
		tmp = (*from++ & 0xf);
		tmp |= ((*from++ << 4) & 0xf0);
	      }
	    state.value = tmp;
	    --max;
	  }
	return from - beg;
      }

      // Maximum 8 bytes unshift sequence followed by max 3 bytes for
      // one character.
      virtual int
      do_max_length() const throw()
      { return 11; }
    };

  template<>
    class ctype<__gnu_test::pod_uchar>
    : public __ctype_abstract_base<__gnu_test::pod_uchar>
    {
    public:
      typedef __gnu_test::pod_uchar char_type;

      explicit ctype(size_t refs  = 0)
      : __ctype_abstract_base<__gnu_test::pod_uchar>(refs) { }

      static locale::id id;

    protected:
      ~ctype()
      { }

      virtual bool
      do_is(mask, char_type) const
      { return false; }

      virtual const char_type*
      do_is(const char_type* low, const char_type* high, mask* vec) const
      {
	fill_n(vec, high - low, mask());
	return high;
      }

      virtual const char_type*
      do_scan_is(mask, const char_type*, const char_type* high) const
      { return high; }

      virtual const char_type*
      do_scan_not(mask, const char_type* low, const char_type*) const
      { return low; }

      virtual char_type
      do_toupper(char_type c) const
      { return c; }

      virtual const char_type*
      do_toupper(char_type*, const char_type*  high) const
      { return high; }

      virtual char_type
      do_tolower(char_type c) const
      { return c; }

      virtual const char_type*
      do_tolower(char_type*, const char_type*  high) const
      { return high; }

      virtual char_type
      do_widen(char c) const
      { return __gnu_test::pod_uchar::from<char>(c); }

      virtual const char* 
      do_widen(const char* low, const char* high, char_type* dest) const
      {
	transform(low, high, dest, &__gnu_test::pod_uchar::from<char>);
	return high;
      }

      virtual char
      do_narrow(char_type, char dfault) const
      { return dfault; }

      virtual const char_type*
      do_narrow(const char_type* low, const char_type* high,
		char dfault, char*  dest) const
      {
	fill_n(dest, high - low, dfault);
	return high;
      }
    };

  // numpunct specializations
  template<> 
    class numpunct<__gnu_test::pod_uint>
    : public locale::facet
    { 
    public: 
      typedef __gnu_test::pod_uint    char_type; 
      typedef basic_string<char_type> string_type; 
    
      static locale::id id; 
      
      explicit
      numpunct(size_t refs = 0)
      : locale::facet(refs) 
      { } 
 
      char_type
      decimal_point() const 
      { return this->do_decimal_point(); } 
 
      char_type
      thousands_sep() const 
      { return this->do_thousands_sep(); } 
 
      string
      grouping() const 
      { return this->do_grouping(); } 
 
      string_type
      truename() const 
      { return this->do_truename(); } 
 
      string_type
      falsename() const 
      { return this->do_falsename(); } 
 
    protected: 
      ~numpunct()
      { } 
 
      virtual char_type
      do_decimal_point() const 
      { return char_type(); } 
 
      virtual char_type
      do_thousands_sep() const 
      { return char_type(); } 
 
      virtual string
      do_grouping() const 
      { return string(); } 
 
      virtual string_type
      do_truename() const 
      { return string_type(); }
 
      virtual string_type
      do_falsename() const 
      { return string_type(); } 
    };

  template<> 
    class moneypunct<__gnu_test::pod_uint>
    : public locale::facet, public money_base
    { 
    public: 
      typedef __gnu_test::pod_uint    char_type; 
      typedef basic_string<char_type> string_type; 
    
      static locale::id id; 
      static const bool intl = false;

      explicit
      moneypunct(size_t refs = 0)
      : locale::facet(refs) 
      { }
 
      char_type
      decimal_point() const 
      { return this->do_decimal_point(); } 
 
      char_type
      thousands_sep() const 
      { return this->do_thousands_sep(); }

      string
      grouping() const
      { return this->do_grouping(); }

      string_type
      curr_symbol() const 
      { return this->do_curr_symbol(); } 
 
      string_type
      positive_sign() const 
      { return this->do_positive_sign(); } 

      string_type
      negative_sign() const 
      { return this->do_negative_sign(); } 
      
      int
      frac_digits() const
      { return this->do_frac_digits(); }

      pattern
      pos_format() const
      { return this->do_pos_format(); }
 
      pattern
      neg_format() const
      { return this->do_neg_format(); }
  
    protected: 
      ~moneypunct() 
      { } 
 
      virtual char_type
      do_decimal_point() const 
      { return char_type(); } 
 
      virtual char_type
      do_thousands_sep() const 
      { return char_type(); } 
 
      virtual string
      do_grouping() const 
      { return string(); }

      virtual string_type
      do_curr_symbol() const 
      { return string_type(); } 
 
      string_type
      do_positive_sign() const 
      { return string_type(); } 

      string_type
      do_negative_sign() const 
      { return string_type(); } 
      
      int
      do_frac_digits() const
      { return 0; }

      pattern
      do_pos_format() const
      { return pattern(); }
 
      pattern
      do_neg_format() const
      { return pattern(); }
     };
} // namespace std

#endif // _GLIBCXX_TESTSUITE_CHARACTER_H

