Index: /trunk/nv/stl/functional.hh
===================================================================
--- /trunk/nv/stl/functional.hh	(revision 386)
+++ /trunk/nv/stl/functional.hh	(revision 386)
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+/**
+ * @file functional.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief functional
+ */
+// TODO : implement
+
+#ifndef NV_STL_FUNCTIONAL_HH
+#define NV_STL_FUNCTIONAL_HH
+
+#include <nv/core/common.hh>
+#include <nv/stl/functional/hash.hh>
+
+#endif // NV_STL_TYPE_TRAITS_HH
Index: /trunk/nv/stl/functional/hash.hh
===================================================================
--- /trunk/nv/stl/functional/hash.hh	(revision 386)
+++ /trunk/nv/stl/functional/hash.hh	(revision 386)
@@ -0,0 +1,207 @@
+// Copyright (C) 2015 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+/**
+* @file hash.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief hash classes
+*/
+
+#ifndef NV_STL_FUNCTIONAL_HASH_HH
+#define NV_STL_FUNCTIONAL_HASH_HH
+
+#include <nv/core/common.hh>
+#include <nv/stl/limits.hh>
+#include <nv/stl/type_traits/properties.hh>
+
+namespace nv
+{
+
+	namespace detail
+	{
+
+		// via http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-source (FNV-1a)
+
+		template < typename H >
+		struct fnv_hash_values;
+
+		template <>
+		struct fnv_hash_values< uint32 >
+		{
+			static constexpr uint32 basis = 2166136261UL;
+			static constexpr uint32 prime = 16777619UL;
+		};
+
+		template <>
+		struct fnv_hash_values< uint64 >
+		{
+			static constexpr uint64 basis = 14695981039346656037ULL;
+			static constexpr uint64 prime = 1099511628211ULL;
+		};
+
+		template < typename H >
+		struct fnv_hash
+		{
+			static constexpr H hash_basis = fnv_hash_values< H >::basis;
+			static constexpr H hash_prime = fnv_hash_values< H >::prime;
+
+			static constexpr H string_hash( const char* str, H basis = hash_basis )
+			{
+				return str != nullptr ? str_hash_impl( str[0], str + 1, basis ) : 0;
+			}
+			template < typename T >
+			static constexpr H hash( const T* p, size_t sz, H basis = hash_basis )
+			{
+				return p != nullptr ? hash_impl( reinterpret_cast<const char*>(p), sizeof(T)*sz, basis ) : 0;
+			}
+		protected:
+			constexpr H str_hash_impl( char c, const char* remain, H value )
+			{
+				return c == 0 ? value : str_hash_impl( remain[0], remain + 1, (H)(H)( value ^ (H)c ) * hash_prime );
+			}
+			constexpr H hash_impl( const char* current, size_t remain, H value )
+			{
+				return remain == 0 ? value : hash_impl( current + 1, remain - 1, (H)(H)( value ^ (H)(current[0]) ) * hash_prime );
+			}
+		};
+
+		template < typename T, typename H >
+		struct hash_base
+		{
+			typedef T argument_type;
+			typedef H result_type;
+		};
+
+	}
+
+	template < typename T, typename H = size_t >
+	struct hash : detail::hash_base< T, H >
+	{
+		typedef T argument_type;
+		typedef H result_type;
+		H operator()( T value ) const;
+	};
+
+	template < typename T >
+	struct hash< T*, uintptr_t > : detail::hash_base< T, uintptr_t >
+	{
+		inline uintptr_t operator()( T* value ) const { return reinterpret_cast<uintptr_t>( value ); }
+	};
+
+#define NV_TRIVIAL_HASH( T ) \
+	template < typename H > struct hash< T, H > : detail::hash_base< T, H > \
+	{ \
+		inline H operator()( T value ) const { return static_cast<H>( value ); } \
+		static constexpr H get( T value ) { return static_cast<H>( value ); } \
+	};
+
+NV_TRIVIAL_HASH( bool )
+NV_TRIVIAL_HASH( char )
+NV_TRIVIAL_HASH( sint8 )
+NV_TRIVIAL_HASH( uint8 )
+NV_TRIVIAL_HASH( sint16 )
+NV_TRIVIAL_HASH( uint16 )
+NV_TRIVIAL_HASH( sint32 )
+NV_TRIVIAL_HASH( uint32 )
+NV_TRIVIAL_HASH( sint64 )
+NV_TRIVIAL_HASH( uint64 )
+
+#undef NV_TRIVIAL_HASH
+
+	// TODO: hash is not compile-time, probably not needed, but doable?
+	template < typename H > 
+	struct hash< float, H > : detail::hash_base< float, H >
+	{
+		static constexpr H get( float value )
+		{
+			return value == 0.0f ? detail::fnv_hash<H>( &value, 1 ) : 0;
+		};
+		inline H operator()( float value ) const { return hash( value ); }
+	};
+
+	// TODO: hash is not compile-time, probably not needed, but doable?
+	template < typename H >
+	struct hash< double, H > : detail::hash_base< double, H >
+	{
+		static constexpr H get( double value )
+		{
+			return value == 0.0f ? detail::fnv_hash<H>( &value, 1 ) : 0;
+		};
+		inline H operator()( float value ) const { return hash( value ); }
+	};
+
+	template < typename H, typename T >
+	constexpr H hash_value( const T& value )
+	{
+		return hash<T, H>::get( h );
+	}
+
+	template < typename H, typename T >
+	constexpr H hash_combine( H seed, const T& h )
+	{
+		return seed ^ hash<T, H>::get( h ) + 0x9e3779b9 + ( seed << 6 ) + ( seed >> 2 );
+	}
+
+	template < typename Iterator, typename H >
+	inline H hash_range( Iterator first, Iterator last, H seed = 0 )
+	{
+		for ( ; first != last; ++first )
+		{
+			seed = hash_combine< H >( seed, *first );
+		}
+		return seed;
+	}
+
+	template < typename H >
+	constexpr H hash_string( const char* s )
+	{
+		return detail::fnv_hash<H>::string_hash( s );
+	}
+
+	template < typename H >
+	constexpr H hash_string( const char* s, size_t length )
+	{
+		return detail::fnv_hash<H>::hash( s, length );
+	}
+
+
+	template < typename T, typename H, bool StoreElement = true >
+	struct hashed_element;
+
+	template < typename T, typename H >
+	struct hashed_element< T, H, true >
+	{
+		typedef hashed_element< T, H, true > this_type;
+		typedef T hash_type;
+		typedef H value_type;
+
+		H hash;
+		T value;
+
+		constexpr hashed_element( const T& v, H h ) : value(v), hash( h ) {}
+		constexpr hashed_element( T&& v, H h ) : value( std::forward<T>(v) ), hash( h ) {}
+
+		hashed_element( const hashed_element& ) = default;
+		hashed_element( hashed_element&& ) = default;
+		hashed_element& operator=( const hashed_element& ) = default;
+		hashed_element& operator=( hashed_element&& ) = default;
+	};
+
+	template < typename T, typename H >
+	struct hashed_element< T, H, false >
+	{
+		H hash;
+		constexpr hashed_element( const T&, H h ) : hash(h) {}
+
+		hashed_element( const hashed_element& ) = default;
+		hashed_element( hashed_element&& ) = default;
+		hashed_element& operator=( const hashed_element& ) = default;
+		hashed_element& operator=( hashed_element&& ) = default;
+	};
+
+}
+
+#endif // NV_STL_FUNCTIONAL_HASH_HH
