//
// Copyright (C) 2008, 2009 Francesco Salvestrini
//
// This program 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 2 of the License, or
// (at your option) any later version.
//
// This program 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 program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//

#ifndef ELKLIB_LIBCXX_BITS_CHAR_TRAITS
#define ELKLIB_LIBCXX_BITS_CHAR_TRAITS

#include "elklib.h"

namespace ktl {

	typedef signed int char_traits_off_type;

	template<class charT> struct char_traits { };

	template<> struct char_traits<char> {
		typedef char                 char_type;
		typedef short int            int_type;
		typedef char_traits_off_type off_type;
		typedef char_traits_off_type pos_type;
		typedef char                 state_type;

		inline static void assign(char_type & c,
					  char_type & d) {
			c = d;
		}

		static bool eq(const char_type & c1,
			       const char_type & c2);

		static char_type to_char_type(const int_type & i);

		inline static int_type to_int_type(const char_type & c) {
			return (short int)(unsigned char) c;
		}

		inline static bool eq_int_type(const int_type & a,
					       const int_type & b) {
			if (a == b) {
				return true;
			}

			return false;
		}

		inline static bool lt(const char_type & c1,
				      const char_type & c2) {
			if (strncmp(&c1, &c2, 1) < 0) {
				return true;
			}
			return false;
		}

		inline static char_type * move(char_type *       s1,
					       const char_type * s2,
					       size_t            n) {
			return (char*) memmove(s1, s2, n);
		}

		inline static char_type * copy(char_type *       s1,
					       const char_type * s2,
					       size_t            n) {
			return strncpy(s1, s2, n);
		}

		inline static char_type* assign(char_type * s,
						size_t      n,
						char_type   a) {
			return (char *) memset(s, a, n);
		}

		inline static int compare(const char_type * s1,
					  const char_type * s2,
					  size_t            n) {
			return strncmp(s1, s2, n);
		}

		inline static size_t length(const char_type * s) {
			return strlen(s);
		}

		static const char_type * find(const char_type * s,
					      int               n,
					      const char_type & a);

		inline static char_type eos() {
			return 0;
		}

		inline static int_type eof() {
			return -1;
		}

		inline static int_type not_eof(const int_type & i) {
			if (i == -1) {
				return 0;
			}

			return i;
		}

		static state_type get_state(pos_type p) {
			p = p;
			state_type a;
			return a;
		}
	};
}

#endif // ELKLIB_LIBCXX_BITS_CHAR_TRAITS
