#ifndef EINTHASHOF_DEC_H
#define EINTHASHOF_DEC_H

#include "eutils.h"
#include "earray_dec.h"
#include "ebasearrayof.h"
#include "ehashmap_dec.h"


template <class T>
class einthashof : public ebasearrayof
{
  mutable ehashitem<unsigned int,T> **_hashitems;
  size_t count;
 public:
  mutable size_t _hashcount;

  einthashof();
  einthashof(const einthashof<T>& oldhm);
  ~einthashof();

  inline size_t size() const { return(count); }

//  void add(const T& value);
  T& add(unsigned int key,const T& value);
  T& addref(unsigned int key,T* value);

  inline const T& operator[](unsigned int key) const;
//  const T& operator[](int i) const;
  T& operator[](unsigned int key);
//  T& operator[](int i);

  einthashof<T>& operator+=(const einthashof<T>& hm);


  T& values(unsigned int key);
  const T& values(unsigned int key) const;

  bool exists(unsigned int key) const ;
  long findkey(unsigned int key,size_t pos=0) const;

  void clear();
  void resizehash(size_t i=0) const;

  void reserve(size_t i);

  void remove(unsigned int key);

  void erase(size_t key);

  ehashitem<unsigned int,T>* gethashitem(unsigned int key) const;

  void addvar(evar& var);
  void addvar(evar& key,evar& var);
  evar getvar(size_t i) const;
  evar getvarkey(size_t i) const;
  evar getvarByKey(const evar& var) const;

  class iter
  {
   public:
    const einthashof<T> *hashmap;
    ehashitem<unsigned int,T> *hitem;
    size_t  bucket;

    iter();

    iter& operator++();
 
    unsigned int key() const;
    T& value() const;

    T& operator*() const;
    T* operator->() const;

    bool operator==(const iter& i) const;
    bool operator!=(const iter& i) const;

    iter& operator=(const iter& i);
  };

  void erase(const typename einthashof<T>::iter&);
  typename einthashof<T>::iter get(unsigned int key) const;
  typename einthashof<T>::iter begin() const;
  typename einthashof<T>::iter end() const;
};

template <class T>
class elonghashof : public ebasearrayof
{
	mutable ehashitem<unsigned long, T> **_hashitems;
	size_t count;
public:
	mutable size_t _hashcount;

	elonghashof();
	elonghashof(const elonghashof<T>& oldhm);
	~elonghashof();

	inline size_t size() const { return(count); }

	//  void add(const T& value);
	T& add(unsigned long key, const T& value);
	T& addref(unsigned long key, T* value);

	inline const T& operator[](unsigned long key) const;
	//  const T& operator[](int i) const;
	T& operator[](unsigned long key);
	//  T& operator[](int i);

	elonghashof<T>& operator+=(const elonghashof<T>& hm);


	T& values(unsigned long key);
	const T& values(unsigned long key) const;

	bool exists(unsigned long key) const;
	long findkey(unsigned long key, size_t pos = 0) const;

	void clear();
	void resizehash(size_t i = 0) const;

	void reserve(size_t i);

	void remove(unsigned long key);

	void erase(size_t key);

	ehashitem<unsigned long, T>* gethashitem(unsigned long key) const;

	void addvar(evar& var);
	void addvar(evar& key, evar& var);
	evar getvar(size_t i) const;
	evar getvarkey(size_t i) const;
	evar getvarByKey(const evar& var) const;

	class iter
	{
	public:
		const elonghashof<T> *hashmap;
		ehashitem<unsigned long, T> *hitem;
		size_t  bucket;

		iter();

		iter& operator++();

		unsigned long key() const;
		T& value() const;

		T& operator*() const;
		T* operator->() const;

		bool operator==(const iter& i) const;
		bool operator!=(const iter& i) const;

		iter& operator=(const iter& i);
	};

	void erase(const typename elonghashof<T>::iter&);
	typename elonghashof<T>::iter get(unsigned long key) const;
	typename elonghashof<T>::iter begin() const;
	typename elonghashof<T>::iter end() const;
};

#endif

