/* Copyright (c) 1997-2004
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de

   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, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   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.
*/

#ifndef _POLYMAKE_STD_HASH_ADAPTER_H
#define _POLYMAKE_STD_HASH_ADAPTER_H "$Project: polymake $$Id: hash_adapter.h,v 1.3 2004/06/22 16:22:42 gawrilow Exp $"

#ifdef __INTEL_COMPILER

#ifndef _POLYMAKE_COMPARATORS_H
#  include <comparators.h>
#endif

namespace std_ext {
   template <typename Key>
   struct hash {
      size_t operator() (const Key& k) const {
	 return std::hash_value(k);
      }
   };

   template <typename Key, typename HashFcn, typename EqualKey,
	     bool _reuse_cmp=pm::derived_from<EqualKey,pm::operations::cmp_based>::answer>
   class hash_compare
      : public std::hash_compare<Key, EqualKey> {
      typedef std::hash_compare<Key, EqualKey> super;
   protected:
      HashFcn hf;
   public:
      hash_compare() { }

      hash_compare(const HashFcn& hf_arg, const EqualKey& ek_arg)
	 : super(ek_arg), hf(hf_arg) { }

      size_t operator() (const Key& key) const {
	 return hf(key);
      }

      bool operator() (const Key& key1, const Key& key2) const {
	 typedef typename EqualKey::super cmp_super;
	 return (static_cast<const typename EqualKey::super&>(comp))(key1,key2)<0;
      }
   };

   template <typename Key, typename HashFcn, typename EqualKey>
   class hash_compare<Key, HashFcn, EqualKey, false>
      : public std::hash_compare<Key, pm::operations::cmp<const Key&, const Key&> > {
   protected:
      HashFcn hf;
      EqualKey ek;
   public:
      hash_compare() { }

      hash_compare(const HashFcn& hf_arg, const EqualKey& ek_arg)
	 : hf(hf_arg), ek(ek_arg) { }

      size_t operator() (const Key& key) const {
	 return hf(key);
      }

      bool operator() (const Key& key1, const Key& key2) const {
	 return !ek(key1,key2) && comp(key1,key2)<0;
      }
   };
} // end namespace std_ext

#else // ! __INTEL_COMPILER

#include <string>

namespace std_ext {
   template <typename _Traits, typename _Alloc>
   struct hash< std::basic_string<char,_Traits,_Alloc> > : hash<const char*> {
      size_t operator() (const std::basic_string<char,_Traits,_Alloc>& s) const {
	 return hash<const char*>::operator() (s.c_str());
      }
   };
} // end namespace std_ext

#endif // ! __INTEL_COMPILER

namespace std_ext {
   template <typename T>
   struct hash<T*> {
      size_t operator() (T* x) const { return reinterpret_cast<size_t>(x); }
   };
}
#endif // _POLYMAKE_STD_HASH_ADAPTER_H

// Local Variables:
// mode:C++
// End:
