/*  This header file defines fundamental type operations
    like functors. */

#ifndef BASICTYPE_HH_
#define BASICTYPE_HH_
#include <config.h>
#include <string>
#include <utility>
#include <functional>
#include <algorithm>
#include <string.h>
#include <stdlib.h>

//
// Usuful functors
//
struct Functor_strcmp {
    bool operator()(const char* s1, const char* s2) const
    {
	return strcmp(s1, s2) < 0;
    }
};

// Delete/Destroy all members.

struct Functor_deleteobject {
    template <typename Key, typename T>
    bool operator()(const std::pair<const Key, T*>& cp) const
    {
	delete cp.second;
	return true;
    }
    template <typename T>
    bool operator()(const T* p) const
    {
	delete p;
	return true;
    }
};

// Delete all pointers of the container.
template <typename T>
void delete_all(T &x)
{
    for_each(x.begin(), x.end(), Functor_deleteobject());
}

struct Functor_destroyobject {
    template <typename Key, typename T>
    bool operator()(std::pair<const Key, T*>& cp) const
    {
	cp.second->destroy();
	return true;
    }
    template <typename T>
    bool operator()(T* p) const
    {
	p->destroy();
	return true;
    }
};

// Call destroy() for all pointers of the container.
template <typename T>
void destroy_all(T &x)
{
    for_each(x.begin(), x.end(), Functor_destroyobject());
}


//
// UTF-16 string.
//

typedef CARD16BIT UTFCHAR;

// char_traits for u16string.
struct UTFCHAR_char_traits {
    typedef UTFCHAR char_type;
    typedef unsigned long int_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)
    { return memcmp(s1, s2, n); }
    static size_t length(const char_type* s)
    { 
	int i;
	for (i = 0; *s; s++, i++);
	return i;
    }
    static const char_type* find(const char_type* s, size_t n, const char_type& a)
    {
	int i;
	for (i = 0; (i < n); s++, i++) {
	    if (*s == a) return s;
	}
	return NULL;
    }
    static char_type* move(char_type* s1, const char_type* s2, size_t n)
    { return (char_type*) memmove(s1, s2, n * sizeof(char_type)); }
    static char_type* copy(char_type* s1, const char_type* s2, size_t n)
    { return (char_type*) memcpy(s1, s2, n * sizeof(char_type)); }
    static char_type* assign(char_type* s, size_t n, const char_type& a)
    { 
	for (int i = 0; i < n; i++) s[i] = a;
	return s;
    }
    static char_type to_char_type(const int_type& i)
    { return (char_type) i; }
    static int_type to_int_type(const char_type& ch)
    { return (int_type) ch; }
    static bool eq_int_type(const int_type& i1, const int_type& i2)
    { return i1 == i2; }
    static int_type eof()
    { return (int_type) EOF; }
    static int_type not_eof(const int_type& i)
    { return (i == eof()) ? 0 : i; }

    // obsolete string_char_traits method.
    static char_type* set(char_type* s, const char_type& c, size_t num)
    { return assign(s, num, c); }
};

// Prohibit implicit conversion from u16string to basic_string,
// make the base class private.
class u16string : private std::basic_string<UTFCHAR, UTFCHAR_char_traits>
{
    typedef std::basic_string<UTFCHAR, UTFCHAR_char_traits> BaseClass;
    enum CHARSTR_STATE {
	    UNINIT,
	    VALID,
	    INVALID
    } state;
    std::string charstr;
    void set_charstr()
    {
	size_type size = BaseClass::size();
	charstr = std::string(size, 0);
	BaseClass::iterator it_s = begin();
	std::string::iterator it_d = charstr.begin();
	for (; it_s != end(); it_s++, it_d++) {
	    if (*it_s > 0x7F) {
		state = INVALID;
		return;
	    }
	    *it_d = (char) *it_s;
	}
	state = VALID;
	return;
    }

  public:
    // basic_string public functions
    typedef BaseClass::iterator iterator;
    typedef BaseClass::const_iterator const_iterator;
    typedef BaseClass::reverse_iterator reverse_iterator;
    typedef BaseClass::const_reverse_iterator const_reverse_iterator;

    BaseClass::npos;
    BaseClass::size;
    BaseClass::begin;
    BaseClass::end;
    BaseClass::empty;
    BaseClass::data;
    BaseClass::c_str;

    int compare(const u16string& s) const
    { return this->BaseClass::compare(s); }
    size_type find(UTFCHAR c, size_type pos = 0) const
    { return this->BaseClass::find(c, pos); }
    size_type find(const u16string& s, size_type pos = 0) const
    { return this->BaseClass::find(s, pos); }

    u16string substr(size_type pos = 0, size_type n = npos) const
    { return u16string(*this, pos, n); }

  public:
    // u16string original extension.

    const char* get_charstr() const
    {
	if (state != VALID) return NULL;
	return charstr.c_str();
    }
    const std::string* get_string() const
    {
	if (state != VALID) return NULL;
	return &charstr;
    }
    u16string() : BaseClass()
    {
	charstr = "";
	state = VALID;
    }
    u16string(UTFCHAR *str) : BaseClass(str)
    {
	set_charstr();
    }
    u16string(UTFCHAR *str, size_type n) : BaseClass(str, n)
    {
	set_charstr();
    }
    u16string(const u16string& str, size_type pos, size_type n)
	: BaseClass(str, pos, n)
    {
	set_charstr();
    }
 
    u16string(const char *cstr)
	: BaseClass(strlen(cstr), 0)
    {
	const char *p;
	BaseClass::iterator it = begin();
	charstr = cstr;
	state = VALID;
	for (p = cstr; *p; p++, it++) {
	    *it = *p;
	}
    }
    u16string(const std::string& s)
	: BaseClass(s.size(), 0)
    {
	int i;
	int n = s.size();
	BaseClass::iterator it = begin();
	std::string::const_iterator its = s.begin();
	charstr = s;
	state = VALID;
	for (i = 0; i < n; i++, it++, its++) {
	    *it = (UTFCHAR) *its;
	}
    }
};

inline bool
operator< (
    const u16string& lhs,
    const u16string& rhs
)
{
  return (lhs.compare (rhs) < 0);
}

inline bool
operator== (
    const u16string& lhs,
    const u16string& rhs
)
{
  return (lhs.compare (rhs) == 0);
}

//sigh...
using namespace std;

#endif /* not BASICTYPE_HH_ */

/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */

