/* Metrowerks Standard Library
 * Copyright  1995-2004 Metrowerks Corporation.  All rights reserved.
 *
 * $Date: 2004/06/15 14:11:55 $
 * $Revision: 1.16.2.1 $
 */

// hash_map

#ifndef _HASH_MAP
#define _HASH_MAP

/*
	WARNING - WARNING - WARNING

	This header is NON-STANDARD

	The classes herein are offered as extensions to the C++ standard.
	They are marked as such by the namespace Metrowerks.
*/

/*  hash_map synopsis

namespace Metrowerks
{

template <class Key, class T, class Hash = hash<Key>, class Compare = std::equal_to<Key>,
          class Allocator = std::allocator<std::pair<const Key, T> > >
class hash_map
{
public:
	//  types:
	typedef Key                                   key_type;
	typedef T                                     mapped_type;
	typedef std::pair<const Key, T>               value_type;
	typedef Hash                                  key_hasher;
	typedef Compare                               key_compare;
	typedef Allocator                             allocator_type;
	typedef typename Allocator::reference         reference;
	typedef typename Allocator::const_reference   const_reference;
	typedef typename Allocator::size_type         size_type;
	typedef typename Allocator::difference_type   difference_type;
	typedef typename Allocator::pointer           pointer;
	typedef typename Allocator::const_pointer     const_pointer;

	class value_hasher
	{
	public:
		typedef value_type argument_type;
		typedef size_type  result_type;

		size_type operator()(const value_type& x) const;
		size_type operator()(const key_type& x) const;
	};

	class value_compare
	{
	public:
	public:
		typedef value_type first_argument_type;
		typedef value_type second_argument_type;
		typedef bool       result_type;

		bool operator()(const value_type& x, const value_type& y) const;
		bool operator()(const key_type& x,   const value_type& y) const;
		bool operator()(const value_type& x, const key_type& y) const;
	};

	class                   iterator;  // forward
	class             const_iterator;  // forward

	//  construct/copy/destroy:
	explicit hash_map(size_type num_buckets = 0,
	                  const key_hasher& hash = key_hasher(),
	                  const key_compare& comp = key_compare(),
	                  float load_factor_limit = 2,
	                  float growth_factor = 4,
	                  const allocator_type& a = allocator_type());

	template <class InputIterator>
	hash_map(InputIterator first, InputIterator last,
	         size_type num_buckets = 0,
	         const key_hasher& hash = key_hasher(),
	         const key_compare& comp = key_compare(),
	         float load_factor_limit = 2,
	         float growth_factor = 4,
	         const allocator_type& a = allocator_type());

	hash_map(const hash_map&);
	hash_map& operator =(const hash_map&);
	~hash_map();

	allocator_type get_allocator() const;
	size_type max_size() const;

	size_type size() const;
	bool      empty() const;
	size_type bucket_count() const;
	size_type bucket_count(size_type num_buckets);
	float     load_factor() const;
	void      load_factor_limit(float lf);
	float     load_factor_limit() const;
	void      growth_factor(float gf);
	float     growth_factor() const;
	size_type collision(const_iterator i) const;

	iterator       begin();
	const_iterator begin() const;
	iterator       end();
	const_iterator end() const;

	mapped_type& operator[](const key_type& x);

	std::pair<iterator, bool> insert(const value_type& x);
	iterator                  insert(iterator, const value_type& x);
	template <class InputIterator>
		void                  insert(InputIterator first, InputIterator last);

	void      erase(iterator position);
	size_type erase(const key_type& x);
	void      erase(iterator first, iterator last);
	void clear();

	void        swap(hash_map& y);
	friend void swap(hash_map& x, hash_map& y);

	key_compare   key_comp() const;
	value_compare value_comp() const;
	key_hasher    key_hash() const;
	value_hasher  value_hash() const;

	iterator       find(const key_type& x);
	const_iterator find(const key_type& x) const;
	size_type      count(const key_type& x) const;

	std::pair<iterator, iterator>             equal_range(const key_type& x);
	std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const;

	bool invariants() const;
};

template <class Key, class T, class Hash, class Compare, class Allocator>
bool
operator==(const hash_map<Key, T, Hash, Compare, Allocator>& x,
           const hash_map<Key, T, Hash, Compare, Allocator>& y);

template <class Key, class T, class Hash, class Compare, class Allocator>
bool
operator!=(const hash_map<Key, T, Hash, Compare, Allocator>& x,
           const hash_map<Key, T, Hash, Compare, Allocator>& y);

template <class Key, class T, class Hash = hash<Key>, class Compare = std::equal_to<Key>,
          class Allocator = std::allocator<std::pair<const Key, T> > >
class hash_multimap
{
public:
	//  types:
	typedef Key                                   key_type;
	typedef T                                     mapped_type;
	typedef std::pair<const Key, T>               value_type;
	typedef Hash                                  key_hasher;
	typedef Compare                               key_compare;
	typedef Allocator                             allocator_type;
	typedef typename Allocator::reference         reference;
	typedef typename Allocator::const_reference   const_reference;
	typedef typename Allocator::size_type         size_type;
	typedef typename Allocator::difference_type   difference_type;
	typedef typename Allocator::pointer           pointer;
	typedef typename Allocator::const_pointer     const_pointer;

	class value_hasher
	{
	public:
		typedef value_type argument_type;
		typedef size_type  result_type;

		size_type operator()(const value_type& x) const;
		size_type operator()(const key_type& x) const;
	};

	class value_compare
	{
	public:
	public:
		typedef value_type first_argument_type;
		typedef value_type second_argument_type;
		typedef bool       result_type;

		bool operator()(const value_type& x, const value_type& y) const;
		bool operator()(const key_type& x,   const value_type& y) const;
		bool operator()(const value_type& x, const key_type& y) const;
	};

	class                   iterator;  // forward
	class             const_iterator;  // forward

	//  construct/copy/destroy:
	explicit hash_multimap(size_type num_buckets = 0,
	                       const key_hasher& hash = key_hasher(),
	                       const key_compare& comp = key_compare(),
	                       float load_factor_limit = 2,
	                       float growth_factor = 4,
	                       const allocator_type& a = allocator_type());

	template <class InputIterator>
	hash_multimap(InputIterator first, InputIterator last,
	              size_type num_buckets = 0,
	              const key_hasher& hash = key_hasher(),
	              const key_compare& comp = key_compare(),
	              float load_factor_limit = 2,
	              float growth_factor = 4,
	              const allocator_type& a = allocator_type());

	hash_multimap(const hash_multimap&);
	hash_multimap& operator =(const hash_multimap&);
	~hash_multimap();

	allocator_type get_allocator() const;
	size_type max_size() const;

	size_type size() const;
	bool      empty() const;
	size_type bucket_count() const;
	size_type bucket_count(size_type num_buckets);
	float     load_factor() const;
	void      load_factor_limit(float lf);
	float     load_factor_limit() const;
	void      growth_factor(float gf);
	float     growth_factor() const;
	size_type collision(const_iterator i) const;

	iterator       begin();
	const_iterator begin() const;
	iterator       end();
	const_iterator end() const;

	iterator insert(const value_type& x);
	iterator insert(iterator, const value_type& x);
	template <class InputIterator>
		void insert(InputIterator first, InputIterator last);

	void      erase(iterator position);
	size_type erase(const key_type& x);
	void      erase(iterator first, iterator last);
	void clear();

	void        swap(hash_multimap& y);
	friend void swap(hash_multimap& x, hash_multimap& y);

	key_compare   key_comp() const;
	value_compare value_comp() const;
	key_hasher    key_hash() const;
	value_hasher  value_hash() const;

	iterator       find(const key_type& x);
	const_iterator find(const key_type& x) const;
	size_type      count(const key_type& x) const;

	std::pair<iterator, iterator>             equal_range(const key_type& x);
	std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const;

	bool invariants() const;
};

template <class Key, class T, class Hash, class Compare, class Allocator>
bool
operator==(const hash_multimap<Key, T, Hash, Compare, Allocator>& x,
           const hash_multimap<Key, T, Hash, Compare, Allocator>& y);

template <class Key, class T, class Hash, class Compare, class Allocator>
bool
operator!=(const hash_multimap<Key, T, Hash, Compare, Allocator>& x,
           const hash_multimap<Key, T, Hash, Compare, Allocator>& y);

}  // Metrowerks
*/

#include <mslconfig>
#include <hash_table>
#include <algorithm>

#ifndef RC_INVOKED

#ifdef __MWERKS__
#pragma options align=native
#endif

#ifdef _MSL_FORCE_ENUMS_ALWAYS_INT
	#if _MSL_FORCE_ENUMS_ALWAYS_INT
		#pragma enumsalwaysint on
	#else
		#pragma enumsalwaysint off
	#endif
#endif  // _MSL_FORCE_ENUMS_ALWAYS_INT

#ifdef _MSL_FORCE_ENABLE_BOOL_SUPPORT
	#if _MSL_FORCE_ENABLE_BOOL_SUPPORT
		#pragma bool on
	#else
		#pragma bool off
	#endif
#endif  // _MSL_FORCE_ENABLE_BOOL_SUPPORT

#ifndef _MSL_NO_CPP_NAMESPACE
	namespace Metrowerks {
#else
	#ifndef Metrowerks
		#define Metrowerks
	#endif
#endif  // _MSL_NO_CPP_NAMESPACE

template <class Key, class T, class Hash = hash<Key>, class Compare = _STD::equal_to<Key>,
          class Allocator = _STD::allocator<_STD::pair<const Key, T> > >
class hash_map
{
public:
	//  types:
	typedef Key                                   key_type;
	typedef T                                     mapped_type;
	typedef _STD::pair<const Key, T>              value_type;
	typedef Hash                                  key_hasher;
	typedef Compare                               key_compare;
	typedef Allocator                             allocator_type;
	typedef typename Allocator::reference         reference;
	typedef typename Allocator::const_reference   const_reference;
	typedef typename Allocator::size_type         size_type;
	typedef typename Allocator::difference_type   difference_type;
	typedef typename Allocator::pointer           pointer;
	typedef typename Allocator::const_pointer     const_pointer;

private:
	template <bool, bool = true>
	class value_hash_imp
		: key_hasher
	{
	public:
		typedef value_type argument_type;
		typedef size_type  result_type;

		size_type operator()(const value_type& x) const
			{return key_hash()(x.first);}
		size_type operator()(const key_type& x) const
			{return key_hash()(x);}
	private:
		value_hash_imp() {}
		value_hash_imp(key_hasher h) : key_hasher(h) {}
		const key_hasher& key_hash() const {return *this;}

		friend class hash_map;
	};

	template <bool b>
	class value_hash_imp<false, b>
	{
	public:
		typedef value_type argument_type;
		typedef size_type  result_type;

		size_type operator()(const value_type& x) const
			{return hash_(x.first);}
		size_type operator()(const key_type& x) const
			{return hash_(x);}
	private:
		key_hasher hash_;

		value_hash_imp() {}
		value_hash_imp(key_hasher h) : hash_(h) {}
		const key_hasher& key_hash() const {return hash_;}

		friend class hash_map;
	};

	template <bool, bool = true>
	class value_compare_imp
		: key_compare
	{
	public:
		typedef value_type first_argument_type;
		typedef value_type second_argument_type;
		typedef bool       result_type;

		bool operator()(const value_type& x, const value_type& y) const
			{return comp()(x.first, y.first);}
		bool operator()(const key_type& x, const value_type& y) const
			{return comp()(x, y.first);}
		bool operator()(const value_type& x, const key_type& y) const
			{return comp()(x.first, y);}
	private:

		value_compare_imp() {}
		value_compare_imp(key_compare c) : key_compare(c) {}
		const key_compare& comp() const {return *this;}

		friend class hash_map;
	};

	template <bool b>
	class value_compare_imp<false, b>
	{
	public:
		typedef value_type first_argument_type;
		typedef value_type second_argument_type;
		typedef bool       result_type;

		bool operator()(const value_type& x, const value_type& y) const
			{return comp_(x.first, y.first);}
		bool operator()(const key_type& x, const value_type& y) const
			{return comp_(x, y.first);}
		bool operator()(const value_type& x, const key_type& y) const
			{return comp_(x.first, y);}
	private:
		key_compare comp_;

		value_compare_imp() {}
		value_compare_imp(key_compare c) : comp_(c) {}
		const key_compare& comp() const {return comp_;}

		friend class hash_map;
	};
public:
	typedef value_hash_imp<is_empty<key_hasher>::value>     value_hasher;
	typedef value_compare_imp<is_empty<key_compare>::value> value_compare;
private:
	typedef hash_table<value_type, value_hasher, value_compare, Allocator> hash_type;
public:
	typedef typename hash_type::iterator                   iterator;
	typedef typename hash_type::const_iterator             const_iterator;

	//  construct/copy/destroy:
	explicit hash_map(size_type num_buckets = 0)
		: table_(num_buckets, value_hasher(), value_compare(), 2.F, 4.F, allocator_type()) {}
	hash_map(size_type num_buckets, const key_hasher& hash)
		: table_(num_buckets, value_hasher(hash), value_compare(), 2.F, 4.F, allocator_type()) {}
	hash_map(size_type num_buckets, const key_hasher& hash, const key_compare& comp,
		float load_factor_limit = 2.F, float growth_factor = 4.F)
		: table_(num_buckets, value_hasher(hash), value_compare(comp),
			load_factor_limit, growth_factor, allocator_type()) {}
	hash_map(size_type num_buckets, const key_hasher& hash, const key_compare& comp,
		float load_factor_limit, float growth_factor, const allocator_type& a)
		: table_(num_buckets, value_hasher(hash), value_compare(comp),
			load_factor_limit, growth_factor, a) {}

	template <class InputIterator>
		hash_map(InputIterator first, InputIterator last, size_type num_buckets = 0)
			: table_(first, last, false, num_buckets, value_hasher(), value_compare(),
				2.F, 4.F, allocator_type()) {}
	template <class InputIterator>
		hash_map(InputIterator first, InputIterator last, size_type num_buckets,
			const key_hasher& hash)
			: table_(first, last, false, num_buckets, value_hasher(hash), value_compare(),
			  2.F, 4.F, allocator_type()) {}
	template <class InputIterator>
		hash_map(InputIterator first, InputIterator last, size_type num_buckets,
			const key_hasher& hash, const key_compare& comp,
			float load_factor_limit = 2.F, float growth_factor = 4.F)
			: table_(first, last, false, num_buckets, value_hasher(hash), value_compare(comp),
			  load_factor_limit, growth_factor, allocator_type()) {}
	template <class InputIterator>
		hash_map(InputIterator first, InputIterator last, size_type num_buckets,
			const key_hasher& hash, const key_compare& comp,
			float load_factor_limit, float growth_factor, const allocator_type& a)
			: table_(first, last, false, num_buckets, value_hasher(hash), value_compare(comp),
				load_factor_limit, growth_factor, a) {}

	allocator_type get_allocator() const {return table_.get_allocator();}

	//  iterators:
	iterator       begin()       {return table_.begin();}
	const_iterator begin() const {return table_.begin();}
	iterator       end()         {return table_.end();}
	const_iterator end() const   {return table_.end();}

	//  capacity:
	bool      empty() const                       {return table_.empty();}
	size_type size() const                        {return table_.size();}
	size_type max_size() const                    {return table_.max_size();}
	size_type bucket_count() const                {return table_.bucket_count();}
	size_type bucket_count(size_type num_buckets) {return table_.bucket_count(num_buckets);}
	float     load_factor() const                 {return table_.load_factor();}
	void      load_factor_limit(float lf)         {table_.load_factor_limit(lf);}
	float     load_factor_limit() const           {return table_.load_factor_limit();}
	void      growth_factor(float gf)             {table_.growth_factor(gf);}
	float     growth_factor() const               {return table_.growth_factor();}
	size_type collision(const_iterator i) const   {return table_.collision(i);}

	//  element access:
	mapped_type& operator[](const key_type& x)
		{return table_.template find_or_insert<key_type, mapped_type>(x).second;}

	//  modifiers:
	_STD::pair<iterator, bool> insert(const value_type& x)   {return table_.insert_one(x);}
	iterator insert(iterator, const value_type& x)           {return table_.insert_one(x).first;}
	template <class InputIterator>
		void insert(InputIterator first, InputIterator last) {table_.insert_one(first, last);}

	void      erase(iterator position)             {table_.erase(position);}
	size_type erase(const key_type& x)             {return table_.erase_one(x);}
	void      erase(iterator first, iterator last) {table_.erase(first, last);}

	void        swap(hash_map& y)              {Metrowerks::swap(  table_, y.table_);}
	friend void swap(hash_map& x, hash_map& y) {Metrowerks::swap(x.table_, y.table_);}

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

	//  observers:
	key_compare   key_comp() const   {return table_.value_comp().comp();}
	value_compare value_comp() const {return table_.value_comp();}
	key_hasher    key_hash() const   {return table_.value_hash().key_hash();}
	value_hasher  value_hash() const {return table_.value_hash();}

	//  set operations:
	iterator       find(const key_type& x)        {return table_.find(x);}
	const_iterator find(const key_type& x) const  {return table_.find(x);}
	size_type      count(const key_type& x) const {return table_.count_one(x);}

	_STD::pair<iterator, iterator>             equal_range(const key_type& x)
		{return table_.equal_range(x);}
	_STD::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
		{return table_.equal_range(x);}

	bool invariants() const {return table_.invariants();}
private:
	hash_type table_;
};

template <class Key, class T, class Hash, class Compare, class Allocator>
bool
operator==(const hash_map<Key, T, Hash, Compare, Allocator>& x,
           const hash_map<Key, T, Hash, Compare, Allocator>& y)
{
	if (x.size() != y.size())
		return false;
	typedef typename hash_map<Key, T, Hash, Compare, Allocator>::const_iterator const_iterator;
	for (const_iterator i = x.begin(), ex = x.end(), ey = y.end(); i != ex; ++i)
	{
		const_iterator j = y.find(i->first);
		if (j == ey)
			return false;
		if (!(*i == *j))
			return false;
	}
	return true;
}

template <class Key, class T, class Hash, class Compare, class Allocator>
inline
bool
operator!=(const hash_map<Key, T, Hash, Compare, Allocator>& x,
           const hash_map<Key, T, Hash, Compare, Allocator>& y)
{
	return !(x == y);
}

template <class Key, class T, class Hash = hash<Key>, class Compare = _STD::equal_to<Key>,
          class Allocator = _STD::allocator<_STD::pair<const Key, T> > >
class hash_multimap
{
public:
	//  types:
	typedef Key                                   key_type;
	typedef T                                     mapped_type;
	typedef _STD::pair<const Key, T>              value_type;
	typedef Hash                                  key_hasher;
	typedef Compare                               key_compare;
	typedef Allocator                             allocator_type;
	typedef typename Allocator::reference         reference;
	typedef typename Allocator::const_reference   const_reference;
	typedef typename Allocator::size_type         size_type;
	typedef typename Allocator::difference_type   difference_type;
	typedef typename Allocator::pointer           pointer;
	typedef typename Allocator::const_pointer     const_pointer;

private:
	template <bool, bool = true>
	class value_hash_imp
		: key_hasher
	{
	public:
		typedef value_type argument_type;
		typedef size_type  result_type;

		size_type operator()(const value_type& x) const
			{return key_hash()(x.first);}
		size_type operator()(const key_type& x) const
			{return key_hash()(x);}
	private:
		value_hash_imp() {}
		value_hash_imp(key_hasher h) : key_hasher(h) {}
		const key_hasher& key_hash() const {return *this;}

		friend class hash_multimap;
	};

	template <bool b>
	class value_hash_imp<false, b>
	{
	public:
		typedef value_type argument_type;
		typedef size_type  result_type;

		size_type operator()(const value_type& x) const
			{return hash_(x.first);}
		size_type operator()(const key_type& x) const
			{return hash_(x);}
	private:
		key_hasher hash_;

		value_hash_imp() {}
		value_hash_imp(key_hasher h) : hash_(h) {}
		const key_hasher& key_hash() const {return hash_;}

		friend class hash_multimap;
	};

	template <bool, bool = true>
	class value_compare_imp
		: key_compare
	{
	public:
		typedef value_type first_argument_type;
		typedef value_type second_argument_type;
		typedef bool       result_type;

		bool operator()(const value_type& x, const value_type& y) const
			{return comp()(x.first, y.first);}
		bool operator()(const key_type& x, const value_type& y) const
			{return comp()(x, y.first);}
		bool operator()(const value_type& x, const key_type& y) const
			{return comp()(x.first, y);}
	private:

		value_compare_imp() {}
		value_compare_imp(key_compare c) : key_compare(c) {}
		const key_compare& comp() const {return *this;}

		friend class hash_multimap;
	};

	template <bool b>
	class value_compare_imp<false, b>
	{
	public:
		typedef value_type first_argument_type;
		typedef value_type second_argument_type;
		typedef bool       result_type;

		bool operator()(const value_type& x, const value_type& y) const
			{return comp_(x.first, y.first);}
		bool operator()(const key_type& x, const value_type& y) const
			{return comp_(x, y.first);}
		bool operator()(const value_type& x, const key_type& y) const
			{return comp_(x.first, y);}
	private:
		key_compare comp_;

		value_compare_imp() {}
		value_compare_imp(key_compare c) : comp_(c) {}
		const key_compare& comp() const {return comp_;}

		friend class hash_multimap;
	};
public:
	typedef value_hash_imp<is_empty<key_hasher>::value>     value_hasher;
	typedef value_compare_imp<is_empty<key_compare>::value> value_compare;
private:
	typedef hash_table<value_type, value_hasher, value_compare, Allocator> hash_type;
public:
	typedef typename hash_type::iterator                   iterator;
	typedef typename hash_type::const_iterator             const_iterator;

	//  construct/copy/destroy:
	explicit hash_multimap(size_type num_buckets = 0)
		: table_(num_buckets, value_hasher(), value_compare(),
			2.F, 4.F, allocator_type()) {}
	hash_multimap(size_type num_buckets, const key_hasher& hash)
		: table_(num_buckets, value_hasher(hash), value_compare(),
			2.F, 4.F, allocator_type()) {}
	hash_multimap(size_type num_buckets, const key_hasher& hash, const key_compare& comp,
		float load_factor_limit = 2.F, float growth_factor = 4.F)
		: table_(num_buckets, value_hasher(hash), value_compare(comp),
			load_factor_limit, growth_factor, allocator_type()) {}
	hash_multimap(size_type num_buckets, const key_hasher& hash, const key_compare& comp,
		float load_factor_limit, float growth_factor, const allocator_type& a)
		: table_(num_buckets, value_hasher(hash), value_compare(comp),
			load_factor_limit, growth_factor, a) {}

	template <class InputIterator>
		hash_multimap(InputIterator first, InputIterator last, size_type num_buckets = 0)
			: table_(first, last, true, num_buckets, value_hasher(), value_compare(),
				2.F, 4.F, allocator_type()) {}
	template <class InputIterator>
		hash_multimap(InputIterator first, InputIterator last, size_type num_buckets,
			const key_hasher& hash)
			: table_(first, last, true, num_buckets, value_hasher(hash), value_compare(),
				2.F, 4.F, allocator_type()) {}
	template <class InputIterator>
		hash_multimap(InputIterator first, InputIterator last, size_type num_buckets,
			const key_hasher& hash, const key_compare& comp,
			float load_factor_limit = 2.F, float growth_factor = 4.F)
			: table_(first, last, true, num_buckets, value_hasher(hash), value_compare(comp),
				load_factor_limit, growth_factor, allocator_type()) {}
	template <class InputIterator>
		hash_multimap(InputIterator first, InputIterator last, size_type num_buckets,
			const key_hasher& hash, const key_compare& comp,
			float load_factor_limit, float growth_factor, const allocator_type& a)
			: table_(first, last, true, num_buckets, value_hasher(hash), value_compare(comp),
				load_factor_limit, growth_factor, a) {}

	allocator_type get_allocator() const {return table_.get_allocator();}

	//  iterators:
	iterator       begin()       {return table_.begin();}
	const_iterator begin() const {return table_.begin();}
	iterator       end()         {return table_.end();}
	const_iterator end() const   {return table_.end();}

	//  capacity:
	bool      empty() const                       {return table_.empty();}
	size_type size() const                        {return table_.size();}
	size_type max_size() const                    {return table_.max_size();}
	size_type bucket_count() const                {return table_.bucket_count();}
	size_type bucket_count(size_type num_buckets) {return table_.bucket_count(num_buckets);}
	float     load_factor() const                 {return table_.load_factor();}
	void      load_factor_limit(float lf)         {table_.load_factor_limit(lf);}
	float     load_factor_limit() const           {return table_.load_factor_limit();}
	void      growth_factor(float gf)             {table_.growth_factor(gf);}
	float     growth_factor() const               {return table_.growth_factor();}
	size_type collision(const_iterator i) const   {return table_.collision(i);}

	//  modifiers:
	iterator insert(const value_type& x)             {return table_.insert_multi(x);}
	iterator insert(iterator p, const value_type& x) {return table_.insert_multi(p, x);}
	template <class InputIterator>
		void insert(InputIterator first, InputIterator last) {table_.insert_multi(first, last);}

	void      erase(iterator position)             {table_.erase(position);}
	size_type erase(const key_type& x)             {return table_.erase_multi(x);}
	void      erase(iterator first, iterator last) {table_.erase(first, last);}

	void        swap(hash_multimap& y)                   {Metrowerks::swap(  table_, y.table_);}
	friend void swap(hash_multimap& x, hash_multimap& y) {Metrowerks::swap(x.table_, y.table_);}

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

	//  observers:
	key_compare   key_comp() const   {return table_.value_comp().comp();}
	value_compare value_comp() const {return table_.value_comp();}
	key_hasher    key_hash() const   {return table_.value_hash().key_hash();}
	value_hasher  value_hash() const {return table_.value_hash();}

	//  set operations:
	iterator       find(const key_type& x)        {return table_.find(x);}
	const_iterator find(const key_type& x) const  {return table_.find(x);}
	size_type      count(const key_type& x) const {return table_.count_multi(x);}

	_STD::pair<iterator, iterator>             equal_range(const key_type& x)
		{return table_.equal_range(x);}
	_STD::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
		{return table_.equal_range(x);}

	bool invariants() const {return table_.invariants();}
private:
	hash_type table_;
};

template <class Key, class T, class Hash, class Compare, class Allocator>
bool
operator==(const hash_multimap<Key, T, Hash, Compare, Allocator>& x,
           const hash_multimap<Key, T, Hash, Compare, Allocator>& y)
{
	if (x.size() != y.size())
		return false;
	typedef typename hash_multimap<Key, T, Hash, Compare, Allocator>::const_iterator const_iterator;
	typedef typename hash_multimap<Key, T, Hash, Compare, Allocator>::size_type size_type;
	typedef typename hash_multimap<Key, T, Hash, Compare, Allocator>::key_compare key_compare;
	key_compare c = x.key_comp();
	for (const_iterator i = x.begin(), ex = x.end(); i != ex;)
	{
		size_type count = 1;
		const_iterator j = i;
		for (++j; j != ex && c(i->first, j->first); ++count)
			++j;
		_STD::pair<const_iterator, const_iterator> p = y.equal_range(i->first);
		if (count != static_cast<size_type>(_STD::distance(p.first, p.second)))
			return false;
		if (!_STD::equal(i, j, p.first))
			return false;
		i = j;
	}
	return true;
}

template <class Key, class T, class Hash, class Compare, class Allocator>
inline
bool
operator!=(const hash_multimap<Key, T, Hash, Compare, Allocator>& x,
           const hash_multimap<Key, T, Hash, Compare, Allocator>& y)
{
	return !(x == y);
}

#ifndef _MSL_DEBUG

template <class Key, class T, class Hash, class Compare, class Allocator>
struct has_trivial_dtor_after_move_ctor<hash_map<Key, T, Hash, Compare, Allocator> >
{
	static const bool value = has_trivial_dtor<Allocator>::value &&
	                          has_trivial_dtor<Compare>::value &&
	                          has_trivial_dtor<Hash>::value;
};

template <class Key, class T, class Hash, class Compare, class Allocator>
struct has_trivial_dtor_after_move_ctor<hash_multimap<Key, T, Hash, Compare, Allocator> >
{
	static const bool value = has_trivial_dtor<Allocator>::value &&
	                          has_trivial_dtor<Compare>::value &&
	                          has_trivial_dtor<Hash>::value;
};

#endif  // _MSL_DEBUG

template <class Key, class T, class Hash, class Compare, class Allocator>
struct move_with_swap<hash_map<Key, T, Hash, Compare, Allocator> >
{
	static const bool value = has_trivial_copy_ctor<Allocator>::value &&
	                          has_trivial_assignment<Allocator>::value &&
	                          has_trivial_copy_ctor<Compare>::value &&
	                          has_trivial_assignment<Compare>::value &&
	                          has_trivial_copy_ctor<Hash>::value &&
	                          has_trivial_assignment<Hash>::value;
};

template <class Key, class T, class Hash, class Compare, class Allocator>
struct move_with_swap<hash_multimap<Key, T, Hash, Compare, Allocator> >
{
	static const bool value = has_trivial_copy_ctor<Allocator>::value &&
	                          has_trivial_assignment<Allocator>::value &&
	                          has_trivial_copy_ctor<Compare>::value &&
	                          has_trivial_assignment<Compare>::value &&
	                          has_trivial_copy_ctor<Hash>::value &&
	                          has_trivial_assignment<Hash>::value;
};

template <class Key, class T, class Hash, class Compare, class Allocator>
struct has_nothrow_constructor<hash_map<Key, T, Hash, Compare, Allocator> >
{
	static const bool value = has_nothrow_constructor<Allocator>::value &&
	                          has_nothrow_constructor<Compare>::value &&
	                          has_nothrow_constructor<Hash>::value;
};

template <class Key, class T, class Hash, class Compare, class Allocator>
struct has_nothrow_constructor<hash_multimap<Key, T, Hash, Compare, Allocator> >
{
	static const bool value = has_nothrow_constructor<Allocator>::value &&
	                          has_nothrow_constructor<Compare>::value &&
	                          has_nothrow_constructor<Hash>::value;
};

#ifndef _MSL_NO_CPP_NAMESPACE
	} // namespace Metrowerks
#endif

#ifdef _MSL_FORCE_ENUMS_ALWAYS_INT
	#pragma enumsalwaysint reset
#endif

#ifdef _MSL_FORCE_ENABLE_BOOL_SUPPORT
	#pragma bool reset
#endif

#ifdef __MWERKS__
#pragma options align=reset
#endif

#endif // RC_INVOKED

#endif  // _HASH_MAP

// hh 991217 Created
// hh 010402 Removed 68K CMF support
// hh 020702 Improved operator == to be order independent
// hh 030527 Made pseudo movable
