Index: /trunk/nv/stl/functional.hh
===================================================================
--- /trunk/nv/stl/functional.hh	(revision 386)
+++ /trunk/nv/stl/functional.hh	(revision 387)
@@ -14,6 +14,11 @@
 #define NV_STL_FUNCTIONAL_HH
 
-#include <nv/core/common.hh>
+#include <nv/stl/functional/common.hh>
 #include <nv/stl/functional/hash.hh>
+#include <nv/stl/functional/reference.hh>
+#include <nv/stl/functional/bitwise_ops.hh>
+#include <nv/stl/functional/logical_ops.hh>
+#include <nv/stl/functional/arithmetic_ops.hh>
+#include <nv/stl/functional/comparisons.hh>
 
 #endif // NV_STL_TYPE_TRAITS_HH
Index: /trunk/nv/stl/functional/arithmetic_ops.hh
===================================================================
--- /trunk/nv/stl/functional/arithmetic_ops.hh	(revision 387)
+++ /trunk/nv/stl/functional/arithmetic_ops.hh	(revision 387)
@@ -0,0 +1,178 @@
+// 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 arithmetic_ops.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief arithmetic function objects
+*/
+
+#ifndef NV_STL_FUNCTIONAL_ARITHMETIC_OPS_HH
+#define NV_STL_FUNCTIONAL_ARITHMETIC_OPS_HH
+
+#include <nv/stl/functional/common.hh>
+
+namespace nv
+{
+	template< typename T = void >
+	struct plus
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr T operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs + rhs;
+		}
+	};
+
+	template<>
+	struct plus< void >
+	{
+		typedef is_transparent_t is_transparent;
+		
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) + static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) + static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct minus
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr T operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs - rhs;
+		}
+	};
+
+	template<>
+	struct minus< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) - static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) - static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct multiplies
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr T operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs * rhs;
+		}
+	};
+
+	template<>
+	struct multiplies< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) * static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) * static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct divides
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr T operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs / rhs;
+		}
+	};
+
+	template<>
+	struct divides< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) / static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) / static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct modulus
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr T operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs % rhs;
+		}
+	};
+
+	template<>
+	struct modulus< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) % static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) % static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct negate
+	{
+		typedef T result_type;
+		typedef T argument_type;
+
+		constexpr T operator() ( const T& arg ) const
+		{
+			return -arg;
+		}
+	};
+
+	template<>
+	struct negate< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T >
+		constexpr auto operator() ( T&& arg ) const
+			-> decltype( -static_cast<T&&>( arg )  )
+		{
+			return -static_cast<T&&>( arg );
+		}
+	};
+
+}
+
+#endif // NV_STL_FUNCTIONAL_ARITHMETIC_OPS_HH
+
Index: /trunk/nv/stl/functional/bitwise_ops.hh
===================================================================
--- /trunk/nv/stl/functional/bitwise_ops.hh	(revision 387)
+++ /trunk/nv/stl/functional/bitwise_ops.hh	(revision 387)
@@ -0,0 +1,101 @@
+// 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 bitwise_ops.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief functional bitwise function objects
+*/
+
+#ifndef NV_STL_FUNCTIONAL_BITWISE_OPS_HH
+#define NV_STL_FUNCTIONAL_BITWISE_OPS_HH
+
+#include <nv/stl/functional/common.hh>
+
+namespace nv
+{
+
+	template< typename T = void >
+	struct bit_and
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr bool operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs & rhs;
+		}
+	};
+
+	template<>
+	struct bit_and< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) & static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) & static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct bit_or
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr bool operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs | rhs;
+		}
+	};
+
+	template<>
+	struct bit_or< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) | static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) | static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct bit_xor
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr bool operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs ^ rhs;
+		}
+	};
+
+	template<>
+	struct bit_xor< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) ^ static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) ^ static_cast<T2&&>( rhs );
+		}
+	};
+
+}
+
+#endif // NV_STL_FUNCTIONAL_BITWISE_OPS_HH
Index: /trunk/nv/stl/functional/common.hh
===================================================================
--- /trunk/nv/stl/functional/common.hh	(revision 387)
+++ /trunk/nv/stl/functional/common.hh	(revision 387)
@@ -0,0 +1,23 @@
+// 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 common.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief functional common
+*/
+
+#ifndef NV_STL_FUNCTIONAL_COMMON_HH
+#define NV_STL_FUNCTIONAL_COMMON_HH
+
+#include <nv/core/common.hh>
+
+namespace nv
+{
+	struct is_transparent_t {};
+}
+
+#endif // NV_STL_FUNCTIONAL_COMMON_HH
Index: /trunk/nv/stl/functional/comparisons.hh
===================================================================
--- /trunk/nv/stl/functional/comparisons.hh	(revision 387)
+++ /trunk/nv/stl/functional/comparisons.hh	(revision 387)
@@ -0,0 +1,155 @@
+// 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 comparisons.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief functional comparisons
+*/
+
+#ifndef NV_STL_FUNCTIONAL_COMPARISONS_HH
+#define NV_STL_FUNCTIONAL_COMPARISONS_HH
+
+#include <nv/stl/functional/common.hh>
+
+namespace nv
+{
+
+	template< typename T = void >
+	struct not_equal_to
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr bool operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs != rhs;
+		}
+	};
+
+	template<>
+	struct not_equal_to< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) != static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) != static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct greater
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr bool operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs > rhs;
+		}
+	};
+
+	template<>
+	struct greater< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) > static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) > static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct less
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr bool operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs < rhs;
+		}
+	};
+
+	template<>
+	struct less< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) < static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) < static_cast<T2&&>( rhs );
+		}
+	};
+
+
+	template< typename T = void >
+	struct greater_equal
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr bool operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs >= rhs;
+		}
+	};
+
+	template<>
+	struct greater_equal< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) >= static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) >= static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct less_equal
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr bool operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs <= rhs;
+		}
+	};
+
+	template<>
+	struct less_equal< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) <= static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) <= static_cast<T2&&>( rhs );
+		}
+	};
+
+}
+
+#endif // NV_STL_FUNCTIONAL_COMPARISONS_HH
+
Index: /trunk/nv/stl/functional/hash.hh
===================================================================
--- /trunk/nv/stl/functional/hash.hh	(revision 386)
+++ /trunk/nv/stl/functional/hash.hh	(revision 387)
@@ -14,5 +14,5 @@
 #define NV_STL_FUNCTIONAL_HASH_HH
 
-#include <nv/core/common.hh>
+#include <nv/stl/functional/common.hh>
 #include <nv/stl/limits.hh>
 #include <nv/stl/type_traits/properties.hh>
Index: /trunk/nv/stl/functional/logical_ops.hh
===================================================================
--- /trunk/nv/stl/functional/logical_ops.hh	(revision 387)
+++ /trunk/nv/stl/functional/logical_ops.hh	(revision 387)
@@ -0,0 +1,100 @@
+// 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 logical_ops.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief functional logical function objects
+*/
+
+#ifndef NV_STL_FUNCTIONAL_LOGICAL_OPS_HH
+#define NV_STL_FUNCTIONAL_LOGICAL_OPS_HH
+
+#include <nv/stl/functional/common.hh>
+
+namespace nv
+{
+
+	template< typename T = void >
+	struct logical_and
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr bool operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs && rhs;
+		}
+	};
+
+	template<>
+	struct logical_and< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) && static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) && static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct logical_or
+	{
+		typedef T result_type;
+		typedef T first_argument_type;
+		typedef T second_argument_type;
+
+		constexpr bool operator() ( const T& lhs, const T& rhs ) const
+		{
+			return lhs || rhs;
+		}
+	};
+
+	template<>
+	struct logical_or< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T1, typename T2 >
+		constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
+			-> decltype( static_cast<T1&&>( lhs ) || static_cast<T2&&>( rhs ) )
+		{
+			return static_cast<T1&&>( lhs ) || static_cast<T2&&>( rhs );
+		}
+	};
+
+	template< typename T = void >
+	struct logical_not
+	{
+		typedef T result_type;
+		typedef T argument_type;
+
+		constexpr T operator() ( const T& arg ) const
+		{
+			return !arg;
+		}
+	};
+
+	template<>
+	struct logical_not< void >
+	{
+		typedef is_transparent_t is_transparent;
+
+		template < typename T >
+		constexpr auto operator() ( T&& arg ) const
+			-> decltype( !static_cast<T&&>( arg ) )
+		{
+			return !static_cast<T&&>( arg );
+		}
+	};
+
+}
+
+#endif // NV_STL_FUNCTIONAL_LOGICAL_OPS_HH
Index: /trunk/nv/stl/functional/reference.hh
===================================================================
--- /trunk/nv/stl/functional/reference.hh	(revision 387)
+++ /trunk/nv/stl/functional/reference.hh	(revision 387)
@@ -0,0 +1,83 @@
+// 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 reference.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief reference_wrapper class and ref/cref
+ */
+
+#ifndef NV_STL_FUNCTIONAL_REFERENCE_HH
+#define NV_STL_FUNCTIONAL_REFERENCE_HH
+
+#include <nv/core/common.hh>
+
+namespace nv
+{
+
+	template < typename T >
+	class reference_wrapper
+	{
+	public:
+		typedef T type;
+
+		reference_wrapper( type& ref ) noexcept : m_pointer( std::addressof( ref ) ) {}
+		reference_wrapper( type&& ) = delete;
+		reference_wrapper( const reference_wrapper& ) noexcept = default;
+		reference_wrapper& operator=( const reference_wrapper& ) noexcept = default;
+		operator type& ( ) const noexcept { return *m_pointer; }
+		type& get() const noexcept { return *m_pointer; }
+	private:
+		type* m_pointer;
+	};
+
+	template< typename T > 
+	inline reference_wrapper< T > ref( T& arg ) noexcept
+	{
+		return reference_wrapper< T >( arg );
+	}
+
+	template< typename T >
+	void ref( const T&& ) = delete;
+
+	template< typename T >
+	inline reference_wrapper< T > ref( reference_wrapper<T> arg ) noexcept
+	{
+		return nv::ref( arg.get() );
+	}
+
+	template< typename T >
+	inline reference_wrapper< const T > cref( const T& arg ) noexcept
+	{
+		return reference_wrapper< const T >( arg );
+	}
+
+	template< typename T >
+	void cref( const T&& ) = delete;
+
+	template< typename T >
+	inline reference_wrapper< const T > cref( reference_wrapper<T> arg ) noexcept
+	{
+		return nv::cref( arg.get() );
+	}
+
+	template< typename T >
+	struct unwrap_reference
+	{
+		typedef T type;
+		static constexpr bool is_wrapped = false;
+	};
+
+	template< typename T >
+	struct unwrap_reference< reference_wrapper< T > >
+	{
+		typedef T& type;
+		static constexpr bool is_wrapped = true;
+	};
+
+}
+
+#endif // NV_STL_FUNCTIONAL_REFERENCE_HH
Index: /trunk/nv/stl/type_traits/transforms.hh
===================================================================
--- /trunk/nv/stl/type_traits/transforms.hh	(revision 386)
+++ /trunk/nv/stl/type_traits/transforms.hh	(revision 387)
@@ -201,12 +201,12 @@
 			remove_extent_t<U>*,
 			conditional_t <
-				is_function<U>::value,
-				add_pointer_t<U>,
-				remove_cv_t<U>
+			is_function<U>::value,
+			add_pointer_t<U>,
+			remove_cv_t<U>
 			>
 		> type;
 	};
 
-	template< typename T > 
+	template< typename T >
 	using decay_t = typename decay<T>::type;
 
Index: /trunk/nv/stl/utility.hh
===================================================================
--- /trunk/nv/stl/utility.hh	(revision 386)
+++ /trunk/nv/stl/utility.hh	(revision 387)
@@ -14,32 +14,6 @@
 #define NV_STL_UTILITY_HH
 
-#include <nv/core/common.hh>
-#include <nv/stl/type_traits/common.hh>
-
-namespace nv
-{
-
-	// TODO: change to swap<T> once you get rid of STL
-	template< typename T, typename U >
-	void swap( T& x, U& y )
-	{
-		T t = move( x );
-		x = move( y );
-		y = move( t );
-	}
-
-	template < typename T >
-	inline const T&	max( const T& a, const T& b )
-	{
-		return a < b ? b : a;
-	}
-
-	template < typename T >
-	inline const T&	min( const T& a, const T& b )
-	{
-		return a > b ? b : a;
-	}
-
-}
+#include <nv/stl/utility/common.hh>
+#include <nv/stl/utility/pair.hh>
 
 #endif // NV_STL_UTILITY_HH
Index: /trunk/nv/stl/utility/common.hh
===================================================================
--- /trunk/nv/stl/utility/common.hh	(revision 387)
+++ /trunk/nv/stl/utility/common.hh	(revision 387)
@@ -0,0 +1,43 @@
+#pragma once
+// 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 common.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief STL common utility library
+*/
+
+#ifndef NV_STL_UTILITY_COMMON_HH
+#define NV_STL_UTILITY_COMMON_HH
+
+#include <nv/core/common.hh>
+#include <nv/stl/type_traits/common.hh>
+
+namespace nv
+{
+	template< typename T, typename U >
+	void swap( T& x, U& y )
+	{
+		T t = move( x );
+		x = move( y );
+		y = move( t );
+	}
+
+	template < typename T >
+	inline const T&	max( const T& a, const T& b )
+	{
+		return a < b ? b : a;
+	}
+
+	template < typename T >
+	inline const T&	min( const T& a, const T& b )
+	{
+		return a > b ? b : a;
+	}
+}
+
+#endif // NV_STL_UTILITY_COMMON_HH
Index: /trunk/nv/stl/utility/make_pair.hh
===================================================================
--- /trunk/nv/stl/utility/make_pair.hh	(revision 387)
+++ /trunk/nv/stl/utility/make_pair.hh	(revision 387)
@@ -0,0 +1,45 @@
+// 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 make_pair.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief STL make_pair library
+*/
+
+#ifndef NV_STL_UTILITY_MAKE_PAIR_HH
+#define NV_STL_UTILITY_MAKE_PAIR_HH
+
+#include <nv/stl/utility/pair.hh>
+#include <nv/stl/type_traits/transforms.hh> // nv::decay
+#include <nv/stl/functional/reference.hh> // nv::unwrap_reference
+
+namespace nv
+{
+	template< typename T >
+	struct decay_and_unwrap
+	{
+		typedef typename decay<T>::type decayed_type;
+		typedef typename unwrap_reference<decayed_type>::type type;
+		static constexpr bool is_wrapped = unwrap_reference<decayed_type>::is_wrapped;
+	};
+
+	template< typename T1, typename T2 > 
+	constexpr pair<
+		typename decay_and_unwrap< T1 >::type,
+		typename decay_and_unwrap< T2 >::type
+	>
+	make_pair( T1&& first, T2&& second )
+	{
+		return pair< 
+			typename decay_and_unwrap< T1 >::type,
+			typename decay_and_unwrap< T2 >::type
+		>( nv::forward< T1 >( first ), nv::forward< T2 >( second ) );
+	}
+
+}
+
+#endif // NV_STL_UTILITY_MAKE_PAIR_HH
Index: /trunk/nv/stl/utility/pair.hh
===================================================================
--- /trunk/nv/stl/utility/pair.hh	(revision 387)
+++ /trunk/nv/stl/utility/pair.hh	(revision 387)
@@ -0,0 +1,104 @@
+// 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 pair.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief STL pair library
+*/
+
+#ifndef NV_STL_UTILITY_PAIR_HH
+#define NV_STL_UTILITY_PAIR_HH
+
+#include <nv/stl/utility/common.hh>
+
+namespace nv
+{
+
+	template < typename T1, typename T2 >
+	struct pair
+	{
+		typedef pair< T1, T2 > this_type;
+		typedef T1 first_type;
+		typedef T2 second_type;
+
+		constexpr pair() : first(), second() {}
+		constexpr pair( const T1& f, const T2& s )
+			: first( f ), second( s )
+
+			pair( const pair& ) = default;
+		pair( pair&& ) = default;
+
+		this_type& operator= ( this_type&& rhs )
+		{
+			first = forward<first_type>( rhs.first );
+			second = forward<first_type>( rhs.second );
+		}
+
+		this_type& operator= ( const this_type& rhs )
+		{
+			first = rhs.first;
+			second = rhs.second;
+		}
+
+		void swap( this_type& rhs )
+		{
+			if ( this != &rhs )
+			{
+				swap( first, rhs.first );
+				swap( second, rhs.second );
+			}
+		}
+
+		first_type  first;
+		second_type second;
+	};
+
+	template < typename T1, typename T2 >
+	void swap( pair< T1, T2 >& lhs, pair< T1, T2 >& rhs )
+	{
+		lhs.swap( rhs );
+	}
+
+	template < typename T1, typename T2 >
+	constexpr bool operator== ( const pair< T1, T2 >& lhs, const pair< T1, T2 >& rhs )
+	{
+		return lhs.first == rhs.first && lhs.second == rhs.second;
+	}
+
+	template < typename T1, typename T2 >
+	constexpr bool operator!= ( const pair< T1, T2 >& lhs, const pair< T1, T2 >& rhs )
+	{
+		return !( lhs == rhs );
+	}
+
+	template < typename T1, typename T2 >
+	constexpr bool operator< ( const pair< T1, T2 >& lhs, const pair< T1, T2 >& rhs )
+	{
+		return lhs.first < rhs.first || ( !( rhs.first < lhs.first ) && lhs.second < rhs.second );
+	}
+
+	template < typename T1, typename T2 >
+	constexpr bool operator> ( const pair< T1, T2 >& lhs, const pair< T1, T2 >& rhs )
+	{
+		return ( rhs < lhs );
+	}
+
+	template < typename T1, typename T2 >
+	constexpr bool operator<= ( const pair< T1, T2 >& lhs, const pair< T1, T2 >& rhs )
+	{
+		return !( rhs < lhs );
+	}
+
+	template < typename T1, typename T2 >
+	constexpr bool operator>= ( const pair< T1, T2 >& lhs, const pair< T1, T2 >& rhs )
+	{
+		return !( lhs < rhs );
+	}
+
+}
+
+#endif // NV_STL_UTILITY_PAIR_HH
