Index: trunk/nv/stl/container/hash_table.hh
===================================================================
--- trunk/nv/stl/container/hash_table.hh	(revision 407)
+++ trunk/nv/stl/container/hash_table.hh	(revision 408)
@@ -27,14 +27,14 @@
 	template <
 		typename HashEntryPolicy,
-		typename RangeHashPolicy,
-		typename RehashPolicy
+		typename RehashPolicy,
+		typename BaseClass
 	>
-	class hash_table_storage : protected HashEntryPolicy
+	class hash_table_storage : protected BaseClass
 	{
 	public:
-		typedef HashEntryPolicy                base_type;
-		typedef typename base_type::value_type value_type;
-		typedef typename base_type::entry_type entry_type;
-		typedef typename base_type::hash_type  hash_type;
+		typedef HashEntryPolicy                      base_type;
+		typedef typename HashEntryPolicy::value_type value_type;
+		typedef typename HashEntryPolicy::entry_type entry_type;
+		typedef typename HashEntryPolicy::hash_type  hash_type;
 
 		struct node_type : entry_type
@@ -48,5 +48,5 @@
 		{
 		public:
-			typedef typename base_type::value_type                         value_type;
+			typedef typename HashEntryPolicy::value_type                   value_type;
 			typedef conditional_t<IsConst, const value_type*, value_type*> pointer;
 			typedef conditional_t<IsConst, const value_type&, value_type&> reference;
@@ -196,4 +196,17 @@
 			}
 			return *this;
+		}
+
+		size_type bucket_size( size_type n ) const
+		{
+			if ( n >= m_bucket_count ) return 0;
+			node_type* current = m_buckets[n];
+			size_type result = 0;
+			while ( current )
+			{
+				++result;
+				current = current->next;
+			}
+			return result;
 		}
 
@@ -261,7 +274,4 @@
 		inline void max_load_factor( float ml ) { m_max_load_factor = ml; }
 
-		using base_type::hash_function;
-		using base_type::key_eq;
-
 		~hash_table_storage()
 		{
@@ -269,5 +279,5 @@
 			free_buckets( m_buckets, m_bucket_count );
 		}
-	public:
+	protected:
 		inline iterator unconst( const_iterator i )                       const { return iterator( i.m_node, i.m_bucket ); }
 		inline iterator unlocalize( size_type n, const_local_iterator i ) const { return iterator( i.m_node, m_buckets + n ); }
@@ -277,5 +287,5 @@
 		{
 			node_type* node = alloc_node();
-			base_type::entry_construct( node, hash_code, nv::forward<Args>( args )... );
+			HashEntryPolicy::entry_construct( node, hash_code, nv::forward<Args>( args )... );
 			node->next = m_buckets[index];
 			m_buckets[index] = node;
@@ -309,6 +319,4 @@
 		}
 
-
-	protected:
 		void do_rehash( size_type new_count )
 		{
@@ -320,5 +328,5 @@
 				while ( ( current = m_buckets[i] ) != nullptr )
 				{
-					size_type new_index = bucket_index( base_type::get_entry_hash( current ), new_count );
+					size_type new_index = bucket_index( HashEntryPolicy::get_entry_hash( current ), new_count );
 					m_buckets[i] = current->next;
 					current->next = new_buckets[new_index];
@@ -359,5 +367,5 @@
 		size_type bucket_index( hash_type hash_code, size_t b_count ) const
 		{
-			return RangeHashPolicy::template get<hash_type>( hash_code, b_count );
+			return RehashPolicy::template get_index<hash_type>( hash_code, b_count );
 		}
 		node_type** allocate_buckets( size_type new_count )
@@ -382,5 +390,5 @@
 		void free_node( node_type* node )
 		{
-			node->~node_type();
+			HashEntryPolicy::entry_destroy( node );
 			nvfree( node );
 		}
@@ -410,25 +418,24 @@
 	template <
 		typename HashEntryPolicy,
-		typename Storage = hash_table_storage< 
-			HashEntryPolicy,
-			hash_table_range_mod_policy,
-			hash_table_prime_rehash_policy
-		>
+		template < typename > class HashQueryPoilcy = hash_table_no_extra_types_policy,
+		typename RehashPolicy = hash_table_prime_rehash_policy,
+		typename SuperClass = empty_type
 	>
-	class hash_table : public Storage
+	class hash_table : public hash_table_storage< HashEntryPolicy, RehashPolicy, SuperClass >
 	{
+		typedef hash_table_storage< HashEntryPolicy, RehashPolicy, SuperClass > base_type;
 	public:
-		typedef Storage                            base_type;
-		typedef typename base_type::key_type       key_type;
-		typedef typename base_type::value_type     value_type;
-		typedef typename base_type::entry_type     entry_type;
-		typedef typename base_type::hash_type      hash_type;
-		typedef typename base_type::mapped_type    mapped_type;
-		typedef size_t                             size_type;
-		typedef ptrdiff_t                          difference_type;
-		typedef value_type&                        reference;
-		typedef const value_type&                  const_reference;
-		typedef value_type*                        pointer;
-		typedef const value_type*                  const_pointer;
+		typedef typename base_type::value_type        value_type;
+		typedef typename base_type::entry_type        entry_type;
+		typedef typename base_type::hash_type         hash_type;
+		typedef typename HashEntryPolicy::query_type  query_type;
+		typedef typename HashEntryPolicy::key_type    key_type;
+		typedef typename HashEntryPolicy::mapped_type mapped_type;
+		typedef size_t                                size_type;
+		typedef ptrdiff_t                             difference_type;
+		typedef value_type&                           reference;
+		typedef const value_type&                     const_reference;
+		typedef value_type*                           pointer;
+		typedef const value_type*                     const_pointer;
 
 		typedef typename base_type::local_iterator       local_iterator;
@@ -439,31 +446,40 @@
 		typedef pair< iterator, bool >                   insert_return_type;
 
-	public:
-		explicit hash_table() {}
+	public: // constructors
+		hash_table() {}
 		explicit hash_table( size_type size ) : base_type( size ) {}
-
-		iterator       find( const key_type& key )
-		{
-			const hash_type c = base_type::get_hash( key );
-			size_type       b = base_type::get_bucket_index( c );
-			return do_find_node( b, c, key );
-		}
-		const_iterator find( const key_type& key ) const
-		{
-			const hash_type c = base_type::get_hash( key );
-			size_type       b = base_type::get_bucket_index( c );
-			return do_find_node( b, c, key );
-		}
-
-// TODO: implement
-// 		template< typename... Args >
-// 		insert_return_type emplace( Args&&... args )
-// 		{
-// 
-// 		}
-
-		inline insert_return_type insert( value_type&& value )
-		{
-			const hash_type h = base_type::get_value_hash( value );
+		hash_table( const hash_table& other ) = delete;
+		hash_table( hash_table&& other ) = default;
+		template< typename InputIterator >
+		hash_table( InputIterator first, InputIterator last ) : base_type()
+		{
+			insert( first, last );
+		}
+
+	public: // assignements
+
+		hash_table& operator=( const hash_table& other ) = delete;
+		hash_table& operator=( hash_table&& other ) = default;
+
+	public: // iterators
+
+		using base_type::begin;
+		using base_type::cbegin;
+		using base_type::end;
+		using base_type::cend;
+
+	public: // capacity
+
+		using base_type::empty;
+		using base_type::size;
+		using base_type::max_size;
+
+	public: // modifiers
+
+		using base_type::clear;
+
+		inline insert_return_type insert( const value_type& value )
+		{
+			const hash_type h = HashEntryPolicy::get_value_hash( value );
 			size_type       b = base_type::get_bucket_index( h );
 			iterator        r = do_find_node( b, h, value );
@@ -472,5 +488,5 @@
 			{
 				if ( base_type::rehash_check( 1 ) ) b = base_type::get_bucket_index( h );
-				return insert_return_type( base_type::insert( b, h, nv::forward( value ) ), true );
+				return insert_return_type( base_type::insert( b, h, value ), true );
 			}
 
@@ -478,8 +494,7 @@
 		}
 
-
-		inline insert_return_type insert( const value_type& value )
-		{
-			const hash_type h = base_type::get_value_hash( value );
+		inline insert_return_type insert( value_type&& value )
+		{
+			const hash_type h = HashEntryPolicy::get_value_hash( value );
 			size_type       b = base_type::get_bucket_index( h );
 			iterator        r = do_find_node( b, h, value );
@@ -488,5 +503,5 @@
 			{
 				if ( base_type::rehash_check( 1 ) ) b = base_type::get_bucket_index( h );
-				return insert_return_type( base_type::insert( b, h, value ), true );
+				return insert_return_type( base_type::insert( b, h, nv::forward( value ) ), true );
 			}
 
@@ -511,53 +526,134 @@
 		}
 
-		size_type erase( const key_type& key )
+		size_type erase( const query_type& key )
+		{
+			const hash_type c = HashEntryPolicy::get_hash( key );
+			size_type       b = base_type::get_bucket_index( c );
+			return do_erase( b, c, key );
+		}
+
+		template < typename T >
+		enable_if_t< HashQueryPoilcy<T>::value, size_type >
+		erase( const T& key )
+		{
+			const hash_type c = HashEntryPolicy::get_hash( key );
+			size_type       b = base_type::get_bucket_index( c );
+			return do_erase( b, c, key );
+		}
+
+	public: // lookup
+
+		iterator       find( const query_type& key )
+		{
+			const hash_type c = HashEntryPolicy::get_hash( key );
+			size_type       b = base_type::get_bucket_index( c );
+			return do_find_node( b, c, key );
+		}
+		
+		const_iterator find( const query_type& key ) const
+		{
+			const hash_type c = HashEntryPolicy::get_hash( key );
+			size_type       b = base_type::get_bucket_index( c );
+			return do_find_node( b, c, key );
+		}
+
+		template < typename T >
+		enable_if_t< HashQueryPoilcy<T>::value, iterator >
+		find( const T& key )
+		{
+			const hash_type c = HashEntryPolicy::get_hash( key );
+			size_type       b = base_type::get_bucket_index( c );
+			return do_find_node( b, c, key );
+		}
+
+		template < typename T >
+		enable_if_t< HashQueryPoilcy<T>::value, const_iterator >
+		find( const T& key ) const
+		{
+			const hash_type c = HashEntryPolicy::get_hash( key );
+			size_type       b = base_type::get_bucket_index( c );
+			return do_find_node( b, c, key );
+		}
+
+	protected:
+
+		template < typename KeyConvertible >
+		inline insert_return_type insert_key( const KeyConvertible& key )
+		{
+			const hash_type h = HashEntryPolicy::get_hash( key );
+			size_type       b = base_type::get_bucket_index( h );
+			iterator        r = do_find_node( b, h, key );
+
+			if ( r == this->end() )
+			{
+				if ( base_type::rehash_check( 1 ) ) b = base_type::get_bucket_index( h );
+				return insert_return_type( base_type::insert( b, h, key, mapped_type() ), true );
+			}
+
+			return insert_return_type( r, false );
+		}
+
+		template < typename KeyConvertible, typename M >
+		inline insert_return_type try_insert( const KeyConvertible& key, M&& obj )
+		{
+			const hash_type h = HashEntryPolicy::get_hash( key );
+			size_type       b = base_type::get_bucket_index( h );
+			iterator        r = do_find_node( b, h, key );
+
+			if ( r == this->end() )
+			{
+				if ( base_type::rehash_check( 1 ) ) b = base_type::get_bucket_index( h );
+				return insert_return_type( base_type::insert( b, h, key, ::nv::forward< M >( obj ) ), true );
+			}
+			return insert_return_type( r, false );
+		}
+
+		template < typename KeyConvertible, typename M >
+		inline insert_return_type try_insert( KeyConvertible&& key, M&& obj )
+		{
+			const hash_type h = HashEntryPolicy::get_hash( key );
+			size_type       b = base_type::get_bucket_index( h );
+			iterator        r = do_find_node( b, h, key );
+
+			if ( r == this->end() )
+			{
+				if ( base_type::rehash_check( 1 ) ) b = base_type::get_bucket_index( h );
+				return insert_return_type( base_type::insert( b, h, ::nv::move(key), ::nv::forward< M >( obj ) ), true );
+			}
+			return insert_return_type( r, false );
+		}
+
+		template < typename ComparableType >
+		inline iterator do_find_node( size_type index, hash_type h, const ComparableType& query ) const
+		{
+			const_local_iterator first = this->cbegin( index );
+			const_local_iterator last  = this->cend( index );
+			while ( first != last )
+			{
+				if ( HashEntryPolicy::entry_compare( first.entry(), h, query ) )
+					return base_type::unlocalize( index, first );
+				++first;
+			}
+			return base_type::unconst( this->cend() );
+		}
+
+		template < typename ComparableType >
+		inline size_type do_erase( size_type index, hash_type h, const ComparableType& query ) 
 		{
 			// TODO : optimize for non-multi sets! (one key possible)
-			const hash_type c = base_type::get_hash( key );
-			size_type       b = base_type::get_bucket_index( c );
-			const_local_iterator i = this->cbegin( b );
+			const_local_iterator first = this->cbegin( index );
+			const_local_iterator last  = this->cend( index );
 			size_type result = 0;
-			while ( i != this->cend( b ) )
-			{
-				if ( base_type::entry_compare( i.entry(), c, key ) )
+			while ( first != last )
+			{
+				if ( HashEntryPolicy::entry_compare( first.entry(), h, query ) )
 				{
-					i = base_type::erase_local( b, i );
+					first = base_type::erase_local( index, first );
 					++result;
 				}
 				else
-					++i;
+					++first;
 			}
 			return result;
-		}
-
-	protected:
-
-		inline insert_return_type insert_key( const key_type& key )
-		{
-			const hash_type h = base_type::get_hash( key );
-			size_type       b = base_type::get_bucket_index( h );
-			iterator        r = do_find_node( b, h, key );
-
-			if ( r == this->end() )
-			{
-				if ( base_type::rehash_check( 1 ) ) b = base_type::get_bucket_index( h );
-				return insert_return_type( base_type::insert( b, h, key ), true );
-			}
-
-			return insert_return_type( r, false );
-		}
-
-		template < typename ComparableType >
-		iterator do_find_node( size_type index, hash_type h, const ComparableType& query ) const
-		{
-			const_local_iterator first = this->cbegin( index );
-			const_local_iterator last  = this->cend( index );
-			while ( first != last )
-			{
-				if ( base_type::entry_compare( first.entry(), h, query ) )
-					return base_type::unlocalize( index, first );
-				++first;
-			}
-			return base_type::unconst( this->cend() );
 		}
 
Index: trunk/nv/stl/container/hash_table_policy.hh
===================================================================
--- trunk/nv/stl/container/hash_table_policy.hh	(revision 407)
+++ trunk/nv/stl/container/hash_table_policy.hh	(revision 408)
@@ -15,271 +15,128 @@
 
 #include <nv/common.hh>
-#include <nv/stl/functional/hash.hh>
-#include <nv/stl/functional/comparisons.hh>
-#include <nv/stl/memory.hh>
-#include <nv/stl/utility/pair.hh>
 
 namespace nv
 {
+	template < typename T >
+	struct hash_table_no_extra_types_policy : false_type{};
 
+	template < typename Key, typename Mapped, typename Hash, bool StoreHash >
+	struct hash_table_standard_entry;
 
-	template <
-		typename T,
-		typename IsEqual = equal_to<T>,
-		bool IsEmpty = is_empty< IsEqual >::value
-	>
-	struct compare_policy;
+	template < typename Key, typename Mapped, typename Hash >
+	struct hash_table_standard_entry< Key, Mapped, Hash, false >
+	{
+		typedef hash_table_standard_entry< Key, Mapped, Hash, false > this_type;
+		typedef Key         key_type;
+		typedef Mapped      mapped_type;
+		typedef Hash        hash_type;
+		typedef pair< const key_type, mapped_type > value_type;
 
+		value_type value;
 
-	template < typename T >
-	struct compare_policy< T, equal_to<T>, true >
-	{
-		constexpr bool compare( const T& t1, const T& t2 ) const
-		{
-			return t1 == t2;
-		}
-		equal_to<T> key_eq() const { return equal_to<T>(); }
+		static constexpr const key_type& get_key( const value_type& value ) { return value.first; }
+		static constexpr const key_type& get_key( const this_type* entry ) { return entry->value.first; }
+		static constexpr value_type* get_value( this_type* entry ) { return &(entry->value); }
 	};
 
-	template < typename T, typename IsEqual >
-	struct compare_policy< T, IsEqual, true > : private IsEqual
+	template < typename Key, typename Mapped, typename Hash >
+	struct hash_table_standard_entry< Key, Mapped, Hash, true >
 	{
-		constexpr bool compare( const T& t1, const T& t2 ) const
+		typedef hash_table_standard_entry< Key, Mapped, Hash, true > this_type;
+		typedef Key         key_type;
+		typedef Mapped      mapped_type;
+		typedef Hash        hash_type;
+		typedef pair< const key_type, mapped_type > value_type;
+
+		value_type value;
+		hash_type  hash_code;
+
+		static constexpr const key_type& get_key( const value_type& value ) { return value.first; }
+		static constexpr const key_type& get_key( const this_type* entry ) { return entry->value.first; }
+		static constexpr value_type* get_value( this_type* entry ) { return &( entry->value ); }
+		static constexpr hash_type get_hash( const this_type* entry )
 		{
-			return (*this)( t1 == t2 );
+			return entry->hash_code;
 		}
-		IsEqual key_eq() const { return ( *this ); }
-	};
-
-	template < typename T, typename IsEqual >
-	struct compare_policy< T, IsEqual, false >
-	{
-		constexpr bool compare( const T& t1, const T& t2 ) const
+		static inline void set_hash( this_type* entry, hash_type hash_code )
 		{
-			return m_key_eq( t1 == t2 );
-		}
-		IsEqual key_eq() const { return m_key_eq; }
-	private:
-		IsEqual m_key_eq;
-	};
-
-	template <
-		typename T,
-		typename H,
-		typename Hasher = hash< T, H >,
-		bool IsEmpty = is_empty< Hasher >::value
-	>
-	struct hash_policy;
-
-
-	template < typename T, typename H >
-	struct hash_policy< T, H, hash< T, H >, true >
-	{
-		constexpr H get_hash( const T& t ) const
-		{
-			return hash< T, H >::get( t );
-		}
-		hash< T, H > hash_function() const { return hash< T, H >(); }
-	};
-
-	template < typename T, typename H, typename Hasher >
-	struct hash_policy< T, H, Hasher, true > : private Hasher
-	{
-		constexpr H get_hash( const T& t ) const
-		{
-			return ( *this )( t );
-		}
-		hash< T, H > hash_function() const { return ( *this ); }
-	};
-
-	template < typename T, typename H, typename Hasher >
-	struct hash_policy< T, H, Hasher, false >
-	{
-		constexpr H get_hash( const T& t ) const
-		{
-			return m_hasher( t );
-		}
-		hash< T, H > hash_function() const { return m_hasher; }
-	private:
-		Hasher m_hasher;
-	};
-
-	// Due to MSVC not being able to handle multiple empty bases, if both
-	// hash and compare are empty, we will still get a 4-size structure.
-	// We will optimize here, to assure that if either is empty, we will still
-	// get an empty class
-	template <
-		typename T,
-		typename H,
-		typename IsEqual = equal_to< T >,
-		typename Hasher = hash< T, H >,
-		bool IsEqualIsEmpty = is_empty< IsEqual >::value,
-		bool HasherIsEmpty = is_empty< Hasher >::value
-	>
-	struct hash_compare_policy;
-
-	template <
-		typename T,
-		typename H,
-		typename IsEqual,
-		typename Hasher,
-		bool HasherIsEmpty
-	>
-	struct hash_compare_policy< T, H, IsEqual, Hasher, false, HasherIsEmpty >
-		: hash_policy< T, H, Hasher, HasherIsEmpty >
-	{
-		constexpr bool compare( const T& t1, const T& t2 ) const
-		{
-			return m_key_eq( t1 == t2 );
-		}
-		IsEqual key_eq() const { return m_key_eq; }
-	private:
-		IsEqual m_key_eq;
-	};
-
-	template <
-		typename T,
-		typename H,
-		typename IsEqual,
-		typename Hasher
-	>
-	struct hash_compare_policy< T, H, IsEqual, Hasher, true, false >
-		: compare_policy< T, IsEqual, true >
-	{
-		constexpr H get_hash( const T& t ) const
-		{
-			return m_hasher( t );
-		}
-		hash< T, H > hash_function() const { return m_hasher; }
-	private:
-		Hasher m_hasher;
-	};
-
-	template <
-		typename T,
-		typename H,
-		typename Hasher,
-		typename IsEqual
-	>
-	struct hash_compare_policy< T, H, IsEqual, Hasher, true, true >
-		: hash_policy< T, H, Hasher, true >
-	{
-		constexpr bool compare( const T& t1, const T& t2 ) const
-		{
-			static_assert( is_trivial< IsEqual >::value, "There is something really wrong with your equality functor." );
-			return IsEqual()( t1, t2 );
-		}
-		IsEqual key_eq() const { return IsEqual(); }
-	};
-
-	template <
-		typename Key,
-		typename Value,
-		typename Hash,
-		typename IsEqual = equal_to< Key >,
-		typename Hasher = hash< Key, Hash >
-	>
-	struct hash_table_entry_stl_map : hash_compare_policy< Key, Hash, IsEqual, Hasher > 
-	{
-		typedef hash_compare_policy< Key, Hash, IsEqual, Hasher > base_type;
-		typedef pair< const Key, Value > value_type;
-		typedef Key        key_type;
-		typedef Hash       hash_type;
-		typedef Value      mapped_type;
-
-		struct entry_type
-		{
-			value_type value;
-		};
-
-		constexpr bool entry_compare( const entry_type* entry, hash_type, const key_type& key ) const
-		{
-			return base_type::compare( entry->value.first, key );
-		}
-
-		constexpr bool entry_compare( const entry_type* entry, hash_type, const value_type& value ) const
-		{
-			return base_type::compare( entry->value.first, value.first );
-		}
-
-		template < typename... Args >
-		inline void entry_construct( entry_type* entry, hash_type, Args&&... params ) const
-		{
-			construct_object( &(entry->value), ::nv::forward<Args>( params )... );
-		}
-
-		inline void entry_construct( entry_type* entry, hash_type, Key key ) const
-		{
-			construct_object( &( entry->value ), value_type( ::nv::move( key ), mapped_type() ) );
-		}
-
-		constexpr hash_type get_entry_hash( const entry_type* entry ) const
-		{
-			return base_type::get_hash( entry->value.first );
-		}
-		constexpr hash_type get_value_hash( const value_type& value ) const
-		{
-			return base_type::get_hash( value.first );
+			entry->hash_code = hash_code;
 		}
 	};
 
-	template <
-		typename Key,
-		typename Value,
-		typename Hash,
-		typename IsEqual = equal_to< Key >,
-		typename Hasher = hash< Key, Hash >
-	>
-	struct hash_table_entry_stl_map_with_hash : hash_compare_policy< Key, Hash, IsEqual, Hasher >
+	template < typename EntryType, bool StoreHash >
+	struct hash_table_standard_entry_hasher;
+
+	template < typename EntryType >
+	struct hash_table_standard_entry_hasher< EntryType, false >
 	{
-		typedef hash_compare_policy< Key, Hash, IsEqual, Hasher > base_type;
-		typedef pair< const Key, Value > value_type;
-		typedef Key        key_type;
-		typedef Hash       hash_type;
-		typedef Value      mapped_type;
+		typedef typename EntryType::hash_type hash_type;
+		typedef typename EntryType::key_type  key_type;
 
-		struct entry_type
+		template < typename T >
+		static constexpr hash_type get_hash( const T& value )
 		{
-			value_type value;
-			hash_type  hash_code;
-		};
+			return hash< T, hash_type >::get( value );
+		}
+		static constexpr hash_type get_hash( const EntryType* entry )
+		{
+			return hash< key_type, hash_type >::get( EntryType::get_key( entry ) );
+		}
+		static inline void set_hash( EntryType*, hash_type ) {}
+	};
 
-		constexpr bool entry_compare( const entry_type* entry, hash_type h, const key_type& key ) const
+	template < typename EntryType >
+	struct hash_table_standard_entry_hasher< EntryType, true >
+	{
+		typedef typename EntryType::hash_type hash_type;
+
+		template < typename T >
+		static constexpr hash_type get_hash( const T& value )
 		{
-			return entry->hash_code == h && base_type::compare( entry->value.first, key );
+			return hash< T, hash_type >::get( value );
 		}
-		constexpr bool entry_compare( const entry_type* entry, hash_type h, const value_type& value ) const
+		static constexpr hash_type get_hash( const EntryType* entry )
 		{
-			return entry->hash_code == h &&  base_type::compare( entry->value.first, value.first );
+			return EntryType::get_hash( entry );
 		}
+		static inline void set_hash( EntryType* entry, hash_type hash_code )
+		{
+			EntryType::set_hash( entry, hash_code );
+		}
+	};
 
-		template < typename... Args >
-		inline void entry_construct( entry_type* entry, hash_type hash_code, Args&&... params ) const
+	template < typename EntryType, typename HasherType, bool UseKey, bool UseHash >
+	struct hash_table_standard_compare;
+
+	template < typename EntryType, typename HasherType >
+	struct hash_table_standard_compare< EntryType, HasherType, true, true >
+	{
+		template < typename T >
+		static constexpr bool apply( const EntryType* entry, typename EntryType::hash_type h, const T& key )
 		{
-			construct_object( &( entry->value ), ::nv::forward<Args>( params )... );
-			entry->hash_code = hash_code;
+			return HasherType::get_hash( entry ) == h && EntryType::get_key( entry ) == key;
 		}
+	};
 
-		inline void entry_construct( entry_type* entry, hash_type hash_code, Key key ) const
+	template < typename EntryType, typename HasherType >
+	struct hash_table_standard_compare< EntryType, HasherType, true, false >
+	{
+		template < typename T >
+		static constexpr bool apply( const EntryType* entry, typename EntryType::hash_type, const T& key )
 		{
-			construct_object( &( entry->value ), value_type( ::nv::move( key ), mapped_type() ) );
-			entry->hash_code = hash_code;
+			return EntryType::get_key( entry ) == key;
 		}
+	};
 
-		constexpr hash_type get_entry_hash( const entry_type* entry ) const
+	template < typename EntryType, typename HasherType >
+	struct hash_table_standard_compare< EntryType, HasherType, false, true >
+	{
+		template < typename T >
+		static constexpr bool apply( const EntryType* entry, typename EntryType::hash_type h, const T& )
 		{
-			return entry->hash_code;
+			return HasherType::get_hash( entry ) == h;
 		}
-		constexpr hash_type get_value_hash( const value_type& value ) const
-		{
-			return base_type::get_hash( value.first );
-		}
-};
-	
-	struct hash_table_range_mod_policy
-	{
-		template< typename H >
-		static size_t get( H h, size_t n ) { return h % n; }
 	};
+
 
 	uint32 get_prime_larger_or_equal_to( uint32 value );
@@ -287,4 +144,7 @@
 	struct hash_table_prime_rehash_policy
 	{
+		template< typename H >
+		static size_t get_index( H h, size_t n ) { return h % n; }
+
 		static uint32 get_bucket_count( uint32 requested_count )
 		{
Index: trunk/nv/stl/hash_map.hh
===================================================================
--- trunk/nv/stl/hash_map.hh	(revision 408)
+++ trunk/nv/stl/hash_map.hh	(revision 408)
@@ -0,0 +1,194 @@
+// Copyright (C) 2015 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of Nova libraries. 
+// For conditions of distribution and use, see copying.txt file in root folder.
+
+/**
+* @file hash_map.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief hash_map
+*/
+
+#ifndef NV_STL_HASH_MAP_HH
+#define NV_STL_HASH_MAP_HH
+
+#include <nv/common.hh>
+#include <nv/stl/container/hash_table.hh>
+#include <nv/stl/container/hash_table_policy.hh>
+#include <nv/stl/utility/pair.hh>
+
+namespace nv
+{
+
+	template <
+		typename Key,
+		typename Query,
+		typename Mapped,
+		typename Hash,
+		bool StoreHash,
+		bool CompareWithHash
+	>
+	struct hash_map_entry_policy
+	{
+		typedef hash_table_standard_entry< Key, Mapped, Hash, StoreHash >        entry_type;
+		typedef hash_table_standard_entry_hasher< entry_type, StoreHash >        hasher_type;
+		typedef hash_table_standard_compare< entry_type, hasher_type, true, CompareWithHash > compare_type;
+		typedef Query                            query_type;
+		typedef typename entry_type::key_type    key_type;
+		typedef typename entry_type::mapped_type mapped_type;
+		typedef typename entry_type::hash_type   hash_type;
+		typedef typename entry_type::value_type  value_type;
+
+		template < typename T >
+		static constexpr hash_type get_hash( const T& t )
+		{
+			return hasher_type::template get_hash< T >( t );
+		}
+
+		template < typename ComparableType >
+		static constexpr bool entry_compare( const entry_type* entry, hash_type h, const ComparableType& key )
+		{
+			return compare_type::template apply< ComparableType >( entry, h, key );
+		}
+		static constexpr bool entry_compare( const entry_type* entry, hash_type h, const value_type& value )
+		{
+			return compare_type::template apply< key_type >( entry, h, entry_type::get_key( value ) );
+		}
+
+		template < typename... Args >
+		static void entry_construct( entry_type* entry, hash_type hash_code, Args&&... params )
+		{
+			construct_object( entry_type::get_value( entry ), ::nv::forward<Args>( params )... );
+			hasher_type::set_hash( entry, hash_code );
+		}
+
+		static void entry_destroy( entry_type* entry )
+		{
+			destroy_object( entry_type::get_value( entry ) );
+		}
+
+		static constexpr hash_type get_entry_hash( const entry_type* entry )
+		{
+			return hasher_type::get_hash( entry );
+		}
+
+		static constexpr hash_type get_value_hash( const value_type& value )
+		{
+			return hasher_type::template get_hash< key_type >( entry_type::get_key( value ) );
+		}
+	};
+	
+	template <
+		typename Key,
+		typename Mapped,
+		typename Hash = size_t,
+		typename EntryPolicy = hash_map_entry_policy< Key, Key, Mapped, Hash, false, false >,
+		template < typename > class QueryConvertPolicy  = hash_table_no_extra_types_policy,
+		template < typename > class InsertConvertPolicy = hash_table_no_extra_types_policy
+	>
+	class hash_map : public hash_table< EntryPolicy, QueryConvertPolicy >
+	{
+	public:
+		typedef hash_table< EntryPolicy, QueryConvertPolicy >                base_type;
+		typedef hash_map< Key, Mapped, Hash, EntryPolicy, QueryConvertPolicy > this_type;
+		typedef typename base_type::value_type                                           value_type;
+		typedef typename base_type::pointer                                              pointer;
+		typedef typename base_type::const_pointer                                        const_pointer;
+		typedef typename base_type::reference                                            reference;
+		typedef typename base_type::const_reference                                      const_reference;
+		typedef typename base_type::iterator                                             iterator;
+		typedef typename base_type::const_iterator                                       const_iterator;
+		typedef typename base_type::size_type                                            size_type;
+		typedef typename base_type::difference_type                                      difference_type;
+		typedef typename base_type::query_type                                           query_type;
+		typedef typename base_type::key_type                                             key_type;
+		typedef typename base_type::mapped_type                                          mapped_type;
+		typedef typename base_type::node_type                                            node_type;
+		typedef typename base_type::insert_return_type                                   insert_return_type;
+
+		using base_type::base_type;
+
+		mapped_type& operator[]( const key_type& key )
+		{
+			return ( *base_type::insert_key( key ).first ).second;
+		}
+
+		template < typename T >
+		enable_if_t< InsertConvertPolicy<T>::value, mapped_type& >
+		operator[]( const T& key )
+		{
+			return ( *base_type::insert_key( key ).first ).second;
+		}
+
+		mapped_type& at( const query_type& key )
+		{
+			iterator it = base_type::find( key );
+			NV_ASSERT_ALWAYS( it != base_type::end(), "Key not found in map!" );
+			return *it;
+		}
+
+		const mapped_type& at( const query_type& key ) const
+		{
+			const_iterator it = base_type::find( key );
+			NV_ASSERT_ALWAYS( it != base_type::cend(), "Key not found in map!" );
+			return *it;
+		}
+
+		template < typename T >
+		enable_if_t< QueryConvertPolicy<T>::value, mapped_type& >
+		at( const T& key )
+		{
+			iterator it = base_type::find( key );
+			NV_ASSERT_ALWAYS( it != base_type::end(), "Key not found in map!" );
+			return *it;
+		}
+
+		template < typename T >
+		enable_if_t< QueryConvertPolicy<T>::value, const mapped_type& >
+		at( const T& key ) const
+		{
+			const_iterator it = base_type::find( key );
+			NV_ASSERT_ALWAYS( it != base_type::cend(), "Key not found in map!" );
+			return *it;
+		}
+
+		template < typename M >
+		insert_return_type assign( const key_type& k, M&& obj )
+		{
+			insert_return_type result = base_type::try_insert( k, nv::forward<M>( obj ) );
+			if ( !result.second ) result.first->second = obj;
+			return result;
+		}
+
+		template < typename M >
+		insert_return_type assign( key_type&& k, M&& obj )
+		{
+			insert_return_type result = base_type::try_insert( nv::forward<key_type>( k ), nv::forward<M>( obj ) );
+			if ( !result.second ) result.first->second = obj;
+			return result;
+		}
+
+		template < typename T, typename M >
+		enable_if_t< InsertConvertPolicy<T>::value, insert_return_type >
+		assign( const T& k, M&& obj )
+		{
+			insert_return_type result = base_type::try_insert( k, nv::forward<M>( obj ) );
+			if ( !result.second ) result.first->second = obj;
+			return result;
+		}
+
+		template < typename T, typename M >
+		enable_if_t< InsertConvertPolicy<T>::value, insert_return_type >
+		assign( T&& k, M&& obj )
+		{
+			insert_return_type result = base_type::try_insert( nv::forward<T>( k ), nv::forward<M>( obj ) );
+			if ( !result.second ) result.first->second = obj;
+			return result;
+		}
+
+	};
+
+}
+
+#endif // NV_STL_HASH_MAP_HH
Index: trunk/nv/stl/string.hh
===================================================================
--- trunk/nv/stl/string.hh	(revision 407)
+++ trunk/nv/stl/string.hh	(revision 408)
@@ -34,4 +34,6 @@
 {
 
+	template < typename Storage > class string_base;
+	class string_view;
 
 	// 	short_string< size_t >
@@ -68,9 +70,12 @@
 		};
 
-
-	}
-
-	template < typename Storage > class string_base;
-	class string_view;
+		template < typename T, typename Enable = void >
+		struct is_string_base_impl : false_type {};
+		template < typename T >
+		struct is_string_base_impl < T,
+			typename enable_if<
+			is_base_of< string_base< typename T::storage_type >, T >::value,
+			void >::type > : true_type{};
+	}
 
 	// Stronger version
@@ -78,11 +83,6 @@
 	//	struct is_string_base : is_template_base_of< T, string_base > {};
 
-	template < typename T, typename Enable = void >
-	struct is_string_base : false_type {};
 	template < typename T >
-	struct is_string_base < T,
-		typename enable_if<
-		is_base_of< string_base< typename T::storage_type >, T >::value,
-		void >::type > : true_type{};
+	struct is_string_base : detail::is_string_base_impl< T > {};
 
 	template < typename T >
@@ -147,5 +147,5 @@
 		inline H get_hash() const
 		{
-			return hash_string< size_type >( this->data(), this->size() );
+			return hash_string< H >( this->data(), this->size() );
 		}
 
@@ -436,5 +436,18 @@
 			initialize( str, nvstrlen( str ) );
 		}
-
+		inline const_string( const string_view& rhs ) 
+		{
+			initialize( rhs.data(), rhs.size() );
+		}
+		template< size_t N >
+		inline const_string( char( &s )[N] )
+		{
+			initialize( s, N-1 );
+		}
+		template< size_t N >
+		inline const_string( const char( &s )[N] )
+		{
+			initialize( s, N - 1 );
+		}
 		~const_string()
 		{
@@ -509,8 +522,8 @@
 		template< size_t N >
 		constexpr hashed_literal_string( char( &s )[N] )
-			: this_type( s, N - 1 ), m_hash( detail::fnv_hash<H>::hash( s, len-1 ) ) {}
+			: this_type( s, N - 1 ), m_hash( detail::fnv_hash<H>::hash( s, N - 1 ) ) {}
 		template< size_t N >
 		constexpr hashed_literal_string( const char( &s )[N] )
-			: this_type( s, N - 1 ), m_hash( detail::fnv_hash<H>::hash( s, len - 1 ) ) {}
+			: this_type( s, N - 1 ), m_hash( detail::fnv_hash<H>::hash( s, N - 1 ) ) {}
 
 		template < typename H2 >
Index: trunk/nv/stl/string_map.hh
===================================================================
--- trunk/nv/stl/string_map.hh	(revision 408)
+++ trunk/nv/stl/string_map.hh	(revision 408)
@@ -0,0 +1,43 @@
+// Copyright (C) 2015 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of Nova libraries. 
+// For conditions of distribution and use, see copying.txt file in root folder.
+
+/**
+* @file string_map.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief string_map and literal_map
+*/
+
+#ifndef NV_STL_STRING_MAP_HH
+#define NV_STL_STRING_MAP_HH
+
+#include <nv/common.hh>
+#include <nv/stl/string.hh>
+#include <nv/stl/container/hash_table.hh>
+#include <nv/stl/utility/pair.hh>
+#include <nv/stl/hash_map.hh>
+
+namespace nv
+{
+
+	template < typename T >
+	using literal_map = hash_map<
+		hashed_literal_string_64, T, uint64, 
+		hash_map_entry_policy< hashed_literal_string_64, hashed_literal_string_64, T, uint64, false, true >,
+		is_string_base
+	>;
+
+	template < typename T >
+	using string_map = hash_map<
+		const_string, T, uint64,
+		hash_map_entry_policy< const_string, string_view, T, uint64, true, true >,
+		hash_table_no_extra_types_policy,
+		is_string_base
+	>;
+
+}
+
+#endif // NV_STL_STRING_MAP_HH
+
Index: trunk/nv/stl/unordered_map.hh
===================================================================
--- trunk/nv/stl/unordered_map.hh	(revision 407)
+++ trunk/nv/stl/unordered_map.hh	(revision 408)
@@ -17,4 +17,7 @@
 #include <nv/stl/container/hash_table.hh>
 #include <nv/stl/utility/pair.hh>
+#include <nv/stl/functional/hash.hh>
+#include <nv/stl/functional/comparisons.hh>
+#include <nv/stl/memory.hh>
 
 namespace nv
@@ -22,17 +25,223 @@
 
 	template <
+		typename T,
+		typename IsEqual = equal_to<T>,
+		bool IsEmpty = is_empty< IsEqual >::value
+	>
+	struct compare_policy;
+
+
+	template < typename T >
+	struct compare_policy< T, equal_to<T>, true >
+	{
+		constexpr bool compare( const T& t1, const T& t2 ) const
+		{
+			return t1 == t2;
+		}
+		equal_to<T> key_eq() const { return equal_to<T>(); }
+	};
+
+	template < typename T, typename IsEqual >
+	struct compare_policy< T, IsEqual, true > : private IsEqual
+	{
+		constexpr bool compare( const T& t1, const T& t2 ) const
+	{
+		return ( *this )( t1 == t2 );
+	}
+	IsEqual key_eq() const { return ( *this ); }
+	};
+
+	template < typename T, typename IsEqual >
+	struct compare_policy< T, IsEqual, false >
+	{
+		constexpr bool compare( const T& t1, const T& t2 ) const
+		{
+			return m_key_eq( t1 == t2 );
+		}
+		IsEqual key_eq() const { return m_key_eq; }
+	private:
+		IsEqual m_key_eq;
+	};
+
+	template <
+		typename T,
+		typename H,
+		typename Hasher = hash< T, H >,
+		bool IsEmpty = is_empty< Hasher >::value
+	>
+	struct hash_policy;
+
+
+	template < typename T, typename H >
+	struct hash_policy< T, H, hash< T, H >, true >
+	{
+		constexpr H get_hash( const T& t ) const
+		{
+			return hash< T, H >::get( t );
+		}
+		hash< T, H > hash_function() const { return hash< T, H >(); }
+	};
+
+	template < typename T, typename H, typename Hasher >
+	struct hash_policy< T, H, Hasher, true > : private Hasher
+	{
+		constexpr H get_hash( const T& t ) const
+	{
+		return ( *this )( t );
+	}
+	hash< T, H > hash_function() const { return ( *this ); }
+	};
+
+	template < typename T, typename H, typename Hasher >
+	struct hash_policy< T, H, Hasher, false >
+	{
+		constexpr H get_hash( const T& t ) const
+		{
+			return m_hasher( t );
+		}
+		hash< T, H > hash_function() const { return m_hasher; }
+	private:
+		Hasher m_hasher;
+	};
+
+	// Due to MSVC not being able to handle multiple empty bases, if both
+	// hash and compare are empty, we will still get a 4-size structure.
+	// We will optimize here, to assure that if either is empty, we will still
+	// get an empty class
+	template <
+		typename T,
+		typename H,
+		typename IsEqual = equal_to< T >,
+		typename Hasher = hash< T, H >,
+		bool IsEqualIsEmpty = is_empty< IsEqual >::value,
+		bool HasherIsEmpty = is_empty< Hasher >::value
+	>
+	struct hash_compare_policy;
+
+	template <
+		typename T,
+		typename H,
+		typename IsEqual,
+		typename Hasher,
+		bool HasherIsEmpty
+	>
+	struct hash_compare_policy< T, H, IsEqual, Hasher, false, HasherIsEmpty >
+		: hash_policy< T, H, Hasher, HasherIsEmpty >
+	{
+		constexpr bool compare( const T& t1, const T& t2 ) const
+	{
+		return m_key_eq( t1 == t2 );
+	}
+	IsEqual key_eq() const { return m_key_eq; }
+	private:
+		IsEqual m_key_eq;
+	};
+
+	template <
+		typename T,
+		typename H,
+		typename IsEqual,
+		typename Hasher
+	>
+	struct hash_compare_policy< T, H, IsEqual, Hasher, true, false >
+		: compare_policy< T, IsEqual, true >
+	{
+		constexpr H get_hash( const T& t ) const
+	{
+		return m_hasher( t );
+	}
+	hash< T, H > hash_function() const { return m_hasher; }
+	private:
+		Hasher m_hasher;
+	};
+
+	template <
+		typename T,
+		typename H,
+		typename Hasher,
+		typename IsEqual
+	>
+	struct hash_compare_policy< T, H, IsEqual, Hasher, true, true >
+		: hash_policy< T, H, Hasher, true >
+	{
+		constexpr bool compare( const T& t1, const T& t2 ) const
+	{
+		static_assert( is_trivial< IsEqual >::value, "There is something really wrong with your equality functor." );
+		return IsEqual()( t1, t2 );
+	}
+	IsEqual key_eq() const { return IsEqual(); }
+	};
+
+	template <
+		typename Key,
+		typename Value,
+		typename Hash,
+		typename IsEqual = equal_to< Key >,
+		typename Hasher = hash< Key, Hash >
+	>
+	struct hash_table_stl_map_policy : hash_compare_policy< Key, Hash, IsEqual, Hasher >
+	{
+		typedef hash_compare_policy< Key, Hash, IsEqual, Hasher >    base_type;
+
+		typedef hash_table_standard_entry< Key, Value, Hash, false > entry_type;
+		typedef typename entry_type::key_type    key_type;
+		typedef typename entry_type::mapped_type mapped_type;
+		typedef typename entry_type::hash_type   hash_type;
+		typedef typename entry_type::value_type  value_type;
+		typedef Key                              query_type;
+
+		constexpr bool entry_compare( const entry_type* entry, hash_type, const query_type& key ) const
+		{
+			return base_type::compare( entry_type::get_key( entry ), key );
+		}
+
+		constexpr bool entry_compare( const entry_type* entry, hash_type, const value_type& value ) const
+		{
+			return base_type::compare( entry_type::get_key( entry ), entry_type::get_key( value ) );
+		}
+
+		template < typename... Args >
+		static void entry_construct( entry_type* entry, hash_type, Args&&... params )
+		{
+			construct_object( entry_type::get_value( entry ), ::nv::forward<Args>( params )... );
+		}
+
+		static void entry_destroy( entry_type* entry )
+		{
+			destroy_object( entry_type::get_value( entry ) );
+		}
+
+		constexpr hash_type get_entry_hash( const entry_type* entry ) const
+		{
+			return base_type::get_hash( entry_type::get_key( entry ) );
+		}
+		constexpr hash_type get_value_hash( const value_type& value ) const
+		{
+			return base_type::get_hash( entry_type::get_key( value ) );
+		}
+	};
+
+	template <
 		typename Key, 
 		typename T,
 		typename Hash = hash< Key >,
-		typename KeyEqual = equal_to< Key >
-//		typename Hash = hash<Key>(), 
-//		typename Predicate = equal_to<Key>,
+		typename KeyEqual = equal_to< Key >,
+		typename HashEntryPolicy = hash_table_stl_map_policy< Key, T, size_t, KeyEqual, Hash >
 	>
 	class unordered_map
-		: public hash_table< hash_table_entry_stl_map< Key, T, size_t, KeyEqual, Hash > >
+		: public hash_table< 
+			HashEntryPolicy,
+			hash_table_no_extra_types_policy,
+			hash_table_prime_rehash_policy,
+			HashEntryPolicy
+		>
 	{
 	public:
-		typedef hash_table< hash_table_entry_stl_map< Key, T, size_t, KeyEqual, Hash > > base_type;
-		typedef unordered_map< Key, T, Hash, KeyEqual >                                  this_type;
+		typedef hash_table< 
+			HashEntryPolicy,
+			hash_table_no_extra_types_policy,
+			hash_table_prime_rehash_policy,
+			HashEntryPolicy
+		> base_type;
 		typedef typename base_type::value_type                                           value_type;
 		typedef typename base_type::pointer                                              pointer;
@@ -51,6 +260,5 @@
 		typedef KeyEqual                                                                 key_equal;
 
-		unordered_map() : base_type() { }
-		explicit unordered_map( size_type bucket_count ) : base_type( bucket_count ) { }
+		using base_type::base_type;
 
 		mapped_type& operator[]( const key_type& key )
@@ -59,6 +267,53 @@
 		}
 
+		mapped_type& at( const key_type& key )
+		{
+			iterator it = base_type::find( key );
+			NV_ASSERT_ALWAYS( it != base_type::end(), "Key not found in map!" );
+			return *it;
+		}
+
+		const mapped_type& at( const key_type& key ) const
+		{
+			const_iterator it = base_type::find( key );
+			NV_ASSERT_ALWAYS( it != base_type::cend(), "Key not found in map!" );
+			return *it;
+		}
+
+		size_type count( const key_type& key ) const
+		{
+			return base_type::find( key ) == base_type::cend() ? 0 : 1;
+		}
+
+		pair<iterator, iterator> equal_range( const key_type& key ) 
+		{
+			iterator it = base_type::find( key );
+			return pair<iterator, iterator>( it, it == base_type::end() ? it : ++it );
+		}
+
+		pair<const_iterator, const_iterator> equal_range( const key_type& key ) const
+		{
+			const_iterator it = base_type::find( key );
+			return pair<const_iterator, const_iterator>( it, it == base_type::cend() ? it : ++it );
+		}
+
 		using base_type::insert;
-	
+
+		template < typename M >
+		insert_return_type insert_or_assign( const key_type& k, M&& obj )
+		{
+			insert_return_type result = base_type::try_insert( k, nv::forward<M>( obj ) );
+			if ( !result.second ) result.first->second = obj;
+			return result;
+		}
+
+		template < typename M >
+		insert_return_type insert_or_assign( key_type&& k, M&& obj )
+		{
+			insert_return_type result = base_type::try_insert( nv::forward<key_type>( k ), nv::forward<M>( obj ) );
+			if ( !result.second ) result.first->second = obj;
+			return result;
+		}
+
 		// STL compatibility only, hint unused
 		iterator insert( const_iterator, const value_type& value )
Index: trunk/nv/stl/utility/pair.hh
===================================================================
--- trunk/nv/stl/utility/pair.hh	(revision 407)
+++ trunk/nv/stl/utility/pair.hh	(revision 408)
@@ -30,6 +30,14 @@
 			: first( f ), second( s ) {}
 
-		constexpr pair( first_type&& f, second_type&& s )
-			: first( ::nv::forward<first_type>( f ) ), second( ::nv::forward<second_type>( s ) ) {}
+		template < typename U1, typename U2 >
+		constexpr pair( U1&& f, U2&& s )
+			: first( ::nv::forward<U1>( f ) ), second( ::nv::forward<U2>( s ) ) {}
+		template < typename U1, typename U2 >
+		constexpr pair( const U1& f, U2&& s )
+			: first( f ), second( ::nv::forward<U2>( s ) ) {}
+		template < typename U1, typename U2 >
+		constexpr pair( U1&& f, const U2& s )
+			: first( ::nv::forward<U1>( f ) ), second( s ) {}
+
 
 		pair( const pair& ) = default;
