// TR1 unordered_set -*- C++ -*-

// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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.

// This library 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 library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.

/** @file 
 *  This is a TR1 C++ Library header. 
 */

#ifndef GNU_LIBSTDCXX_TR1_UNORDERED_SET_
#define GNU_LIBSTDCXX_TR1_UNORDERED_SET_

#include <tr1/hashtable>
#include <tr1/functional>
#include <memory>

namespace std { namespace tr1 {

// XXX When we get typedef templates these class definitions will be unnecessary.

template <class Value,
	  class Hash = hash<Value>,
	  class Pred = std::equal_to<Value>,
	  class Alloc = std::allocator<Value>,
	  bool cache_hash_code = false>
class unordered_set
  : public hashtable <Value, Value, Alloc,
		      Internal::identity<Value>, Pred,
		      Hash, Internal::mod_range_hashing, Internal::default_ranged_hash,
		      Internal::prime_rehash_policy,
		      cache_hash_code, false, true>
{
  typedef hashtable <Value, Value, Alloc,
		      Internal::identity<Value>, Pred,
		      Hash, Internal::mod_range_hashing, Internal::default_ranged_hash,
		      Internal::prime_rehash_policy,
		      cache_hash_code, false, true>
          Base;

public:
  typedef typename Base::size_type size_type;
  typedef typename Base::hasher hasher;
  typedef typename Base::key_equal key_equal;
  typedef typename Base::allocator_type allocator_type;

  explicit unordered_set(size_type n = 10,
			 const hasher& hf = hasher(),
			 const key_equal& eql = key_equal(),
			 const allocator_type& a = allocator_type())
    : Base (n,
	    hf, Internal::mod_range_hashing(), Internal::default_ranged_hash(),
	    eql, Internal::identity<Value>(),
	    a)
  { }

  template <typename InputIterator>
  unordered_set(InputIterator f, InputIterator l, 
		size_type n = 10,
		const hasher& hf = hasher(), 
		const key_equal& eql = key_equal(), 
		const allocator_type& a = allocator_type())
    : Base (f, l,
	    n,
	    hf, Internal::mod_range_hashing(), Internal::default_ranged_hash(),
	    eql, Internal::identity<Value>(),
	    a)
	    { }
};

template <class Value,
	  class Hash = hash<Value>,
	  class Pred = std::equal_to<Value>,
	  class Alloc = std::allocator<Value>,
	  bool cache_hash_code = false>
class unordered_multiset
  : public hashtable <Value, Value, Alloc,
		      Internal::identity<Value>, Pred,
		      Hash, Internal::mod_range_hashing, Internal::default_ranged_hash,
		      Internal::prime_rehash_policy,
		      cache_hash_code, false, false>
{
  typedef hashtable <Value, Value, Alloc,
		      Internal::identity<Value>, Pred,
		      Hash, Internal::mod_range_hashing, Internal::default_ranged_hash,
		      Internal::prime_rehash_policy,
		      cache_hash_code, false, false>
          Base;

public:
  typedef typename Base::size_type size_type;
  typedef typename Base::hasher hasher;
  typedef typename Base::key_equal key_equal;
  typedef typename Base::allocator_type allocator_type;

  explicit unordered_multiset(size_type n = 10,
			      const hasher& hf = hasher(),
			      const key_equal& eql = key_equal(),
			      const allocator_type& a = allocator_type())
    : Base (n,
	    hf, Internal::mod_range_hashing(), Internal::default_ranged_hash(),
	    eql, Internal::identity<Value>(),
	    a)
  { }


  template <typename InputIterator>
  unordered_multiset(InputIterator f, InputIterator l, 
		     typename Base::size_type n = 0,
		     const hasher& hf = hasher(), 
		     const key_equal& eql = key_equal(), 
		     const allocator_type& a = allocator_type())
    : Base (f, l,
	    n,
	    hf, Internal::mod_range_hashing(), Internal::default_ranged_hash(),
	    eql, Internal::identity<Value>(),
	    a)
  { }
};

template <class Value, class Hash, class Pred, class Alloc, bool cache_hash_code>
inline void swap (unordered_set<Value, Hash, Pred, Alloc, cache_hash_code>& x,
		  unordered_set<Value, Hash, Pred, Alloc, cache_hash_code>& y)
{
  x.swap(y);
}

template <class Value, class Hash, class Pred, class Alloc, bool cache_hash_code>
inline void swap (unordered_multiset<Value, Hash, Pred, Alloc, cache_hash_code>& x,
		  unordered_multiset<Value, Hash, Pred, Alloc, cache_hash_code>& y)
{
  x.swap(y);
}

} }

#endif /* GNU_LIBSTDCXX_TR1_UNORDERED_SET_ */
