#ifndef _STDEX_HASHSET_H_
#define _STDEX_HASHSET_H_
/***************************************************************************
 *
 * declaration for STL-like set based on hash table
 *
 * $Id: hashset.h,v 7.8 1996/02/19 12:34:12 jims Exp $
 *
 * (c) Copyright 1989 - 1996 Rogue Wave Software, Inc.
 * ALL RIGHTS RESERVED
 *
 * The software and information contained herein are proprietary to, and
 * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
 * intends to preserve as trade secrets such software and information.
 * This software is furnished pursuant to a written license agreement and
 * may be used, copied, transmitted, and stored only in accordance with
 * the terms of such license and with the inclusion of the above copyright
 * notice.  This software and information or any other copies thereof may
 * not be provided or otherwise made available to any other person.
 *
 * Notwithstanding any other lease or license that may pertain to, or
 * accompany the delivery of, this computer software and information, the
 * rights of the Government regarding its use, reproduction and disclosure
 * are as set forth in Section 52.227-19 of the FARS Computer
 * Software-Restricted Rights clause.
 * 
 * Use, duplication, or disclosure by the Government is subject to
 * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
 * Technical Data and Computer Software clause at DFARS 252.227-7013.
 * Contractor/Manufacturer is Rogue Wave Software, Inc.,
 * P.O. Box 2328, Corvallis, Oregon 97339.
 *
 * This computer software and information is distributed with "restricted
 * rights."  Use, duplication or disclosure is subject to restrictions as
 * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
 * Computer Software-Restricted Rights (April 1985)."  If the Clause at
 * 18-52.227-74 "Rights in Data General" is specified in the contract,
 * then the "Alternate III" clause applies.
 *
 ***************************************************************************
 *
 * $Log: hashset.h,v $
 * Revision 7.8  1996/02/19 12:34:12  jims
 * Port to Stdlib 1.2
 *
 * Revision 7.7  1996/02/07 02:42:30  jims
 * Standard library extensions now in directory rw/stdex
 *
 * Revision 7.6  1995/09/25 11:05:22  jims
 * Remove duplicate declarations of key_hash_type, key_equal_type
 *
 * Revision 7.5  1995/09/21  00:20:55  griswolf
 * Provide more consistent typedefs.
 *
 * Revision 7.4  1995/09/12  18:12:58  griswolf
 * Move contents to this filename.
 *
 * Revision 7.3  1995/09/05  19:38:52  jims
 * Update header section
 *
 * Revision 7.2  1995/08/31  12:03:51  jims
 * next rev
 *
 * Revision 7.1  1995/08/29  09:16:50  jims
 * Port to sgi and Borland
 *
 * Revision 1.1  1995/08/28  22:12:03  griswolf
 * Initial revision
 *
 */

#include <memory>
#include <assert.h>
#include "rw/stdex/lhash.h"

template <class T, class Hash, class EQ> //, class Allocator>
class rw_hashset  {
public:
///// typdefs /////
  typedef T				key_type;
  typedef T				value_type;
  typedef Hash			key_hash_type;
  typedef EQ				key_equal_type;
  typedef LHashTable<T,Hash,EQ>		impl_type;
  typedef impl_type::const_reference	reference;
  typedef impl_type::const_reference	const_reference;
  typedef impl_type::const_iterator	iterator;
  typedef impl_type::const_iterator	const_iterator;
  typedef impl_type::size_type		size_type;
  typedef impl_type::difference_type	difference_type;

  // see "lhash.h" for comments on key_compare:
  typedef impl_type::key_compare	key_compare;
  key_compare key_comp()                { return key_compare(); }

  key_hash_type key_hash()		{ return impl.key_hash(); }
  key_equal_type key_equal()		{ return impl.key_equal(); }

///// constructors /////
  rw_hashset(
	     size_type sz=1024,
	     const Hash& h = Hash(), const EQ& eq=EQ()
	     )
    : impl(sz,h,eq) {}

  rw_hashset(const rw_hashset<T,Hash,EQ>& arg) : impl(arg.impl) {}

  rw_hashset(const value_type* first, const value_type* bound,
	     size_type sz=1024, const Hash& h = Hash(), const EQ& eq=EQ()
	     );

  rw_hashset(const_iterator first, const_iterator bound,
	     size_type sz=1024, const Hash& h = Hash(), const EQ& eq=EQ()
	    );

  ~rw_hashset() {} // mainly to document no (non-impl) action

///// operators ////
  rw_hashset<T,Hash,EQ>&
    operator=(const rw_hashset<T,Hash,EQ>& t)
  { impl = t.impl; return *this; }

  bool
    operator==(const rw_hashset<T,Hash,EQ>& t) const
  { return impl == t.impl; }

/*
 * Not to be used.  Present only to appease overacheiving compilers (the
 * ones that compile all member functions whether used or not).
 */
  bool
    operator<(const rw_hashset<T,Hash,EQ>&) const
  { assert(false); return false; }
    
///// various public methods ////
  iterator
    begin() const { return impl.begin(); }

  iterator
    end() const { return impl.end(); }

  bool
    empty() const { return impl.empty(); }

  size_type
    size() const { return impl.size(); }

  size_type
    count(const_reference key) const
    { return impl.find(key) == impl.end() ? 0 : 1; }

  iterator
    find(const_reference key) const { return impl.find(key); }

  iterator
    lower_bound(const_reference key) const { return impl.lower_bound(key); }

  iterator
    upper_bound(const_reference key) const { return impl.upper_bound(key); }

  pair<iterator,iterator>
    equal_range(const_reference key) const { return impl.equal_range(key); }

  size_type
    capacity() const { return impl.capacity(); }

  float
    fill_ratio() const { return impl.fill_ratio(); }

  void
    resize(size_type s) { impl.resize(s); }

  void
    swap(rw_hashset<T,Hash,EQ>& t) { impl.swap(t.impl); }

///// insertion and erasure ////

  pair<iterator,bool>
    insert(const_reference k)
{
  impl_type::Iterator itr;
  bool fits = impl.insertMaybe(k,itr,true);
  return pair<rw_hashset<T,Hash,EQ>::iterator,bool> (iterator(itr),fits);
}


  iterator
    insert(iterator hint, const_reference);

  size_type
    insert(const value_type* first, const value_type* bound)
    { impl_type::Iterator dum; return impl.insertMaybe(first,bound,dum,true); }

  size_type
    insert(const_iterator first, const_iterator bound)
    { impl_type::Iterator dum; return impl.insertMaybe(first,bound,dum,true); }

  size_type
    erase(const_reference t) { return impl.erase(t); }

  iterator
    erase(iterator it) { return impl.erase(it); }

  iterator
    erase(iterator it, iterator bound) { return impl.erase(it,bound); }

  void clear() { impl.clear(); }

  void idump() { impl.idump(); }

private:
  LHashTable<T,Hash,EQ> impl;
};

#ifdef RW_COMPILE_INSTANTIATE
#include "rw/stdex/hashset.cc"
#endif

#endif /* _STDEX_HASHSET_H_ */
