#ifndef __ITG_TYPES_H
#define __ITG_TYPES_H

#include <string.h>

#if (__GNUC__<3)
#include <stl_hash_fun.h> 
#include <hash_map> 
#define BEGIN_HASH_NAMESPACE
#define END_HASH_NAMESPACE
#elif (__GNUC__<4 || __GNUC_MINOR__<1)
#include <ext/hash_map> 	// for GCC 3, also works for 4.1
using namespace __gnu_cxx;
using __gnu_cxx::hash;
#define BEGIN_HASH_NAMESPACE namespace __gnu_cxx {
#define END_HASH_NAMESPACE }
#else
#include <tr1/unordered_map>	// for GCC 4.3  -  hash_map is deprecated
#define hash_map unordered_map
using namespace std::tr1;
#define BEGIN_HASH_NAMESPACE namespace std { namespace tr1 {
#define END_HASH_NAMESPACE } }
#endif	// GCC 4

using namespace std;


#if (__GNUC__<4 || __GNUC_MINOR__<1)
struct hash_string {
  size_t operator()(const string& s) const {
    __gnu_cxx::hash<const char*> hh;		// hash string contents
    return hh(s.c_str());
  }
};
#else
typedef hash<string> hash_string;		// hash string contents
#endif

struct eq_string { 
  bool operator()(const string &s1, const string &s2) const { 
    return s1 == s2; 
  } 
}; 
struct eqstr { 
  bool operator()(const char* s1, const char* s2) const { 
    return strcmp(s1, s2) == 0; 
  } 
}; 
struct eqst { 
  bool operator()(const char* s1, const char* s2) const { 
    return s1 == s2; 
  } 
}; 
struct eqint { 
  bool operator()(int i1, int i2) const { 
    return i1 == i2; 
  } 
}; 
struct ltint { 
  bool operator()(int i1, int i2) const { 
    return i1 < i2; 
  } 
};

typedef class hash_map<string,float,hash_string,eq_string> string_float_hash;
typedef class hash_map<const string,double,hash_string,eq_string> string_double_hash;
typedef class hash_map<string,unsigned short,hash_string,eq_string> string_bool_hash;
//typedef hash_map<Set,string_float_hash,hash_set,eq_set> set_string_float_hash;
//typedef hash_map<Set,string_bool_hash,hash_set,eq_set> set_string_bool_hash;
typedef hash_map<string, int, hash_string, eq_string> string_int_hash;
typedef string_double_hash::iterator string_double_hash_iter;
typedef hash_map<string, string_double_hash, hash_string, eq_string> string_string_double_hash;
typedef hash_map<int, double> int_double_hash;
typedef hash_map<string, int_double_hash, hash_string, eq_string> string_int_double_hash;

typedef class hash_map<string, int, hash_string, eq_string> string_int_hash; 
typedef class hash_map<string, string, hash_string, eq_string> string_string_hash; 
typedef class hash_map<string,float,hash_string, eq_string> string_float_hash; 
typedef class hash_map<string,unsigned short,hash_string, eq_string> string_bool_hash; 
typedef class hash_map<int, string, hash<int>, eqint> int_string_hash; 
typedef class hash_map<char*, int, hash<char*>, eqstr> str_int_hash; 
typedef class hash_map<char*, float, hash<char*>, eqstr> str_float_hash; 
typedef class hash_map<char*, unsigned short, hash<char*>, eqstr> str_bool_hash;
typedef class hash_map<char*, int, hash<char*>, eqst> st_int_hash; 


typedef class hash_map<int, int, hash<int>, eqint> int_int_hash;
typedef class hash_map<int, int_int_hash, hash<int>, eqint> int_int_int_hash;
typedef class hash_map<char*, int_int_hash, hash<char*>, eqst> st_int_int_hash; 

typedef class hash_map<string, string_int_hash, hash_string, eq_string> string_string_int_hash; 
typedef class hash_map<string, int_int_hash, hash_string, eq_string> string_int_int_hash; 

typedef class hash_map<string,float,hash_string, eq_string> string_float_hash; 
typedef class hash_map<string,unsigned short,hash_string, eq_string> string_bool_hash; 
typedef class hash_map<int, string, hash<int>, eqint> int_string_hash; 
typedef class hash_map<char*, int, hash<char*>, eqstr> str_int_hash; 
typedef class hash_map<char*, int, hash<char*>, eqst> st_int_hash; 


typedef class hash_map<int, int, hash<int>, eqint> int_int_hash;
typedef int_int_hash::iterator int_int_hash_iter;
typedef class hash_map<char*, int_int_hash, hash<char*>, eqst> st_int_int_hash; 

typedef class hash_map<string, string_int_hash, hash_string, eq_string> string_string_int_hash; 
typedef class hash_map<string, int_int_hash, hash_string, eq_string> string_int_int_hash; 

#endif
