Index: /trunk/nv.lua
===================================================================
--- /trunk/nv.lua	(revision 367)
+++ /trunk/nv.lua	(revision 368)
@@ -4,5 +4,5 @@
 	kind "StaticLib"
 	includedirs { "." }
-	files { "nv/core/**.hh", "nv/interface/**.hh", "nv/detail/**.inc", "src/core/**.cc" }
+	files { "nv/core/**.hh", "nv/stl/**.hh", "nv/interface/**.hh", "nv/detail/**.inc", "src/core/**.cc", "src/stl/**.cc"  }
 
 project "nv-lib"
Index: unk/nv/core/allocator.hh
===================================================================
--- /trunk/nv/core/allocator.hh	(revision 367)
+++ 	(revision )
@@ -1,61 +1,0 @@
-// 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 allocator.hh
-* @author Kornel Kisielewicz
-* @brief allocator type
-*
-* Allocator concept based on:
-*
-* http://bitsquid.blogspot.com/2010/09/custom-memory-allocation-in-c.html
-* http://www.gamedev.net/page/resources/_/technical/general-programming/c-custom-memory-allocation-r3010
-*/
-
-#ifndef NV_CORE_ALLOCATOR_HH
-#define NV_CORE_ALLOCATOR_HH
-
-#include <nv/core/common.hh>
-#include <nv/core/type_traits.hh>
-
-namespace nv
-{
-
-	class allocator
-	{
-	public:
-		virtual void* allocate( size_t size, size_t alignment ) = 0;
-		virtual void deallocate( void *p ) = 0;
-		virtual void* reallocate( void* p, size_t new_size ) = 0;
-		virtual size_t allocated_size( void *p ) = 0;
-
-		virtual size_t get_allocated_count() = 0;
-		virtual size_t get_allocated_size() = 0;
-		virtual size_t get_max_allocated_count() = 0;
-		virtual size_t get_max_allocated_size() = 0;
-
-		template < class T, typename... Args > 
-		T *create( Args&&... args ) 
-		{
-			return new ( allocate( sizeof( T ), alignof( T ) ) ) T( std::forward<Args>( args )... );
-		}
-
-		template <class T> 
-		void destroy( T *p )
-		{
-			if ( p )
-			{
-				p->~T();
-				deallocate( p );
-			}
-		}
-	};
-
-
-
-}
-
-#endif // NV_CORE_ALLOCATOR_HH
Index: unk/nv/core/any.hh
===================================================================
--- /trunk/nv/core/any.hh	(revision 367)
+++ 	(revision )
@@ -1,154 +1,0 @@
-// Copyright (C) 2014 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 any.hh
- * @author Kornel Kisielewicz
- * @brief any type
- *
- * based on http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf
- */
-
-#ifndef NV_CORE_ANY_HH
-#define NV_CORE_ANY_HH
-
-#include <nv/core/common.hh>
-#include <nv/core/type_traits.hh>
-
-namespace nv
-{
-	
-	class any
-	{
-	public:
-		any() : m_content( nullptr ) {}
-		
-		any( const any& other )
-			: m_content( other.m_content ? other.m_content->clone() : nullptr )
-		{}
-
-		template< typename T >
-		any( const T& value )
-			: m_content( new holder<T>( value ) )
-		{}
-
-		any( any&& other ) 
-			: m_content( other.m_content )
-		{}
-
-		template< typename T >
-		any( T&& value )
-			: m_content( new holder<T>( std::forward<T>(value) ) )
-		{}
-
-		~any() 
-		{ 
-			delete m_content; 
-		}
-
-		any& swap( any& rhs )
-		{
-			std::swap( m_content, rhs.m_content );
-			return *this;
-		}
-
-		any& operator=( const any& rhs )
-		{
-			return swap( any( rhs ) );
-		}
-
-		any& operator=( any&& rhs )
-		{
-			swap( rhs );
-			any().swap( rhs );
-			return *this;
-		}
-
-		template < typename T >
-		any& operator= ( T&& rhs )
-		{
-			any( std::forward<T>(rhs) ).swap(*this);
-			return *this;
-		}
-
-		operator const void* () const
-		{
-			return m_content;
-		}
-
-		template< typename T >
-		bool copy_to( T& value ) const
-		{
-			const T* copyable = to_ptr<T>();
-			if ( copyable ) value = *copyable;
-			return copyable;
-		}
-		template< typename T >
-		const T* to_ptr() const
-		{
-			return type_info() == typeid(T) ? &static_cast< holder<T> *>(m_content)->held				: nullptr;
-		}
-
-		bool empty() const
-		{
-			return !m_content;
-		}
-
-		void clear()
-		{
-			any().swap(*this);
-		}
-
-		const std::type_info &type_info() const
-		{
-			return m_content ? m_content->type_info() : typeid(void);
-		}
-	private:
-		class placeholder
-		{
-		public:
-			virtual const std::type_info& type_info() const = 0;
-			virtual placeholder *clone() const = 0;
-			virtual ~placeholder() {}
-		};
-
-		template< typename T >
-		class holder : public placeholder
-		{
-		public:
-			holder( const T& value ) : held(value)
-			{
-			}
-			holder( T&& value ) : held(std::forward<T>(value))
-			{
-			}
-			virtual const std::type_info &type_info() const
-			{
-				return typeid(T);
-			}
-			virtual placeholder *clone() const
-			{
-				return new holder(held);
-			}
-			const T held;
-		};
-		placeholder *m_content;
-	};
-
-	inline void swap( any& lhs, any& rhs )
-	{
-		lhs.swap(rhs);
-	}
-
-	template< typename T >
-	T any_cast( const any& operand )
-	{
-		const T* result = operand.to_ptr<T>();
-		return result ? *result : throw std::bad_cast();
-	}
-}
-
-#endif // NV_CORE_ANY_HH
Index: unk/nv/core/array.hh
===================================================================
--- /trunk/nv/core/array.hh	(revision 367)
+++ 	(revision )
@@ -1,197 +1,0 @@
-// Copyright (C) 2014 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 array.hh
- * @author Kornel Kisielewicz epyon@chaosforge.org
- * @brief exception free array classes
- */
-
-#ifndef NV_CORE_ARRAY_HH
-#define NV_CORE_ARRAY_HH
-
-#include <nv/core/common.hh>
-#include <vector>
-#include <algorithm>
-#include <array>
-
-namespace nv
-{
-	using std::vector;
-	using std::array;
-
-	template< class T, std::size_t N >
-	class static_array
-	{
-	public:
-		typedef T              value_type;
-		typedef T*             iterator;
-		typedef const T*       const_iterator;
-		typedef T&             reference;
-		typedef const T&       const_reference;
-		typedef std::size_t    size_type;
-		typedef std::ptrdiff_t difference_type;
-
-		typedef std::reverse_iterator<iterator>       reverse_iterator;
-		typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
-		iterator        begin()        { return m_data; }
-		const_iterator  begin()  const { return m_data; }
-		const_iterator  cbegin() const { return m_data; }
-
-		iterator        end()        { return m_data+N; }
-		const_iterator  end()  const { return m_data+N; }
-		const_iterator  cend() const { return m_data+N; }
-
-		reverse_iterator rbegin()              { return reverse_iterator( end() ); }
-		const_reverse_iterator rbegin() const  { return const_reverse_iterator( end() ); }
-		const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); }
-
-		reverse_iterator rend()                { return reverse_iterator( begin() ); }
-		const_reverse_iterator rend() const    { return const_reverse_iterator( begin() ); }
-		const_reverse_iterator crend() const   { return const_reverse_iterator( begin() ); }
-
-		reference operator[]( size_type i ) 
-		{ 
-			NV_ASSERT( i < N, "Out of range" ); 
-			return m_data[i];
-		}
-
-		const_reference operator[]( size_type i ) const 
-		{     
-			NV_ASSERT( i < N, "Out of range" ); 
-			return m_data[i]; 
-		}
-
-		reference       front()       { return m_data[0]; }
-		const_reference front() const { return m_data[0]; }
-		reference       back()        { return m_data[N-1]; }
-		const_reference back() const  { return m_data[N-1]; }
-
-		static size_type size()     { return N; }
-		static bool      empty()    { return false; }
-		static size_type max_size() { return N; }
-
-		const value_type* data() const { return m_data; }
-		value_type*       data()       { return m_data; }
-
-		size_type   raw_size() const { return N * ELEMENT_SIZE; }
-		const char* raw_data() const { return (const char*)m_data; }
-		char*       raw_data()       { return (char*)m_data; }
-
-		void assign( const value_type& value ) { std::fill_n( begin(), size(), value ); }
-
-		static const size_type SIZE = N;
-		static const size_type ELEMENT_SIZE = sizeof(T);
-	public:
-		value_type m_data[N];
-	};
-
-	template< class T >
-	class dynamic_array
-	{
-	public:
-		typedef T              value_type;
-		typedef T*             iterator;
-		typedef const T*       const_iterator;
-		typedef T&             reference;
-		typedef const T&       const_reference;
-		typedef std::size_t    size_type;
-		typedef std::ptrdiff_t difference_type;
-
-		typedef std::reverse_iterator<iterator>       reverse_iterator;
-		typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
-		dynamic_array() 
-			: m_data( nullptr ), m_size(0) {}
-		explicit dynamic_array( size_type new_size )
-			: m_data( new value_type[ new_size ] ), m_size( new_size ) {}
-		dynamic_array( const value_type& value, size_type size )
-			: m_data( nullptr ), m_size(0) { assign( value, size ); }
-		dynamic_array( const_iterator values, size_type size )
-			: m_data( nullptr ), m_size(0) { assign( values, size ); }
-
-		void resize( size_type new_size )
-		{
-			if ( new_size != m_size ) 
-			{
-				value_type* old_data = m_data;
-				m_data = new_size > 0 ? new value_type[ new_size ] : nullptr;
-				if ( old_data && m_data )
-				{
-					std::copy_n( old_data, new_size > m_size ? m_size : new_size, m_data );
-				}
-				delete[] old_data;
-				m_size = new_size;
-			}
-		}
-
-		iterator        begin()        { return m_data; }
-		const_iterator  begin()  const { return m_data; }
-		const_iterator  cbegin() const { return m_data; }
-
-		iterator        end()        { return m_data+m_size; }
-		const_iterator  end()  const { return m_data+m_size; }
-		const_iterator  cend() const { return m_data+m_size; }
-
-		reverse_iterator rbegin()              { return reverse_iterator( end() ); }
-		const_reverse_iterator rbegin() const  { return const_reverse_iterator( end() ); }
-		const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); }
-
-		reverse_iterator rend()                { return reverse_iterator( begin() ); }
-		const_reverse_iterator rend() const    { return const_reverse_iterator( begin() ); }
-		const_reverse_iterator crend() const   { return const_reverse_iterator( begin() ); }
-
-		reference operator[]( size_type i ) 
-		{ 
-			NV_ASSERT( i < m_size, "Out of range" ); 
-			return m_data[i];
-		}
-
-		const_reference operator[]( size_type i ) const 
-		{     
-			NV_ASSERT( i < m_size, "Out of range" ); 
-			return m_data[i]; 
-		}
-
-		reference       front()       { return m_data[0]; }
-		const_reference front() const { return m_data[0]; }
-		reference       back()        { return m_data[m_size-1]; }
-		const_reference back() const  { return m_data[m_size-1]; }
-
-		size_type        size() const     { return m_size; }
-		bool             empty() const    { return m_size == 0; }
-		static size_type max_size()       { return std::numeric_limits< size_type >::max(); }
-		const value_type* data() const { return m_data; }
-		value_type*       data()       { return m_data; }
-
-		size_type   raw_size() const { return m_size * ELEMENT_SIZE; }
-		const char* raw_data() const { return (const char*)m_data; }
-		char*       raw_data()       { return (char*)m_data; }
-
-		void assign( const value_type& value ) { std::fill_n( begin(), size(), value ); }
-		void assign( const value_type& value, size_type new_size ) 
-		{
-			resize( new_size );
-			std::fill_n( begin(), size(), value );
-		}
-		void assign( const_iterator values, size_type new_size )
-		{
-			resize( new_size );
-			std::copy_n( values, size(), m_data );
-		}
-
-		~dynamic_array() { delete[] m_data; }
-
-		static const size_type ELEMENT_SIZE = sizeof(T);
-	public:
-		value_type* m_data;
-		size_type   m_size;
-	};
-
-}
-
-#endif // NV_CORE_ARRAY_HH
Index: unk/nv/core/array2d.hh
===================================================================
--- /trunk/nv/core/array2d.hh	(revision 367)
+++ 	(revision )
@@ -1,356 +1,0 @@
-// Copyright (C) 2012-2014 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 array2d.hh
- * @author Kornel Kisielewicz
- * @brief 2D array
- */
-
-// TODO: make it work with the stl allocator
-
-#ifndef NV_CORE_ARRAY2D_HH
-#define NV_CORE_ARRAY2D_HH
-
-#include <nv/core/common.hh>
-#include <nv/core/math.hh>
-#include <nv/core/range.hh>
-
-namespace nv
-{
-	typedef ivec2 coord2d;
-
-	template < typename T >
-	class array2d
-	{
-	public:
-		typedef T                 value_type;
-		typedef value_type&       reference;
-		typedef const value_type& const_reference;
-		typedef value_type*       pointer;
-		typedef const value_type* const_pointer;
-		typedef pointer           iterator;
-		typedef const_pointer     const_iterator;
-
-		/**
-		 * Creates a new 2D array.
-		 */
-		array2d() : m_data( nullptr ), m_size() {}
-
-		/**
-		 * Creates a new 2D array.
-		 *
-		 * @param asize The dimensions of the new array.
-		 */
-		array2d( const ivec2& asize ) : m_data( nullptr ), m_size() { resize( asize ); }
-
-		/**
-		 * Creates a new 2D array.
-		 *
-		 * @param asize_x The width of the new array.
-		 * @param asize_y The height of the new array.
-		 */
-		array2d( const sint32 asize_x, const sint32 asize_y ) : m_data( nullptr ), m_size() { resize( new ivec2( asize_x, asize_y ) ); }
-		
-		/**
-		 * Gets the dimensions of the array.
-		 *
-		 * @returns The size of the array.
-		 */
-		const ivec2& size() const { return m_size; }
-
-		/**
-		 * Gets a pointer to the data in the array.
-		 *
-		 * @returns A pointer to the data in the array.
-		 */
-		pointer data() { return m_data; }
-
-		/**
-		 * Gets a constant pointer to the data in the array.
-		 *
-		 * @returns A constant pointer to the data in the array.
-		 */
-		const_pointer data() const { return m_data; }
-
-		/**
-		 * Changes the dimensions of the array.
-		 *
-		 * @param new_size The new dimensions of the array.
-		 * @param preserve True to keep as much of the existing data as will fit in the new array, False to discard the existing data.
-		 */
-		void resize( const ivec2& new_size, bool preserve = false ) 
-		{
-			if (new_size == m_size) return; // Don't do anything if the sizes are the same.
-
-			pointer new_data = ( (new_size.x * new_size.y != 0) ? new value_type[ new_size.x * new_size.y ] : nullptr );
-			if ( m_data != nullptr )
-			{
-				if ( new_data && preserve )
-				{
-					// Copy the data.  Truncates the bottom or right side of the data if destination is smaller.
-					for ( sint32 i = 0; i < min(new_size.y, m_size.y); i++ )
-					{
-						std::copy( m_data + m_size.x * i, m_data + m_size.x * i + min( new_size.x, m_size.x ), new_data + m_size.x * i );
-					}
-				}
-				delete[] m_data;
-			}
-			m_data = new_data;
-			m_size = new_size;
-		}
-
-		/**
-		 * Gets a pointer to the start of the array.
-		 *
-		 * @returns A pointer to the first position in the array.
-		 */
-		iterator       begin()       { return m_data; }
-
-		/**
-		 * Gets a constant pointer to the start of the array.
-		 *
-		 * @returns A constant pointer to the first position in the array.
-		 */
-		const_iterator begin() const { return m_data; }
-
-		/**
-		 * Gets a pointer to the end of the array.
-		 *
-		 * @returns A pointer to the end of the array.
-		 */
-		iterator       end()         { return m_data + ( m_size.x * m_size.y ); }
-
-		/**
-		 * Gets a constant pointer to the end of the array.
-		 *
-		 * @returns A constant pointer to the end of the array.
-		 */
-		const_iterator end() const   { return m_data + ( m_size.x * m_size.y ); }
-
-
-		/**
-		 * Looks up a position by X and Y value.
-		 *
-		 * @param x The X position of the array to look up.
-		 * @param y The Y position of the array to look up.
-		 * @returns A reference to the data at the indicated position.
-		 */
-		inline const_reference operator() ( sint32 x, sint32 y ) const
-		{
-			NV_ASSERT( x >= 0 && y >= 0 && x < m_size.x && y < m_size.y, "Bad parameters passed to array2d()" );
-			return m_data[ y * m_size.x + x ];
-		}
-
-		/**
-		 * Looks up a position by X and Y value.
-		 *
-		 * @param x The X position of the array to look up.
-		 * @param y The Y position of the array to look up.
-		 * @returns A reference to the data at the indicated position.
-		 */
-		inline reference operator() ( sint32 x, sint32 y )
-		{
-			NV_ASSERT( x >= 0 && y >= 0 && x < m_size.x && y < m_size.y, "Bad parameters passed to array2d()" );
-			return m_data[ y * m_size.x + x ];
-		}
-
-		/**
-		 * Looks up the given position in the array.
-		 *
-		 * @param c The position to look up.
-		 * @returns A reference to the data at the indicated position.
-		 */
-		inline const_reference operator[] ( const ivec2& c ) const 
-		{
-			NV_ASSERT( c.x >= 0 && c.y >= 0 && c.x < m_size.x && c.y < m_size.y, "Bad parameters passed to array2d[]" );
-			return m_data[ c.y * m_size.x + c.x ];
-		}
-
-		/**
-		 * Looks up the given position in the array.
-		 *
-		 * @param c The position to look up.
-		 * @returns A reference to the data at the indicated position.
-		 */
-		inline reference operator[] ( const ivec2& c )
-		{
-			NV_ASSERT( c.x >= 0 && c.y >= 0 && c.x < m_size.x && c.y < m_size.y, "Bad parameters passed to array2d[]" );
-			return m_data[ c.y * m_size.x + c.x ];
-		}
-
-		/**
-		 * Returns a copy of this array in a new instance.
-		 *
-		 * @returns An independent copy of this array.
-		 */
-		array2d<T> clone()
-		{
-			array2d<T> temp = new array2d<T>(m_size);
-			for ( sint32 i = 0; i < m_size.y; i++ )
-			{
-				std::copy( m_data + m_size.x * i, m_data + m_size.x * i + m_size.x, m_size.x * i );
-			}
-			return temp;
-		}
-
-		/**
-		 * Returns an array that represents a subset of the data in this array.
-		 *
-		 * @param start The upper and left bounds of data to retrieve.
-		 * @param size The width and height of the data to retrieve.
-		 * @returns A new 2D array containing the subset of data within the bounds specified.
-		 */
-		array2d<T> get_sub_array( const ivec2& start, const ivec2& size ) {	return get_sub_array( start.x, start.y, size.x, size.y ); }
-
-		/**
-		 * Returns an array that represents a subset of the data in this array.
-		 *
-		 * @param start_x The left bound of the data to retrieve.
-		 * @param start_y The upper bound of the data to retrieve.
-		 * @param size_x The width of the data to retrieve.
-		 * @param size_y The height of the data to retrieve.
-		 * @returns A new 2D array containing the subset of data within the bounds specified.
-		 */
-		array2d<T> get_sub_array( const sint32 start_x, const sint32 start_y, const sint32 size_x, const sint32 size_y)
-		{
-			// Make sure the parameters are correct and in bounds.
-			NV_ASSERT( start_x >= 0 && start_x < m_size.x && start_y >= 0 && start_y < m_size.y, "get_sub_array: start is out of bounds." );
-			NV_ASSERT( size_x >= 1 && size_x + start_x <= m_size.x && size_y >= 1 && size_y + start_y <= m_size.y, "get_sub_array: size is invalid." );
-			// Empty holder for the sub array of the correct size.
-			array2d<T> temp = new array2d<T>( size_x, size_y );
-			for ( sint32 i = start_y; i < start_y + size_y; i++ )
-			{
-				// Copy starts at start_x.
-				// Copy end is the end position.
-				// Destination is the start of the destination row.
-				//         Start                              End                                         Destination
-				std::copy( m_data + m_size().x * i + start_x, m_data + m_size().x * i + start_x + size_x, temp.m_data + temp.m_size().x * ( i - start_y ) );
-			}
-			return temp;
-		}
-
-		/**
-		 * Fills this array with another array.
-		 *
-		 * @param source The array to fill with.  If it does not fit in the destination it will be truncated.
-		 * @param dest_start The upper and left bounds of the data to fill.
-		 */
-		void set_sub_array( const array2d<T> source, const ivec2& dest_start )
-		{
-			return set_sub_array( source, dest_start.x, dest_start.y, 0, 0, source.m_size.x, source.m_size.y );
-		}
-
-		/**
-		 * Fills this array with a subset of another array.
-		 *
-		 * @param source The arrya to fill with.  If it does not fit in the destination it will be truncated.
-		 * @param dest_start The upper and left bounds of the data to fill.
-		 * @param size The size of the area to copy over.
-		 */
-		void set_sub_array( const array2d<T> source, const ivec2& dest_start, const ivec2& size )
-		{
-			return set_sub_array( source, dest_start.x, dest_start.y, 0, 0, size.x, size.y );
-		}
-
-
-		/**
-		 * Fills this array with a subset of another array.
-		 *
-		 * @param source The array to fill with.  If it does not fit in the destination it will be truncated.
-		 * @param dest_start The upper and left bounds of the data to fill.
-		 * @param source_start The upper and left bounds of the source to fill with.
-		 * @param size The size of the area to copy over.
-		 */
-		void set_sub_array( const array2d<T> source, const ivec2& dest_start, const ivec2& source_start, const ivec2& size )
-		{
-			return set_sub_array( source, dest_start.x, dest_start.y, source_start.x, source_start.y, size.x, size.y );
-		}
-
-		/**
-		 * Fills this array with another array.
-		 *
-		 * @param source The array to fill with.  If it does not fit in the area to fill, it will be truncated.
-		 * @param dest_start_x The left bound of the data to fill.
-		 * @param dest_start_y The upper bound of the data to fill.
-		 */
-		void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y )
-		{
-			return set_sub_array( source, dest_start_x, dest_start_y, 0, 0, source.m_size.x, source.m_size.y );
-		}
-
-		/**
-		 * Fills this array with another array.
-		 *
-		 * @param source The array to fill with.  If it does not fit in the area to fill, it will be truncated.
-		 * @param dest_start_x The left bound of the data to fill.
-		 * @param dest_start_y The upper bound of the data to fill.
-		 * @param size_x The width of the area to copy over.
-		 * @param size_y The height of the area to copy over.
-		 */
-		void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y, const sint32 size_x, const sint32 size_y )
-		{
-			return set_sub_array( source, dest_start_x, dest_start_y, 0, 0, size_x, size_y );
-		}
-
-		/**
-		 * Fills this array with a subset of another array.
-		 *
-		 * @param source The array to fill with.  If it does not fit in the area to fill, it will be truncated.
-		 * @param dest_start_x The left bound of the data to fill.
-		 * @param dest_start_y The upper bound of the data to fill.
-		 * @param source_start_x The left bound of the source to fill with.
-		 * @param source_start_y The upper bound of the source to fill with.
-		 * @param size_x The width of the area to copy over.
-		 * @param size_y The height of the area to copy over.
-		 */
-		void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y, const sint32 source_start_x, const sint32 source_start_y, const sint32 size_x, const sint32 size_y )
-		{
-			// Start by checking the parameters.  Make sure nothing is out of bounds.
-			NV_ASSERT( source != nullptr, "set_sub_array: no source defined." );
-			NV_ASSERT( dest_start_x >= 0 && dest_start_x < m_size.x && dest_start_y >= 0 && dest_start_y < m_size.y, "set_sub_array: destination start is out of bounds." );
-			NV_ASSERT( source_start_x >= 0 && source_start_x < source.m_size.x && source_start_y >= 0 && source_start_y < source.m_size.y, "set_sub_array: source start is out of bounds." );
-			NV_ASSERT( size_x >= 1 && size_y >= 1, "set_sub_array: invalid size specified." ); // If size is 0, nothing would be copied in the first place.
-		
-			// Warn when copied data is truncated.
-			// If the end of the copied area is beyond the bounds of the destination array, data will be truncated.
-			if ( dest_start_x + min(size_x, source.m_size.x - source_start_x) > m_size.x || dest_start_y + min(size_y, source.m_size.y - source_start_y) > m_size.y )
-			{
-				//NV_LOG_WARNING( "set_sub_array: Source area does not fit in the destination area.  Data will be truncated." );
-			}
-		
-			// Copy into THIS array from source the following.
-			// Highest row is either the size limit or the end of either array, whichever is smaller.
-			for ( uint32 i = 0; i < min( size_y , min ( m_size.y - dest_start_y, source.m_size.y - source_start_y ) ); i++ )
-			{
-				// Copy the indicated row.
-				// The start position is the beginning of the current row (which is source_start_y + i), offset by source_start_x.
-				// The end position is either the size limit or the end of either array, whichever is smaller.
-				// Destination start is the beginning of the current destination row (which is dest_start_y + i), offset by dest_start_x.
-				std::copy( source.m_data + ( source_start_y + i ) * source.m_size.x + source_start_x,  // Source Start
-						  source.m_data + ( source_start_y + i ) * source.m_size.x + min( source.m_size.x, min( source_start_x + size_x, source_start_x + m_size.x - dest_start_x ) ), // Source End
-						  m_data + (dest_start_y + i) * m_size.x + dest_start_x ); // Destination Start
-			}
-		}
-
-		/**
-		 * Destructor.
-		 */
-		~array2d()
-		{
-			if ( m_data != nullptr )
-			{
-				delete[] m_data;
-			}
-		}
-	protected:
-		pointer m_data; ///< Pointer to the data.
-		ivec2   m_size; ///< Allocated size of the data.
-	};
-
-}
-
-#endif // NV_CORE_ARRAY2D_HH
Index: /trunk/nv/core/common.hh
===================================================================
--- /trunk/nv/core/common.hh	(revision 367)
+++ /trunk/nv/core/common.hh	(revision 368)
@@ -137,8 +137,23 @@
 #if NV_COMPILER == NV_MSVC
 #define NV_DEPRECATED(func) __declspec(deprecated) func
+#define NV_ALIGN(value) __declspec(align(value))
+#define NV_ALIGNED_STRUCT(value) __declspec(align(value)) struct
+#define NV_RESTRICT __declspec(restrict)
+#define NV_RESTRICT_VAR __restrict
+//#define NV_CONSTEXPR 
 #elif NV_COMPILER == NV_GNUC || NV_COMPILER == NV_CLANG
 #define NV_DEPRECATED(func) func __attribute__ ((deprecated))
-#else 
+#define NV_ALIGN(value) __attribute__((aligned(value)))
+#define NV_ALIGNED_STRUCT(value) struct __attribute__((aligned(value)))
+#define NV_RESTRICT __restrict__
+#define NV_RESTRICT_VAR __restrict__
+//#define NV_CONSTEXPR constexpr 
+#else
 #define NV_DEPRECATED(func) func
+#define NV_ALIGN(value)
+#define NV_ALIGNED_STRUCT(value) struct 
+#define NV_RESTRICT
+#define NV_RESTRICT_VAR
+//#define NV_CONSTEXPR 
 #endif 
 
Index: unk/nv/core/cstring_store.hh
===================================================================
--- /trunk/nv/core/cstring_store.hh	(revision 367)
+++ 	(revision )
@@ -1,146 +1,0 @@
-// Copyright (C) 2014 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 cstring_store.hh
-* @author Kornel Kisielewicz
-* @brief cstring_store
-*/
-
-#ifndef NV_CORE_CSTRING_STORE_HH
-#define NV_CORE_CSTRING_STORE_HH
-
-#include <nv/core/common.hh>
-#include <nv/core/array.hh>
-#include <unordered_map>
-#include <cstring>
-#include <cstdlib>
-
-namespace nv
-{
-
-	namespace detail
-	{
-
-		inline char *cstring_duplicate( const char *s )
-		{
-			size_t length = std::strlen( s ) + 1;
-			void *result = std::malloc( length );
-			if ( result == nullptr ) return nullptr;
-			return (char *)std::memcpy( result, s, length );
-		}
-
-		struct cstring_compare
-		{
-			bool operator()( const char* lhs, const char* rhs ) const
-			{
-				return strcmp( lhs, rhs ) == 0;
-			}
-		};
-
-
-		struct cstring_hash
-		{
-			int operator()( const char* str ) const
-			{
-				int seed = 131;
-				int hash = 0;
-				while ( *str )
-				{
-					hash = ( hash * seed ) + ( *str );
-					str++;
-				}
-				return hash & ( 0x7FFFFFFF );
-			}
-		};
-	}
-
-	template < typename T >
-	using cstring_unordered_map = std::unordered_map < const char*, T, detail::cstring_hash, detail::cstring_compare > ;
-
-	struct cstring_deleter : public noncopyable
-	{
-	public:
-		cstring_deleter() {}
-
-		char* duplicate( const char* s )
-		{
-			char* result = detail::cstring_duplicate( s );
-			insert( result );
-			return result;
-		}
-
-		void insert( char * s )
-		{
-			m_array.push_back( s );
-		}
-
-		~cstring_deleter()
-		{
-			for ( auto s : m_array ) free( s );
-		}
-	private:
-		std::vector< char* > m_array;
-	};
-
-	class cstring_store : public noncopyable
-	{
-	public:
-		cstring_store() {}
-
-		bool exists( const char* cstr )
-		{
-			return m_map.find( cstr ) != std::end( m_map );
-		}
-		
-		const char* get( uint32 index )
-		{
-			return index < m_array.size() ? m_array[index] : nullptr;
-		}
-
-		uint32 resolve( const char* cstr )
-		{
-			auto it = m_map.find( cstr );
-			if ( it != std::end( m_map ) )
-			{
-				return it->second;
-			}
-			return uint32(-1);
-		}
-
-		uint32 push( const char* cstr )
-		{
-			char* duplicate = detail::cstring_duplicate( cstr );
-			m_array.push_back( duplicate );
-			uint32 index = (uint32)m_array.size() - 1;
-			m_map[duplicate] = index;
-			return index;
-		}
-
-		uint32 insert( const char* cstr )
-		{
-			auto it = m_map.find( cstr );
-			if ( it == std::end( m_map ) )
-			{
-				return push( cstr );
-			}
-			return it->second;
-		}
-
-
-
-		~cstring_store()
-		{
-			for ( auto s : m_array ) free( s );
-		}
-	private:
-		std::vector< char* >            m_array;
-		cstring_unordered_map< uint32 > m_map;
-	};
-
-}
-
-#endif // NV_CORE_STRING_STORE_HH
Index: unk/nv/core/exception.hh
===================================================================
--- /trunk/nv/core/exception.hh	(revision 367)
+++ 	(revision )
@@ -1,46 +1,0 @@
-// Copyright (C) 2012-2014 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 exception.hh
- * @author Kornel Kisielewicz epyon@chaosforge.org
- * @brief nv exception bases
- */
-
-#ifndef NV_CORE_EXCEPTION_HH
-#define NV_CORE_EXCEPTION_HH
-
-#include <nv/core/common.hh>
-#include <string>
-#include <exception>
-#include <stdexcept>
-
-namespace nv
-{
-	/**
-	 * NV logic_error.
-	 *
-	 * Inherits std::logic_error.
-	 */
-	class logic_error : public std::logic_error
-	{
-	public:
-		explicit logic_error( const std::string& msg ) : std::logic_error( msg ) {}
-	};
-
-	/**
-	 * NV runtime_error.
-	 *
-	 * Inherits std::runtime_error.
-	 */
-	class runtime_error : public std::runtime_error
-	{
-	public:
-		explicit runtime_error( const std::string& msg ) : std::runtime_error( msg ) {}
-	};
-}
-
-#endif // NV_CORE_EXCEPTION_HH
Index: unk/nv/core/flags.hh
===================================================================
--- /trunk/nv/core/flags.hh	(revision 367)
+++ 	(revision )
@@ -1,221 +1,0 @@
-// Copyright (C) 2012-2014 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 flags.hh
- * @author Kornel Kisielewicz
- * @brief flags
- */
-
-#ifndef NV_CORE_FLAGS_HH
-#define NV_CORE_FLAGS_HH
-
-#include <nv/core/common.hh>
-#include <nv/core/type_traits.hh>
-#include <nv/core/array.hh>
-
-namespace nv
-{
-	template < uint32 SIZE, typename T = uint32 >
-	class flags
-	{
-	public:
-		class reference
-		{
-			friend class flags<SIZE,T>;
-		public:
-			typedef bool value_type;
-			typedef T    index_type;
-
-			reference& operator=( value_type a_value )
-			{
-				m_flags->set( m_index, a_value );
-				return (*this);
-			}
-			reference& operator=( const reference& a_value )
-			{
-				m_flags->set( m_index, bool( a_value ) );
-				return (*this);
-			}
-			operator bool() const 
-			{
-				return m_flags->test( m_index );
-			}
-
-		private:
-			reference() : m_flags( nullptr ), m_index( index_type(0) ) {}
-
-			reference( flags<SIZE,T>* a_flags, index_type a_index )
-				: m_flags( a_flags ), m_index( a_index )
-			{	
-			}
-
-		private:
-			flags<SIZE,T>* m_flags;
-			index_type     m_index;
-		};
-
-		class enumerator
-		{
-			friend class flags<SIZE,T>;
-		public:
-			typedef T              index_type;
-			typedef T              value_type;
-			typedef T*             iterator;
-			typedef const T*       const_iterator;
-			typedef T&             reference;
-			typedef const T&       const_reference;
-			typedef std::size_t    size_type;
-			typedef std::ptrdiff_t difference_type;
-
-			T operator* () const { return m_index; }
-			T const* operator-> () const { return &m_index; }
-			bool operator== ( const enumerator& rhs ) const
-			{
-				return ( m_index == rhs.m_index ) && ( m_flags == rhs.m_flags );
-			}
-			bool operator!= ( const enumerator& rhs ) const
-			{
-				return !( *this == rhs );
-			}
-			
-			enumerator& operator++ () 
-			{
-				next();
-				return *this; 
-			}
-			enumerator operator++ (int) 
-			{
-				auto result = *this; 
-				++*this; 
-				return result;
-			}
-		protected:
-			enumerator() : m_flags( nullptr ), m_index( index_type(0) ) {}
-
-			enumerator( const flags<SIZE,T>* a_flags, index_type a_index )
-				: m_flags( a_flags ), m_index( a_index )
-			{	
-				if ( a_flags && !a_flags->test( a_index ) ) next();
-			}
-
-			void next()
-			{
-				if ( m_flags )
-				do 
-				{
-					if ( raw_index_type(m_index) >= SIZE ) { m_flags = nullptr; m_index = index_type(0); return; }
-					m_index = index_type((raw_index_type)m_index + 1);
-				} while ( !m_flags->test( m_index ) );
-			}
-
-			const flags<SIZE,T>* m_flags;
-			index_type           m_index;
-		};
-
-		typedef uint8     data_type;
-		typedef T         index_type;
-		typedef uint32 size_type;
-		typedef typename base_underlying_type<T>::type raw_index_type;
-
-		static const size_type data_type_size = sizeof( data_type ) * 8;
-		static const size_type data_count     = SIZE;
-		static const size_type data_size      = (SIZE+data_type_size-1) / data_type_size;
-
-		enumerator begin()  const { return enumerator( this, index_type(0) ); }
-		enumerator cbegin() const { return enumerator( this, index_type(0) ); }
-
-		enumerator end()  const { return enumerator(); }
-		enumerator cend() const { return enumerator(); }
-
-		flags()
-		{
-			reset();
-		}
-
-		explicit flags( const data_type* a_data )
-		{
-			assign( a_data );
-		}
-
-		void assign( const data_type* a_data )
-		{
-			std::copy( a_data, a_data + data_size, m_data );
-		}
-
-		void reset()
-		{
-			std::fill( m_data, m_data + data_size, 0 );
-		}
-
-		void include( index_type i )
-		{
-			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
-			raw_index_type pos = static_cast< raw_index_type >( i ) % data_type_size;
-			m_data[ idx ] |= 1 << static_cast< data_type >( pos );
-		}
-
-		void exclude( index_type i )
-		{
-			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
-			raw_index_type pos = static_cast< raw_index_type >( i ) % data_type_size;
-			m_data[ idx ] &= ~(1 << static_cast< data_type >( pos ) );
-		}
-
-		void set( index_type i, bool value )
-		{
-			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
-			raw_index_type pos = static_cast< raw_index_type >( i ) % data_type_size;
-			if ( value )
-				m_data[ idx ] |= 1 << static_cast< data_type >( pos );
-			else
-				m_data[ idx ] &= ~(1 << static_cast< data_type >( pos ) );
-		}
-
-		bool test( index_type i ) const
-		{
-			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
-			raw_index_type pos = static_cast< raw_index_type >( i ) % data_type_size;
-			return ( m_data[ idx ] & ( 1 << static_cast< data_type >( pos ) ) ) != 0;
-		}
-
-		const data_type* data() const
-		{
-			return m_data;
-		}
-
-		data_type* data()
-		{
-			return m_data;
-		}
-
-		size_type size() const
-		{
-			return data_count;
-		}
-
-		size_type capacity() const
-		{
-			return data_size;
-		}
-
-		bool operator[]( index_type idx ) const
-		{
-			return test( idx );
-		}
-
-		reference operator[]( index_type idx )
-		{
-			return reference( this, idx );
-		}
-
-	private:
-		data_type m_data[ data_size ];
-	};
-
-} // namespace nv
-
-#endif // NV_CORE_FLAGS_HH
Index: unk/nv/core/handle.hh
===================================================================
--- /trunk/nv/core/handle.hh	(revision 367)
+++ 	(revision )
@@ -1,335 +1,0 @@
-// Copyright (C) 2014 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 handle.hh
- * @author Kornel Kisielewicz
- */
-
-#ifndef NV_CORE_HANDLE_HH
-#define NV_CORE_HANDLE_HH
-
-#include <nv/core/common.hh>
-#include <nv/core/array.hh>
-
-namespace nv
-{
-
-	template < 
-		typename T = uint32, 
-		unsigned IBITS = 16,
-		unsigned CBITS = 16,
-		typename TAG = void 
-	>
-	class handle
-	{
-	public:
-		typedef T value_type;
-		typedef TAG tag_type;
-		static const int INDEX_BITS   = IBITS;
-		static const int COUNTER_BITS = IBITS;
-		static const T MAX_INDEX   = (1 << IBITS) - 1;
-		static const T MAX_COUNTER = (1 << CBITS) - 1;
-
-		handle() : m_index(0), m_counter(0) {}
-
-		inline bool operator==(const handle& rhs) const {return m_index == rhs.m_index && m_counter == rhs.m_counter; }
-		inline bool operator!=(const handle& rhs) const {return !(*this == rhs);}
-
-		bool is_nil() const { return m_index == 0 && m_counter == 0; }
-		bool is_valid() const { return !is_nil(); }
-		T index() const { return m_index; }
-		size_t hash() const { return std::hash<T>()( T( m_counter << IBITS | m_index ) ); }
-	protected:
-		T m_index   : IBITS;
-		T m_counter : CBITS;
-
-		handle( T a_index, T a_counter ) : m_index( a_index ), m_counter( a_counter ) {}
-		template < typename H >
-		friend class handle_operator;
-	};
-
-	template < typename HANDLE >
-	class handle_operator
-	{
-	public:
-		typedef typename HANDLE::value_type value_type;
-
-		static HANDLE create( value_type index, value_type counter )
-		{
-			return HANDLE( index, counter );
-		}
-		static value_type get_counter( const HANDLE& h ) { return h.m_counter; }
-		static value_type get_index( const HANDLE& h ) { return h.m_index; }
-	};
-
-	template < typename HANDLE, typename INDEX = sint32 >
-	class handle_manager
-	{
-		typedef INDEX index_type;
-		static const index_type NONE = index_type(-1);
-		static const index_type USED = index_type(-2);
-	public:
-
-		typedef HANDLE handle;
-		typedef typename HANDLE::value_type value_type;
-
-		handle_manager() : m_first_free( NONE ), m_last_free( NONE ) {}
-
-		handle create_handle()
-		{
-			typedef handle_operator<HANDLE> hop;
-			value_type i = get_free_entry();
-			m_entries[i].counter++;
-			NV_ASSERT( m_entries[i].counter != 0, "Out of handles!" );
-			m_entries[i].next_free = USED;
-			return hop::create( i, m_entries[i].counter );
-		}
-
-		void free_handle( handle h )
-		{
-			value_type index = h.index();
-			typedef handle_operator<HANDLE> hop;
-			NV_ASSERT( m_entries[index].next_free == USED, "Unused handle freed!" );
-			NV_ASSERT( m_entries[index].counter == hop::get_counter( h ), "Handle corruption!" );
-			m_entries[index].next_free = NONE;
-			if ( m_last_free == NONE )
-			{
-				m_first_free = m_last_free = (index_type)index;
-				return;
-			}
-			m_entries[(value_type)m_last_free].next_free = (index_type)index;
-			m_last_free = (index_type)index;
-		}
-
-		bool is_valid( handle h ) const
-		{
-			typedef handle_operator<HANDLE> hop;
-			if ( h.is_nil() ) return false;
-			if ( h.index() >= m_entries.size() ) return false;
-			const index_entry& entry = m_entries[h.index()];
-			return entry.next_free == USED && entry.counter == hop::get_counter( h );
-		}
-
-	private:
-		struct index_entry
-		{
-			value_type counter;
-			index_type next_free;
-
-			index_entry() : counter( 0 ), next_free( NONE ) {}
-		};
-
-		value_type get_free_entry()
-		{
-			if ( m_first_free != NONE )
-			{
-				value_type result = (value_type)m_first_free;
-				m_first_free = m_entries[result].next_free;
-				m_entries[result].next_free = USED;
-				if ( m_first_free == NONE ) m_last_free = NONE;
-				return result;
-			}
-			m_entries.emplace_back();
-			return value_type( m_entries.size() - 1 );
-		}
-
-		index_type m_first_free;
-		index_type m_last_free;
-		std::vector< index_entry > m_entries;
-	};
-
-	template < typename T, typename HANDLE = handle<>, typename TINDEX = sint32 >
-	class packed_indexed_array
-	{
-	public:
-		typedef HANDLE                   handle;
-		typedef TINDEX                   index_type;
-		typedef std::vector< T >         storage;
-		typedef T                        value_type;
-		typedef typename storage::iterator        iterator;
-		typedef typename storage::const_iterator  const_iterator;
-		typedef typename storage::reference       reference;
-		typedef typename storage::const_reference const_reference;
-
-		packed_indexed_array() {}
-		packed_indexed_array( uint32 reserve )
-		{
-			m_data.reserve( reserve );
-			m_indexes.reserve( reserve );
-		}
-
-		T* insert( handle h )
-		{
-			resize_indexes_to( (index_type) h.index() );
-			m_indexes[ h.index() ] = (index_type) m_data.size();
-			m_handles.push_back( h );
-			m_data.emplace_back();
-			return &(m_data.back());
-		}
-
-		bool exists( handle h )
-		{
-			if ( h.is_nil() || h.index() >= m_indexes.size() ) return false;
-			return m_indexes[ h.index() ] >= 0;		
-		}
-
-		T* get( handle h )
-		{
-			if ( h.is_nil() || h.index() >= m_indexes.size() ) return nullptr;
-			index_type i = m_indexes[ h.index() ];
-			return i >= 0 ? &(m_data[ (unsigned)i ]) : nullptr;
-		}
-
-		const T* get( handle h ) const
-		{
-			if ( h.is_nil() || h.index() >= m_indexes.size() ) return nullptr;
-			index_type i = m_indexes[h.index()];
-			return i >= 0 ? &( m_data[(unsigned)i] ) : nullptr;
-		}
-
-		void remove( handle h )
-		{
-			if ( h.is_nil() || h.index() >= m_indexes.size() || m_indexes[h.index()] == -1 ) 
-				return;
-			handle swap_handle    = m_handles.back();
-			sint32 dead_eindex    = m_indexes[ h.index() ];
-			if ( dead_eindex != (sint32)m_data.size()-1 )
-			{
-				m_data[ (unsigned)dead_eindex ]    = m_data.back();
-				m_handles[ (unsigned)dead_eindex ] = swap_handle;
-				m_indexes[ swap_handle.index() ]   = dead_eindex;
-			}
-			m_data.pop_back();
-			m_handles.pop_back();
-			m_indexes[ h.index() ] = -1;
-		}
-
-		void clear()
-		{
-			m_data.clear();
-			m_handles.clear();
-			m_indexes.clear();
-		}
-
-		handle get_handle( index_type i ) const { return m_handles[(unsigned)i]; }
-
-		const value_type& operator[] ( index_type i ) const { return m_data[i]; }
-		value_type& operator[] ( index_type i ) { return m_data[i]; }
-		size_t size() const { return m_data.size(); }
-
-		iterator        begin()        { return m_data.begin(); }
-		const_iterator  begin()  const { return m_data.cbegin(); }
-		const_iterator  cbegin() const { return m_data.cbegin(); }
-
-		iterator        end()        { return m_data.end(); }
-		const_iterator  end()  const { return m_data.cend(); }
-		const_iterator  cend() const { return m_data.cend(); }
-
-	private:
-		void resize_indexes_to( index_type i )
-		{
-			index_type size = (index_type)m_indexes.size();
-			if ( i >= size )
-			{
-				if ( size == 0 ) size = 1;
-				while ( i >= size ) size = size * 2;
-				m_indexes.resize( (size_t)size, -1 );
-			}
-		}
-
-		std::vector< T >          m_data;
-		std::vector< handle >     m_handles;
-		std::vector< index_type > m_indexes;
-	};
-
-
-	template < typename T, typename HANDLE = handle<>, typename TINDEX = sint32 >
-	class handle_store
-	{
-	public:
-		typedef HANDLE                   handle;
-		typedef TINDEX                   index_type;
-		typedef std::vector< T >         storage;
-		typedef T                        value_type;
-		typedef typename storage::iterator        iterator;
-		typedef typename storage::const_iterator  const_iterator;
-		typedef typename storage::reference       reference;
-		typedef typename storage::const_reference const_reference;
-
-		handle_store() {}
-
-		explicit handle_store( uint32 reserve )
-		{
-			m_data.reserve( reserve );
-		}
-
-		handle create()
-		{
-			handle h = m_indexes.create_handle();
-			m_data.insert( h );
-			return h;
-		}
-
-		bool is_valid( handle h )
-		{
-			return m_indexes.is_valid( h );
-		}
-
-		const value_type* get( handle h ) const
-		{
-			return m_data.get( h );
-		}
-
-		value_type* get( handle h )
-		{
-			return m_data.get( h );
-		}
-
-		void destroy( handle e )
-		{
-			m_data.remove( e );
-			m_indexes.free_handle( e );
-		}
-
-		handle get_handle( index_type i ) const { return m_data.get_handle(i); }
-		const value_type& operator[] ( index_type i ) const { return m_data[(unsigned)i]; }
-		value_type& operator[] ( index_type i ) { return m_data[(unsigned)i]; }
-		size_t size() const { return m_data.size(); }
-
-		iterator        begin() { return m_data.begin(); }
-		const_iterator  begin()  const { return m_data.cbegin(); }
-		const_iterator  cbegin() const { return m_data.cbegin(); }
-
-		iterator        end() { return m_data.end(); }
-		const_iterator  end()  const { return m_data.cend(); }
-		const_iterator  cend() const { return m_data.cend(); }
-
-	private:
-		packed_indexed_array< T, handle, TINDEX > m_data;
-		handle_manager< handle >                  m_indexes;
-	};
-	
-}
-
-namespace std
-{
-	template < 
-		typename T, 
-		unsigned IBITS,
-		unsigned CBITS,
-		typename TAG
-	>
-	struct hash<nv::handle<T,IBITS,CBITS,TAG>>
-	{
-		size_t operator()(const nv::handle<T,IBITS,CBITS,TAG>& h) const
-		{
-			return h.hash();
-		}
-	};
-}
-
-#endif // NV_CORE_HANDLE_HH
Index: /trunk/nv/core/library.hh
===================================================================
--- /trunk/nv/core/library.hh	(revision 367)
+++ /trunk/nv/core/library.hh	(revision 368)
@@ -14,6 +14,6 @@
 #define NV_CORE_LIBRARY_HH
 
-#include <nv/core/exception.hh>
-#include <nv/core/string.hh>
+#include <nv/stl/exception.hh>
+#include <nv/stl/string.hh>
 
 namespace nv
Index: /trunk/nv/core/logger.hh
===================================================================
--- /trunk/nv/core/logger.hh	(revision 367)
+++ /trunk/nv/core/logger.hh	(revision 368)
@@ -14,6 +14,6 @@
 #define NV_CORE_LOGGER_HH
 
-#include <nv/core/string.hh>
 #include <nv/core/logging.hh>
+#include <nv/stl/string.hh>
 
 namespace nv
@@ -35,19 +35,20 @@
 		virtual void log( log_level level, const string_ref& message ) = 0;
 		/**
-         * Optional timestamp string
-		 */
-		string_ref timestamp() const;
-		/**
-         * Log level name (unpadded)
-		 */
+		 * Enforcement of virtual destructor.
+		 */
+		virtual ~log_sink() {}
+	protected:
+		/**
+		* Optional timestamp string
+		*/
+		size_t timestamp( char* buffer ) const;
+		/**
+		* Log level name (unpadded)
+		*/
 		string_ref level_name( log_level level ) const;
 		/**
-         * Log level name (padded)
-		 */
+		* Log level name (padded)
+		*/
 		string_ref padded_level_name( log_level level ) const;
-		/**
-		 * Enforcement of virtual destructor.
-		 */
-		virtual ~log_sink() {}
 	};
 
Index: /trunk/nv/core/logging.hh
===================================================================
--- /trunk/nv/core/logging.hh	(revision 367)
+++ /trunk/nv/core/logging.hh	(revision 368)
@@ -15,6 +15,6 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/string.hh>
-#include <nv/core/singleton.hh>
+#include <nv/stl/string.hh>
+#include <nv/stl/singleton.hh>
 #include <sstream>
 
Index: unk/nv/core/math.hh
===================================================================
--- /trunk/nv/core/math.hh	(revision 367)
+++ 	(revision )
@@ -1,273 +1,0 @@
-// Copyright (C) 2012-2014 ChaosForge Ltd
-// http://chaosforge.org/
-//
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-
-#ifndef NV_CORE_MATH_HH
-#define NV_CORE_MATH_HH
-
-#include <nv/core/common.hh>
-
-#if NV_COMPILER == NV_GNUC
-#pragma GCC system_header
-#elif NV_COMPILER == NV_CLANG
-#pragma clang system_header
-#endif
-
-#include <glm/glm.hpp>
-#include <glm/gtc/matrix_transform.hpp>
-#include <glm/gtc/matrix_access.hpp>
-#include <glm/gtc/type_ptr.hpp>
-#include <glm/gtc/quaternion.hpp>
-#include <glm/gtx/rotate_vector.hpp>
-#include <glm/gtx/vector_angle.hpp>
-
-namespace nv
-{
-
-	typedef glm::detail::tvec2<sint8> i8vec2;
-	typedef glm::detail::tvec3<sint8> i8vec3;
-	typedef glm::detail::tvec4<sint8> i8vec4;
-
-	typedef glm::detail::tvec2<sint16> i16vec2;
-	typedef glm::detail::tvec3<sint16> i16vec3;
-	typedef glm::detail::tvec4<sint16> i16vec4;
-
-	typedef glm::detail::tvec2<uint8> u8vec2;
-	typedef glm::detail::tvec3<uint8> u8vec3;
-	typedef glm::detail::tvec4<uint8> u8vec4;
-
-	typedef glm::vec2 vec2;
-	typedef glm::vec3 vec3;
-	typedef glm::vec4 vec4;
-
-	typedef glm::ivec2 ivec2;
-	typedef glm::ivec3 ivec3;
-	typedef glm::ivec4 ivec4;
-
-	typedef glm::mat2 mat2;
-	typedef glm::mat3 mat3;
-	typedef glm::mat4 mat4;
-
-	typedef glm::quat quat;
-
-	template <typename T> 
-	struct datatype_traits 
-	{
-		typedef T type;
-		typedef T base_type;
-		static const size_t size = 1;
-	};
-
-	template <typename T> 
-	struct datatype_traits< glm::detail::tvec2<T> > 
-	{
-		typedef glm::detail::tvec2<T> type;
-		typedef typename type::value_type base_type;
-		static const size_t size = 2;
-	};
-
-	template <typename T> 
-	struct datatype_traits< glm::detail::tvec3<T> > 
-	{
-		typedef glm::detail::tvec3<T> type;
-		typedef typename type::value_type base_type;
-		static const size_t size = 3;
-	};
-
-	template <typename T> 
-	struct datatype_traits< glm::detail::tvec4<T> > 
-	{
-		typedef glm::detail::tvec4<T> type;
-		typedef typename type::value_type base_type;
-		static const size_t size = 4;
-	};
-
-	using glm::max;
-	using glm::min;
-
-	enum datatype
-	{
-		NONE,
-		INT,
-		BYTE,
-		SHORT,
-		UINT,
-		UBYTE,
-		USHORT,
-		FLOAT,
-		FLOAT_VECTOR_2,
-		FLOAT_VECTOR_3,
-		FLOAT_VECTOR_4,
-		FLOAT_MATRIX_2,
-		FLOAT_MATRIX_3,
-		FLOAT_MATRIX_4,
-		INT_VECTOR_2,
-		INT_VECTOR_3,
-		INT_VECTOR_4,
-		// unsupported gl conversion, remove?
-		BYTE_VECTOR_2, 
-		BYTE_VECTOR_3,
-		BYTE_VECTOR_4,
-		UBYTE_VECTOR_2,
-		UBYTE_VECTOR_3,
-		UBYTE_VECTOR_4,
-		QUAT,
-		TRANSFORM,
-		DATATYPE_COUNT,
-	};
-
-	struct datatype_info
-	{
-		size_t   size;
-		datatype base;
-		size_t   elements;
-	};
-
-	inline const datatype_info& get_datatype_info( datatype dt )
-	{
-		static datatype_info info[ DATATYPE_COUNT ] = {
-			{ 0, NONE, 0 },   // NONE  
-			{ 4, INT, 1 },    // INT,
-			{ 1, BYTE, 1 },   // BYTE,
-			{ 2, SHORT, 1 },  // SHORT,
-			{ 4, UINT, 1 },   // UINT,
-			{ 1, UBYTE, 1 },  // UBYTE,
-			{ 2, USHORT, 1 }, // USHORT,
-			{ 4, FLOAT, 1 },  // FLOAT
-			{ 4 * 2,  FLOAT, 2 },  // FLOAT_VECTOR_2,
-			{ 4 * 3,  FLOAT, 3 },  // FLOAT_VECTOR_3,
-			{ 4 * 4,  FLOAT, 4 },  // FLOAT_VECTOR_4,
-			{ 4 * 4,  FLOAT, 4 },  // FLOAT_MATRIX_2,
-			{ 4 * 9,  FLOAT, 9 },  // FLOAT_MATRIX_3,
-			{ 4 * 16, FLOAT, 16 }, // FLOAT_MATRIX_4,
-			{ 4 * 2,  INT, 2 },  // INT_VECTOR_2,
-			{ 4 * 3,  INT, 3 },  // INT_VECTOR_3,
-			{ 4 * 4,  INT, 4 },  // INT_VECTOR_4,
-			// unsupported gl conversion, remove?
-			{ 1 * 2,  BYTE, 2 },  // BYTE_VECTOR_2,
-			{ 1 * 3,  BYTE, 3 },  // BYTE_VECTOR_3,
-			{ 1 * 4,  BYTE, 4 },  // BYTE_VECTOR_4,
-			{ 1 * 2, UBYTE, 2 },  // UBYTE_VECTOR_2,
-			{ 1 * 3, UBYTE, 3 },  // UBYTE_VECTOR_3,
-			{ 1 * 4, UBYTE, 4 },  // UBYTE_VECTOR_4,
-			{ 4 * 4, FLOAT, 4 },      // QUAT,
-			{ 7 * 4,  FLOAT, 7 },      // TRANSFORM,
-		};
-		return info[dt];
-	}
-
-	template < datatype EnumType > struct enum_to_type {};
-
-	template <> struct enum_to_type< NONE >  { typedef void type; };
-	template <> struct enum_to_type< INT >   { typedef int type; };
-	template <> struct enum_to_type< UINT >  { typedef unsigned int type; };
-	template <> struct enum_to_type< SHORT > { typedef short type; };
-	template <> struct enum_to_type< USHORT >{ typedef unsigned short type; };
-	template <> struct enum_to_type< BYTE >  { typedef char type; };
-	template <> struct enum_to_type< UBYTE > { typedef unsigned char type; };
-	template <> struct enum_to_type< FLOAT > { typedef f32 type; };
-
-	template <> struct enum_to_type< FLOAT_VECTOR_2 > { typedef vec2 type; };
-	template <> struct enum_to_type< FLOAT_VECTOR_3 > { typedef vec3 type; };
-	template <> struct enum_to_type< FLOAT_VECTOR_4 > { typedef vec4 type; };
-
-	template <> struct enum_to_type< INT_VECTOR_2 > { typedef ivec2 type; };
-	template <> struct enum_to_type< INT_VECTOR_3 > { typedef ivec3 type; };
-	template <> struct enum_to_type< INT_VECTOR_4 > { typedef ivec4 type; };
-
-	template <> struct enum_to_type< BYTE_VECTOR_2 > { typedef i8vec2 type; };
-	template <> struct enum_to_type< BYTE_VECTOR_3 > { typedef i8vec3 type; };
-	template <> struct enum_to_type< BYTE_VECTOR_4 > { typedef i8vec4 type; };
-
-	template <> struct enum_to_type < UBYTE_VECTOR_2 > { typedef u8vec2 type; };
-	template <> struct enum_to_type < UBYTE_VECTOR_3 > { typedef u8vec3 type; };
-	template <> struct enum_to_type < UBYTE_VECTOR_4 > { typedef u8vec4 type; };
-
-	template <> struct enum_to_type< FLOAT_MATRIX_2 > { typedef mat2 type; };
-	template <> struct enum_to_type< FLOAT_MATRIX_3 > { typedef mat3 type; };
-	template <> struct enum_to_type< FLOAT_MATRIX_4 > { typedef mat4 type; };
-
-	template <> struct enum_to_type< QUAT > { typedef quat type; };
-
-	template < typename TYPE > struct type_to_enum {};
-
-	template <> struct type_to_enum< long >          { static const datatype type = INT; };
-	template <> struct type_to_enum< unsigned long > { static const datatype type = UINT; };
-	template <> struct type_to_enum< int >           { static const datatype type = INT; };
-	template <> struct type_to_enum< unsigned int >  { static const datatype type = UINT; };
-	template <> struct type_to_enum< short >         { static const datatype type = SHORT; };
-	template <> struct type_to_enum< unsigned short >{ static const datatype type = USHORT; };
-	template <> struct type_to_enum< char >          { static const datatype type = BYTE; };
-	template <> struct type_to_enum< signed char >   { static const datatype type = BYTE; };
-	template <> struct type_to_enum< unsigned char > { static const datatype type = UBYTE; };
-	template <> struct type_to_enum< f32 > { static const datatype type = FLOAT; };
-
-	template <> struct type_to_enum< vec2 > { static const datatype type = FLOAT_VECTOR_2; };
-	template <> struct type_to_enum< vec3 > { static const datatype type = FLOAT_VECTOR_3; };
-	template <> struct type_to_enum< vec4 > { static const datatype type = FLOAT_VECTOR_4; };
-
-	template <> struct type_to_enum< ivec2 > { static const datatype type = INT_VECTOR_2; };
-	template <> struct type_to_enum< ivec3 > { static const datatype type = INT_VECTOR_3; };
-	template <> struct type_to_enum< ivec4 > { static const datatype type = INT_VECTOR_4; };
-
-	template <> struct type_to_enum< i8vec2 > { static const datatype type = BYTE_VECTOR_2; };
-	template <> struct type_to_enum< i8vec3 > { static const datatype type = BYTE_VECTOR_3; };
-	template <> struct type_to_enum< i8vec4 > { static const datatype type = BYTE_VECTOR_4; };
-
-	template <> struct type_to_enum < u8vec2 > { static const datatype type = UBYTE_VECTOR_2; };
-	template <> struct type_to_enum < u8vec3 > { static const datatype type = UBYTE_VECTOR_3; };
-	template <> struct type_to_enum < u8vec4 > { static const datatype type = UBYTE_VECTOR_4; };
-
-
-	template <> struct type_to_enum< mat2 > { static const datatype type = FLOAT_MATRIX_2; };
-	template <> struct type_to_enum< mat3 > { static const datatype type = FLOAT_MATRIX_3; };
-	template <> struct type_to_enum< mat4 > { static const datatype type = FLOAT_MATRIX_4; };
-	template <> struct type_to_enum< quat > { static const datatype type = QUAT; };
-
-	template < typename T >
-	struct sizeof_type 
-	{
-		static const int result = sizeof( T );
-	};
-
-	template <>
-	struct sizeof_type< void >
-	{
-		static const int result = 0;
-	};
-
-	template < datatype T >
-	struct sizeof_enum_type 
-	{
-		static const int result = sizeof_type< typename enum_to_type<T>::type >::result;
-	};
-
-	template < typename T >
-	T interpolate( const T& lhs, const T& rhs, float f )
-	{
-		return glm::mix( lhs, rhs, f );
-	}
-
-	template <>
-	inline quat interpolate( const quat& lhs, const quat& rhs, float f )
-	{
-		return glm::slerp( lhs, rhs, f );
-	}
-
-	template <typename T>
-	glm::detail::tvec3<T> normalize_safe( 
-		const glm::detail::tvec3<T>& x, 
-		const glm::detail::tvec3<T>& def = vec3()
-	)
-	{
-		typename glm::detail::tvec3<T>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z;
-		return ( sqr > 0 ? x * glm::inversesqrt(sqr) : def );
-	}
-
-
-
-} // namespace nv
-
-#endif // NV_CORE_MATH_HH
Index: /trunk/nv/core/position.hh
===================================================================
--- /trunk/nv/core/position.hh	(revision 367)
+++ /trunk/nv/core/position.hh	(revision 368)
@@ -15,6 +15,6 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
-#include <nv/core/range.hh>
+#include <nv/stl/math.hh>
+#include <nv/stl/range.hh>
 #include <utility>
 
Index: /trunk/nv/core/profiler.hh
===================================================================
--- /trunk/nv/core/profiler.hh	(revision 367)
+++ /trunk/nv/core/profiler.hh	(revision 368)
@@ -15,5 +15,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/singleton.hh>
+#include <nv/stl/singleton.hh>
 #include <unordered_map>
 
Index: /trunk/nv/core/random.hh
===================================================================
--- /trunk/nv/core/random.hh	(revision 367)
+++ /trunk/nv/core/random.hh	(revision 368)
@@ -9,5 +9,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <random>
 
Index: unk/nv/core/range.hh
===================================================================
--- /trunk/nv/core/range.hh	(revision 367)
+++ 	(revision )
@@ -1,233 +1,0 @@
-// Copyright (C) 2014 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 range.hh
- * @author Kornel Kisielewicz epyon@chaosforge.org
- * @brief range iterators
- */
-
-#ifndef NV_CORE_RANGE_HH
-#define NV_CORE_RANGE_HH
-
-#include <nv/core/common.hh>
-#include <nv/core/math.hh>
-#include <nv/core/type_traits.hh>
-#include <iterator>
-
-namespace nv
-{
-
-	namespace detail
-	{
-
-		template < typename T >
-		class forward_iterator_base : public std::iterator< std::input_iterator_tag, T >
-		{
-		public:
-			forward_iterator_base( T value ) : m_value( value ) {}
-			T operator* () const { return m_value; }
-			T const* operator-> () const { return &m_value; }
-			bool operator== ( const forward_iterator_base& rhs ) const
-			{
-				return m_value == rhs.m_value;
-			}
-			bool operator!= ( const forward_iterator_base& rhs ) const
-			{
-				return !( *this == rhs );
-			}
-		protected:
-			T m_value;
-		};
-
-		template < typename T >
-		class range_iterator_base : public forward_iterator_base< T >
-		{
-		public:
-			typedef forward_iterator_base< T > base_class;
-
-			range_iterator_base( T value ) : forward_iterator_base<T>( value ) {}
-			range_iterator_base& operator++ () 
-			{
-				++base_class::m_value; 
-				return *this; 
-			}
-			range_iterator_base operator++ (int) 
-			{
-				auto result = *this; 
-				++*this; 
-				return result;
-			}
-		};
-
-		template < typename T >
-		class range2d_iterator_base 
-			: public forward_iterator_base< glm::detail::tvec2<T> >
-		{
-		public:
-			typedef forward_iterator_base< glm::detail::tvec2<T> > base_class;
-
-			range2d_iterator_base( glm::detail::tvec2<T> value, T min, T max ) 
-				: forward_iterator_base< glm::detail::tvec2<T> >( value ), m_min(min), m_max(max) {}
-			range2d_iterator_base& operator++ () 
-			{
-				++base_class::m_value.x;
-				if ( base_class::m_value.x > m_max ) 
-				{
-					++base_class::m_value.y;
-					base_class::m_value.x = m_min;
-				}
-				return *this; 
-			}
-			range2d_iterator_base operator++ (int) 
-			{
-				auto result = *this; 
-				++*this; 
-				return result;
-			}
-		protected:
-			T m_min;
-			T m_max;
-		};
-
-		template < typename T >
-		class bits_iterator_base : public forward_iterator_base< T >
-		{
-		public:
-			typedef typename base_underlying_type<T>::type base_type;
-			typedef forward_iterator_base< T > base_class;
-
-			static const T invalid = T( 0 );
-
-			bits_iterator_base( T value, T current ) : forward_iterator_base<T>( current ), m_full( value )
-			{
-				if( !( (base_type)value & (base_type)current ) )
-					next();
-			}
-			bits_iterator_base& operator++ () 
-			{
-				next();
-				return *this; 
-			}
-			bits_iterator_base operator++ (int) 
-			{
-				auto result = *this; 
-				++*this; 
-				return result;
-			}
-		private:
-			void next()
-			{
-				do
-				{
-					if ( base_class::m_value == invalid || m_full <= base_class::m_value ) { base_class::m_value = invalid; m_full = invalid; break; }
-					base_class::m_value = T((base_type)base_class::m_value << 1);
-				} while ( !( (base_type)m_full & (base_type)base_class::m_value ) );
-			}
-
-			T m_full;
-		};
-
-
-	} // namespace detail
-
-	template < typename T >
-	class range_iterator_provider
-	{
-	public:
-		class iterator : public detail::range_iterator_base<T>
-		{
-		public:
-			iterator( T value ) : detail::range_iterator_base<T>(value) {}
-		};
-
-		range_iterator_provider( T begin, T end ) : m_begin( begin ), m_end( end ) {}
-		iterator begin() { return m_begin; }
-		iterator end() { return m_end; }
-
-	protected:
-		iterator m_begin;
-		iterator m_end;
-	};
-
-	template < typename T >
-	class range2d_iterator_provider
-	{
-	public:
-		typedef T value_type;
-		typedef typename T::value_type element_type;
-
-		class iterator : public detail::range2d_iterator_base<element_type>
-		{
-		public:
-			iterator( value_type begin, element_type min, element_type max ) 
-				: detail::range2d_iterator_base<element_type>(begin, min, max) {}
-		};
-
-		range2d_iterator_provider( value_type begin, value_type end ) : m_begin( begin, begin.x, end.x ), m_end( T(begin.x, ++end.y ), begin.x, end.x ) {}
-		iterator begin() { return m_begin; }
-		iterator end() { return m_end; }
-
-	protected:
-		iterator m_begin;
-		iterator m_end;
-	};
-
-	template < typename T >
-	class bits_iterator_provider
-	{
-	public:
-		typedef typename base_underlying_type<T>::type base_type;
-		typedef detail::bits_iterator_base<T> iterator;
-		static const T invalid = T( 0 );
-
-		bits_iterator_provider( T value ) : m_value( value ) {}
-		iterator begin() { return iterator( m_value, T(1) ); }
-		iterator end() { return iterator( m_value, invalid ); }
-
-	protected:
-		T m_value;
-	};
-
-	template < typename T >
-	range_iterator_provider<T> range( T begin, T end )
-	{
-		return range_iterator_provider<T>( begin, end+1 );
-	}
-
-	template < typename T >
-	range2d_iterator_provider<T> range2d( T begin, T end )
-	{
-		return range2d_iterator_provider<T>( begin, end );
-	}
-
-	template < typename T >
-	range_iterator_provider<T> range( T end )
-	{
-		return range_iterator_provider<T>( 0, end );
-	}
-
-	template < typename T >
-	range2d_iterator_provider<T> range2d( T end )
-	{
-		return range2d_iterator_provider<T>( T(0,0), T( --end.x, --end.y ) );
-	}
-
-	template < typename C >
-	auto index( const C& c ) -> range_iterator_provider<decltype( c.size() )>
-	{
-		return range_iterator_provider<decltype( c.size() )>( 0, c.size() );
-	}
-
-	template < typename T >
-	bits_iterator_provider<T> bits( T value )
-	{
-		return bits_iterator_provider<T>( value );
-	}
-
-
-}
-
-#endif // NV_CORE_RANGE_HH
Index: unk/nv/core/singleton.hh
===================================================================
--- /trunk/nv/core/singleton.hh	(revision 367)
+++ 	(revision )
@@ -1,120 +1,0 @@
-// Copyright (C) 2012-2014 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 singleton.hh
- * @author Kornel Kisielewicz epyon@chaosforge.org
- * @brief singleton pattern
- */
-
-#ifndef NV_CORE_SINGLETON_HH
-#define NV_CORE_SINGLETON_HH
-
-#include <cassert>
-
-namespace nv
-{
-	/**
-	 * singleton
-	 * @brief Represents an accessible static object that will only have one instance.
-	 */
-    template <class T>
-    class singleton
-    {
-    private:
-        static T *singleton_; ///< Pointer to the instance of this object type.
-
-    protected:
-
-		/**
-		 * Creates the single instance if one doesn't already exist.
-		 */
-        singleton()
-        {
-            assert(!singleton_);
-            singleton_ = static_cast<T*>(this);
-        }
-
-		/**
-		 * Destroys the instance.
-		 */
-        ~singleton()
-        {
-            assert(singleton_);
-            singleton_ = 0;
-        }
-
-    public:
-		/**
-		 * Checks to see if the instance exists.
-		 *
-		 * @returns True if this singleton has an instance assigned, false otherwise.
-		 */
-        static bool is_valid()
-        {
-            return singleton_ != 0;
-        }
-
-		/**
-		 * Returns the pointer to the instance.
-		 *
-		 * @returns The pointer to the instance.
-		 */
-        static T *pointer()
-        {
-            assert(singleton_);
-            return singleton_;
-        }
-		/**
-		 * Returns the object referenced by this singleton.
-		 */
-        static T &reference()
-        {
-            assert(singleton_);
-            return *singleton_;
-        }
-    };
-
-    template <class T>
-    T* singleton<T>::singleton_ = 0;
-
-
-	/**
-	 * auto_singleton
-	 * @brief Represents a singleton that automatically creates an instance if one doesn't already exist.
-	 */
-    template <class T>
-    class auto_singleton : public singleton<T>
-    {
-    public:
-		/**
-		 * Returns the pointer to the instance.  Makes an instance if one doesn't already exist.
-		 */
-        static T *pointer()
-        {
-            if ( !singleton<T>::is_valid() )
-            {
-                new T();
-            }
-            return singleton<T>::pointer();
-        }
-
-		/**
-		 * Returns the object referenced by this singleton.  Makes an instance if one doesn't already exist.
-		 */
-        static T &reference()
-        {
-            if ( !singleton<T>::is_valid() )
-            {
-                new T();
-            }
-            return singleton<T>::reference();
-        }
-    };
-
-} // namespace nv
-
-#endif // NV_CORE_SINGLETON_HH
Index: unk/nv/core/string.hh
===================================================================
--- /trunk/nv/core/string.hh	(revision 367)
+++ 	(revision )
@@ -1,665 +1,0 @@
-// Copyright (C) 2012-2014 ChaosForge Ltd
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-//
-// TODO: tests for string_length
-//  * performance tests
-//  * matching tests
-//  * compatibility tests
-//  * check if we can get rid of const templates
-//
-// String reference implementation based of string_ref proposal and boost::string_ref
-//
-// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
-// http://www.boost.org/doc/libs/1_58_0/libs/utility/doc/html/string_ref.html
-//
-// TODO: WARNING: this code is centered around 8bit char. In particular, 
-//   const_string wont work with non-8bit chars.
-// TODO: remove templating on char type, make a string_utf8 instead.
-
-#ifndef NV_CORE_STRING_HH
-#define NV_CORE_STRING_HH
-
-#include <string>
-#include <algorithm>
-#include <cstring>
-#include <sstream>
-#include <fstream>
-#include <nv/core/common.hh>
-#include <nv/core/exception.hh>
-
-namespace nv
-{
-	using std::string;
-
-
-
-	/**
-	* Utility function for converting any value to string.
-	*
-	* @param value value to be converted, needs to have << operator
-	*        to stream
-	* @throw runtime_error Throws runtime_error on conversion fail
-	* @return value converted to string
-	*/
-	template < class T >
-	string to_string( const T& value )
-	{
-		std::stringstream stream;
-		stream << value;
-
-		if ( stream.fail() )
-		{
-//			NV_THROW( runtime_error, "bad cast" );
-		}
-
-		return stream.str();
-	}
-
-	/**
-	* Override function for special treatment of strings. Returns the
-	* value passed.
-	*/
-	inline string to_string( const string& value)
-	{
-		return value;
-	}
-
-	/**
-	* Utility function for converting a string to the given type
-	*
-	* @param vin the string representing the value
-	* @param vout the value to be read. Must be streamable with >>
-	* @throw runtime_error Throws runtime_error on conversion fail
-	*/
-	template < class T >
-	void from_string( const string& vin, T& vout )
-	{
-		std::istringstream value( vin );
-		value >> vout;
-
-		if ( value.fail() )
-		{
-//			NV_THROW( runtime_error, "bad cast" );
-		}
-	}
-
-	/**
-	* Utility function for converting a string to the given type
-	*
-	* @param vin the string representing the value
-	* @throw runtime_error Throws runtime_error on conversion fail
-	*/
-	template < class T >
-	T string_cast( const string& vin )
-	{
-		T vout;
-		std::istringstream value( vin );
-		value >> vout;
-
-		if ( value.fail() )
-		{
-//			NV_THROW( runtime_error, "bad cast" );
-		}
-		return vout;
-	}
-
-
-	/**
-	* Override function for special treatment of strings. Returns the
-	* value passed.
-	*/
-	inline void from_string( const string& vin, string& vout )
-	{
-		vout = vin;
-	}
-
-	/**
-	* Override function for special treatment of strings. Returns the
-	* value passed.
-	*/
-	template <>
-	inline std::string string_cast( const string& vin )
-	{
-		return vin;
-	}
-
-
-	/**
-	* Simple function for slurping a file into a string.
-	*/
-	inline std::string slurp( const std::string& filename )
-	{
-		std::ifstream input(filename);
-//		if ( !input.is_open() ) NV_THROW( std::runtime_error, "File "+filename+" not found!");
-		std::stringstream sstr;
-		while(input >> sstr.rdbuf());
-		return sstr.str();
-	}
-
-	inline bool trim( std::string& str )
-	{
-		size_t endpos = str.find_last_not_of(" \r\n\t");
-		size_t startpos = str.find_first_not_of(" \r\n\t");
-
-		if ( string::npos != endpos || string::npos != startpos )
-		{
-			if ( string::npos == startpos ) startpos = 0;
-			if ( string::npos != endpos )   endpos = endpos+1-startpos;
-			str = str.substr( startpos, endpos );
-			return true;
-		}
-		return false;
-	}
-
-	inline bool rtrim( std::string& str )
-	{
-		size_t endpos = str.find_last_not_of(" \r\n\t");
-		if ( string::npos != endpos )
-		{
-			str = str.substr( 0, endpos+1 );
-			return true;
-		}
-		return false;
-	}
-
-	inline bool ltrim( std::string& str )
-	{
-		size_t startpos = str.find_first_not_of(" \r\n\t");
-		if( string::npos != startpos )
-		{
-			str = str.substr( startpos );
-			return true;
-		}
-		return false;
-	}
-
-	inline std::string trimmed( const std::string& str )
-	{
-		size_t endpos = str.find_last_not_of(" \r\n\t");
-		size_t startpos = str.find_first_not_of(" \r\n\t");
-
-		if ( string::npos != endpos || string::npos != startpos )
-		{
-			if ( string::npos == startpos ) startpos = 0;
-			if ( string::npos != endpos )   endpos = endpos+1-startpos;
-			return str.substr( startpos, endpos );
-		}
-		return str;
-	}
-
-	inline std::string rtrimmed( const std::string& str )
-	{
-		size_t endpos = str.find_last_not_of(" \r\n\t");
-		if ( string::npos != endpos )
-		{
-			return str.substr( 0, endpos+1 );
-		}
-		return str;
-	}
-
-	inline std::string ltrimmed( const std::string& str )
-	{
-		size_t startpos = str.find_first_not_of(" \r\n\t");
-		if( string::npos != startpos )
-		{
-			return str.substr( startpos );
-		}
-		return str;
-	}
-
-	inline bool ends_with( const std::string& s, const std::string & ending )
-	{
-		if ( s.length() >= ending.length() ) {
-			return ( 0 == s.compare (s.length() - ending.length(), ending.length(), ending) );
-		} else {
-			return false;
-		}
-	}
-
-	inline std::string& remove_chars( std::string& s, const std::string& chars ) 
-	{
-		s.erase(remove_if(s.begin(), s.end(), 
-			[&chars](const char& c) {
-				return chars.find(c) != std::string::npos;
-			}), s.end());
-		return s;
-	}
-
-	inline std::string extract_extension( const std::string& filename )
-	{
-		size_t lastdot = filename.find_last_of( "." );
-		std::string ext;
-		if ( std::string::npos != lastdot )
-			ext = filename.substr( lastdot + 1 );
-		std::transform( ext.begin(), ext.end(), ext.begin(), ::tolower );
-		return ext;
-	}
-
-	inline std::string remove_chars_copy( std::string s, const std::string& chars ) 
-	{
-		return remove_chars(s, chars);
-	}
-
-	namespace detail
-	{
-		template< typename T >
-		struct string_length_impl
-		{
-			static size_t get( T ) { return 0; }
-		};
-		template< size_t S >
-		struct string_length_impl < char[S] >
-		{
-			static size_t get( const char[S] ) { return S - 1; }
-		};
-		template< size_t S >
-		struct string_length_impl < const char[S] >
-		{
-			static size_t get( const char[S] ) { return S - 1; }
-		};
-		template<>
-		struct string_length_impl < char* >
-		{
-			static size_t get( const char* s ) { return std::strlen( s ); }
-		};
-		template<>
-		struct string_length_impl < const char* >
-		{
-			static size_t get( const char* s ) { return std::strlen( s ); }
-		};
-		template<>
-		struct string_length_impl < std::string >
-		{
-			static size_t get( const std::string& s ) { return s.length(); }
-		};
-		template<>
-		struct string_length_impl < const std::string >
-		{
-			static size_t get( const std::string& s ) { return s.length(); }
-		};
-	}
-
-#if NV_COMPILER == NV_GNUC
-	template< typename T >
-	struct string_length : public detail::string_length_impl <
-		typename std::remove_cv < typename std::remove_reference< T >::type >::type >
-	{
-	};
-#else
-	template< typename T >
-	using string_length = detail::string_length_impl <
-		typename std::remove_cv < typename std::remove_reference< T >::type >::type >;
-#endif
-
-	class string_ref;
-
-	// string base class - will become a base for a string class later
-	class string_base
-	{
-	public:
-		typedef char           value_type;
-		typedef const char*    pointer;
-		typedef const char&    reference;
-		typedef const char&    const_reference;
-		typedef pointer        const_iterator;
-		typedef const_iterator iterator;
-		typedef std::size_t    size_type;
-		typedef std::ptrdiff_t difference_type;
-
-		typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-		typedef const_reverse_iterator                reverse_iterator;
-
-		static NV_CONSTEXPR_CONST size_type npos = size_type( -1 );
-
-		// conversion to std::string
- 		inline std::string to_string() const
- 		{
- 			return std::string( m_data, m_size );
- 		}
-
-		// iterators
-		inline NV_CONSTEXPR const_iterator  cbegin() const { return m_data; }
-		inline NV_CONSTEXPR const_iterator    cend() const { return m_data + m_size; }
-		inline const_reverse_iterator crbegin() const { return const_reverse_iterator( cend() ); }
-		inline const_reverse_iterator   crend() const { return const_reverse_iterator( cbegin() ); }
-
-		inline NV_CONSTEXPR size_type size()     const { return m_size; }
-		inline NV_CONSTEXPR size_type length()   const { return m_size; }
-		inline NV_CONSTEXPR size_type max_size() const { return m_size; }
-		inline NV_CONSTEXPR bool empty()         const { return m_size == 0; }
-
-		// access
-		inline NV_CONSTEXPR char operator[]( size_type i ) const { return m_data[i]; }
-		inline char at( size_t i ) const
-		{
-			//	if ( i >= m_data ) NV_THROW( std::out_of_range( "string_ref::at" ) );
-			return m_data[i];
-		}
-
-		inline NV_CONSTEXPR char front()        const { return m_data[0]; }
-		inline NV_CONSTEXPR char back()         const { return m_data[m_size - 1]; }
-		inline NV_CONSTEXPR const char* data()  const { return m_data; }
-
-		// string operations
-		int compare( const string_base& rhs ) const
-		{
-			int cmp = std::memcmp( m_data, rhs.m_data, ( std::min )( m_size, rhs.m_size ) );
-			return cmp != 0 ? cmp : ( m_size == rhs.m_size ? 0 : m_size < rhs.m_size ? -1 : 1 );
-		}
-		bool starts_with( char c ) const { return !empty() && c == front(); }
-		bool starts_with( const string_base& s ) const
-		{
-			return m_size >= s.m_size && std::memcmp( m_data, s.m_data, s.m_size ) == 0;
-		}
-		bool ends_with( char c ) const { return !empty() && c == back(); }
-		bool ends_with( const string_base& s ) const
-		{
-			return m_size >= s.m_size && std::memcmp( m_data + m_size - s.m_size, s.m_data, s.m_size ) == 0;
-		}
-		size_type find( const string_base& s, size_type pos = 0 ) const
-		{
-			if ( pos >= m_size ) return npos;
-			const_iterator it = std::search( this->cbegin() + ( difference_type ) pos, this->cend(), s.cbegin(), s.cend() );
-			return it == this->cend() ? npos : ( size_type )std::distance( this->cbegin(), it );
-		}
-		size_type find( char c, size_type pos = 0 ) const
-		{
-			if ( pos >= m_size ) return npos;
-			const_iterator it = std::find_if( this->cbegin() + ( difference_type ) pos, this->cend(), [=] ( char val ) { return val == c; } );
-			return it == this->cend() ? npos : ( size_type )std::distance( this->cbegin(), it );
-		}
-		size_type rfind( const string_base& s, size_type pos = 0 ) const
-		{
-			if ( pos >= m_size ) return npos;
-			const_reverse_iterator it = std::search( this->crbegin() + ( difference_type ) pos, this->crend(), s.crbegin(), s.crend() );
-			return it == this->crend() ? npos : m_size - 1 - ( size_type )std::distance( this->crbegin(), it );
-		}
-		size_type rfind( char c, size_type pos = 0 ) const
-		{
-			if ( pos >= m_size ) return npos;
-			const_reverse_iterator it = std::find_if( this->crbegin() + ( difference_type ) pos, this->crend(), [=] ( char val ) { return val == c; } );
-			return it == this->crend() ? npos : m_size - 1 - ( size_type )std::distance( this->crbegin(), it );
-		}
-		size_type find_first_of( char c ) const { return find( c ); }
-		size_type find_first_of( const string_base& s ) const
-		{
-			const_iterator it = std::find_first_of( this->cbegin(), this->cend(), s.cbegin(), s.cend() );
-			return it == this->cend() ? npos : ( size_type )std::distance( this->cbegin(), it );
-		}
-		size_type find_last_of( char c )  const { return rfind( c ); }
-		size_type find_last_of( const string_base& s ) const
-		{
-			const_reverse_iterator it = std::find_first_of( this->crbegin(), this->crend(), s.cbegin(), s.cend() );
-			return it == this->crend() ? npos : m_size - 1 - ( size_type )std::distance( this->crbegin(), it );
-		}
-		size_type find_first_not_of( const string_base& s ) const
-		{
-			for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
-				if ( 0 == std::memchr( s.m_data, *it, s.m_size ) )
-					return ( size_type )std::distance( this->cbegin(), it );
-			return npos;
-		}
-		size_type find_first_not_of( char c ) const
-		{
-			for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
-				if ( c != *it )
-					return ( size_type )std::distance( this->cbegin(), it );
-			return npos;
-		}
-		size_type find_last_not_of( const string_base& s ) const
-		{
-			for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
-				if ( 0 == std::memchr( s.m_data, *it, s.m_size ) )
-					return m_size - 1 - ( size_type )std::distance( this->crbegin(), it );;
-			return npos;
-		}
-		size_type find_last_not_of( char c ) const
-		{
-			for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
-				if ( c != *it )
-					return m_size - 1 - ( size_type )std::distance( this->crbegin(), it );
-			return npos;
-		}
-
-		// string operations
-		string_ref substr( size_type p, size_type n = npos ) const;
-
-		inline std::size_t hash() const
-		{
-			const char* str = m_data;
-			size_type   sz  = m_size;
-			int seed = 131;
-			int result = 0;
-			while ( sz )
-			{
-				result = ( result * seed ) + ( *str );
-				str++;
-				sz--;
-			}
-			return result & ( 0x7FFFFFFF );
-		}
-
-	protected:
-		inline NV_CONSTEXPR string_base() : m_data( nullptr ), m_size( 0 ) {}
-		inline NV_CONSTEXPR string_base( pointer a_data, size_type a_lenght )
-			: m_data( a_data ), m_size( a_lenght ) {}
-
-	protected:
-		pointer   m_data;
-		size_type m_size;
-	};
-
-	class string_ref : public string_base
-	{
-	public:
-		inline NV_CONSTEXPR string_ref() {}
-		inline NV_CONSTEXPR string_ref( const string_ref& rhs )
-			: string_base( rhs.m_data, rhs.m_size )
-		{
-		}
-		inline NV_CONSTEXPR string_ref( const string_base& rhs )
-			: string_base( rhs.data(), rhs.size() )
-		{
-		}
-
-		inline string_ref( const std::string& str )
-			: string_base( str.data(), str.size() )
-		{
-		}
-
-		inline NV_CONSTEXPR string_ref( const char* str, size_type len )
-			: string_base( str, len )
-		{
-		}
-
-		// Literal constructors
-		template< size_t N >
-		inline string_ref( char( &s )[N] ) : string_base( s, N - 1 ) {}
-		template< size_t N >
-		inline string_ref( const char( &s )[N] ) : string_base( s, N - 1 ) {}
-
-		// Non-literal constructors
-		template< typename U >
-		inline string_ref( U str, typename std::enable_if<std::is_same<U, const char*>::value>::type* = nullptr ) : string_base( str, std::strlen( str ) ) {}
-
-		// Non-literal constructors
-		template< typename U >
-		inline string_ref( U str, typename std::enable_if<std::is_same<U, char*>::value>::type* = nullptr ) : string_base( str, std::strlen( str ) ) {}
-
-		inline string_ref& operator=( const string_ref &rhs )
-		{
-			m_data = rhs.m_data;
-			m_size = rhs.m_size;
-			return *this;
-		}
-
-		// iterators
-		inline NV_CONSTEXPR const_iterator   begin() const { return m_data; }
-		inline NV_CONSTEXPR const_iterator     end() const { return m_data + m_size; }
-		inline const_reverse_iterator  rbegin() const { return const_reverse_iterator( end() ); }
-		inline const_reverse_iterator    rend() const { return const_reverse_iterator( begin() ); }
-
-		// modifiers
-		inline void clear()
-		{
-			m_size = 0;
-			m_data = nullptr;
-		}
-		inline void remove_prefix( size_type n )
-		{
-			if ( n > m_size )	n = m_size;
-			m_data += n;
-			m_size -= n;
-		}
-		inline void remove_suffix( size_type n )
-		{
-			if ( n > m_size ) n = m_size;
-			m_size -= n;
-		}
-
-	};
-
-	// const string is movable but not copyable
-	class const_string : public string_base
-	{
-	public:
-		NV_CONSTEXPR const_string() {}
-		const_string( const char* str, size_type len )
-		{
-			initialize( str, len );
-		}
-		explicit const_string( const char* str )
-		{
-			initialize( str, std::strlen( str ) );
-		}
-
-		~const_string()
-		{
-			if ( m_data ) delete m_data;
-		}
-
-		inline const_string( const_string&& other )
-		{
-			m_data = other.m_data;
-			other.m_data = nullptr;
-		}
-
-		inline const_string& operator=( const_string&& other )
-		{
-			pointer temp = m_data;
-			m_data = other.m_data;
-			other.m_data = temp;
-			return *this;
-		}
-
-		// blocked copy constructor
-		const_string( const const_string & ) = delete;
-		// blocked copy operator
-		const_string& operator=( const const_string& ) = delete;
-
-	private:
-
-		void initialize( const char* p, size_type s )
-		{
-			char* data = new char[s + 1];
-			std::memcpy( data, p, s );
-			data[s] = 0;
-			m_data = data;
-		}
-	};
-
-	inline string_ref string_base::substr( size_type p, size_type n ) const
-	{
-		if ( p > size() ) return string_ref(); // NV_THROW( std::out_of_range( "substr" ) );
-		if ( n == p || p + n > size() ) n = size() - p;
-		return string_ref( data() + p, n );
-	}
-
-#define NV_STRING_BASE_CAST_OPERATORS( OPERATOR )\
-inline bool operator OPERATOR ( const string_base& lhs, const std::string& rhs )\
-{\
-	return lhs OPERATOR string_ref( rhs );\
-}\
-inline bool operator OPERATOR ( const std::string& lhs, const string_base& rhs )\
-{\
-	return string_ref( lhs ) OPERATOR rhs;\
-}\
-inline bool operator OPERATOR ( const string_base& lhs, const char* rhs )\
-{\
-	return lhs OPERATOR string_ref( rhs );\
-}\
-inline bool operator OPERATOR ( const char* lhs, const string_base& rhs )\
-{\
-	return string_ref( lhs ) OPERATOR rhs;\
-}\
-
-	// Base operators
-	inline bool operator==( const string_base& lhs, const string_base& rhs )
-	{
-		return lhs.size() != rhs.size() ? false : ( lhs.compare( rhs ) == 0 );
-	}
-	inline bool operator!=( const string_base& lhs, const string_base& rhs )
-	{
-		return lhs.size() != rhs.size() ? true : ( lhs.compare( rhs ) != 0 );
-	}
-	inline bool operator<( const string_base& lhs, const string_base& rhs )
-	{
-		return lhs.compare( rhs ) < 0;
-	}
-	inline bool operator>( const string_base& lhs, const string_base& rhs )
-	{
-		return lhs.compare( rhs ) > 0;
-	}
-	inline bool operator<=( const string_base& lhs, const string_base& rhs )
-	{
-		return lhs.compare( rhs ) <= 0;
-	}
-	inline bool operator>=( const string_base& lhs, const string_base& rhs )
-	{
-		return lhs.compare( rhs ) >= 0;
-	}
-
-NV_STRING_BASE_CAST_OPERATORS( == )
-NV_STRING_BASE_CAST_OPERATORS( != )
-NV_STRING_BASE_CAST_OPERATORS( < )
-NV_STRING_BASE_CAST_OPERATORS( > )
-NV_STRING_BASE_CAST_OPERATORS( <= )
-NV_STRING_BASE_CAST_OPERATORS( >= )
-
-	inline std::ostream& operator<<( std::ostream& os, const string_base& str )
-	{
-		if ( os.good() )
-		{
-			os.write( str.data(), static_cast<std::streamsize>( str.size() ) );
-		}
-		return os;
-	}
-
-#undef NV_STRING_REF_CAST_OPERATORS
-
-size_t sint32_to_buffer( sint32 n, char* str );
-size_t sint64_to_buffer( sint64 n, char* str );
-size_t uint32_to_buffer( uint32 n, char* str );
-size_t uint64_to_buffer( uint64 n, char* str );
-size_t f32_to_buffer( f32 n, char* str );
-size_t f64_to_buffer( f64 n, char* str );
-
-
-}
-
-namespace std
-{
-
-	template<>
-	struct hash< nv::string_base >
-	{
-		std::size_t operator()( const nv::string_base& s ) const
-		{
-			return s.hash();
-		}
-	};
-
-}
-
-#endif // NV_CORE_STRING_HH
Index: /trunk/nv/core/transform.hh
===================================================================
--- /trunk/nv/core/transform.hh	(revision 367)
+++ /trunk/nv/core/transform.hh	(revision 368)
@@ -9,5 +9,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 
 namespace nv
Index: unk/nv/core/type_traits.hh
===================================================================
--- /trunk/nv/core/type_traits.hh	(revision 367)
+++ 	(revision )
@@ -1,178 +1,0 @@
-// Copyright (C) 2012-2014 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 type_traits.hh
- * @author Kornel Kisielewicz epyon@chaosforge.org
- * @brief type traits
- */
-// TODO: function_traits support only up to 4 parameters because:
-//    -- if you have more than 4 params, you're doing something wrong
-//    -- once the Variadic Templates cometh, for great justice we will win!
-
-#ifndef NV_CORE_TYPE_TRAITS_HH
-#define NV_CORE_TYPE_TRAITS_HH
-
-#include <nv/core/common.hh>
-#include <type_traits>
-
-namespace nv
-{
-
-	// These could be done much better
-	template <typename T>
-	struct is_cstring
-		: public std::integral_constant<bool,
-		std::is_same<       char *, typename std::decay< T >::type >::value ||
-		std::is_same< const char *, typename std::decay< T >::type >::value >
-		{};
-
-	template <typename T>
-	struct is_stdstring
-		: public std::integral_constant<bool,
-		std::is_same< std::string, typename std::decay< T >::type >::value 
-		>
-	{};
-
-	template < typename T > struct is_string : public std::integral_constant<bool, is_stdstring<T>::value || is_cstring<T>::value> {};
-
-	// Just for once, MSVC is the good guy, and everybody else sucks.
-	// Remove, once requiring standard-compliant CLANG/GCC versions.
-#if NV_COMPILER == NV_MSVC
-	using std::underlying_type;
-#elif NV_COMPILER == NV_CLANG
-	template < typename T >
-	struct underlying_type
-	{
-		typedef __underlying_type(T) type;
-	};
-#else
-	template< typename T >
-	struct underlying_type
-	{
-		typedef typename std::conditional<
-			T( -1 ) < T( 0 ),
-			typename std::make_signed< T >::type,
-			typename std::make_unsigned< T >::type
-			>::type type;
-	};
-#endif
-
-	namespace detail
-	{
-
-		template < typename F >
-		struct function_traits_impl
-		{
-
-		};
-
-		template < typename R >
-		struct function_traits_impl< R (*)(void) >
-		{
-			typedef R (*type)();
-			typedef R        return_type;
-			typedef void     class_type;
-			static const int arg_count = 0;
-		};
-
-		template < typename R, typename... Args >
-		struct function_traits_impl < R(*)(Args...) >
-		{
-			typedef R(*type)( Args... );
-			typedef R        return_type;
-			typedef void     class_type;
-			static const int arg_count = sizeof...(Args);
-		};
-
-		template < class C, typename R >
-		struct function_traits_impl< R (C::*)() >
-		{
-			typedef R (*type)();
-			typedef R       return_type;
-			typedef C       class_type;
-			static const int arg_count = 0;
-		};
-
-		template < class C, typename R, typename... Args >
-		struct function_traits_impl < R(C::*)(Args...) >
-		{
-			typedef R(C::*type)(Args...);
-			typedef R        return_type;
-			typedef C        class_type;
-			static const int arg_count = sizeof...(Args);
-		};
-
-	}
-
-	template < typename F >
-	struct function_traits : public detail::function_traits_impl< F >
-	{
-
-	};
-
-	template < typename T >
-	struct return_type
-	{
-		typedef typename function_traits< T >::return_type type;
-	};
-
-	template < typename T >
-	struct memfn_class_type
-	{
-		typedef typename function_traits< T >::class_type type;
-	};
-
-	template<typename T>
-	struct is_container
-	{
-	private:
-		typedef char                      yes;
-		typedef struct { char array[2]; } no;
-		template<typename C> static yes test(typename C::iterator*);
-		template<typename C> static no  test(...);
-	public:
-		static const bool value = sizeof(test<T>(0)) == sizeof(yes);
-	};
-
-	template<>
-	struct is_container< std::string > {
-		static const bool value = false;
-	};
-
-	template <typename TYPE> 
-	void construct_object(void* object)
-	{
-		new (object) TYPE;
-	}
-	template <typename TYPE> 
-	void destroy_object(void* object)
-	{
-		((TYPE*)object)->TYPE::~TYPE();
-	}
-
-	template< typename T, typename IS_ENUM >
-	struct base_underlying_type_helper
-	{
-		typedef T type;
-	};
-
-	template< typename T >
-	struct base_underlying_type_helper< T, std::true_type >
-	{
-		typedef typename nv::underlying_type<T>::type type;
-	};
-
-
-	template< typename T >
-	struct base_underlying_type
-	{
-		typedef typename base_underlying_type_helper< T, typename std::is_enum<T>::type >::type type;
-	};
-
-
-}
-
-#endif // NV_CORE_TYPE_TRAITS_HH
Index: /trunk/nv/engine/particle_engine.hh
===================================================================
--- /trunk/nv/engine/particle_engine.hh	(revision 367)
+++ /trunk/nv/engine/particle_engine.hh	(revision 368)
@@ -9,7 +9,7 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
-#include <nv/core/array.hh>
-#include <nv/core/handle.hh>
+#include <nv/stl/math.hh>
+#include <nv/stl/array.hh>
+#include <nv/stl/handle.hh>
 #include <nv/lua/lua_state.hh>
 #include <nv/gfx/texture_atlas.hh>
Index: /trunk/nv/formats/md2_loader.hh
===================================================================
--- /trunk/nv/formats/md2_loader.hh	(revision 367)
+++ /trunk/nv/formats/md2_loader.hh	(revision 368)
@@ -16,5 +16,5 @@
 #include <nv/core/common.hh>
 #include <unordered_map>
-#include <nv/core/array.hh>
+#include <nv/stl/array.hh>
 #include <nv/interface/mesh_loader.hh>
 
Index: /trunk/nv/formats/md3_loader.hh
===================================================================
--- /trunk/nv/formats/md3_loader.hh	(revision 367)
+++ /trunk/nv/formats/md3_loader.hh	(revision 368)
@@ -16,5 +16,5 @@
 #include <nv/core/common.hh>
 #include <unordered_map>
-#include <nv/core/array.hh>
+#include <nv/stl/array.hh>
 #include <nv/core/transform.hh>
 #include <nv/interface/mesh_data.hh>
Index: /trunk/nv/formats/md5_loader.hh
===================================================================
--- /trunk/nv/formats/md5_loader.hh	(revision 367)
+++ /trunk/nv/formats/md5_loader.hh	(revision 368)
@@ -15,5 +15,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/array.hh>
+#include <nv/stl/array.hh>
 #include <nv/interface/mesh_loader.hh>
 
Index: /trunk/nv/gfx/animation.hh
===================================================================
--- /trunk/nv/gfx/animation.hh	(revision 367)
+++ /trunk/nv/gfx/animation.hh	(revision 368)
@@ -9,7 +9,7 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/array.hh>
+#include <nv/stl/array.hh>
 #include <nv/interface/stream.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/interface/animation_key.hh>
 #include <nv/interface/interpolation_raw.hh>
Index: /trunk/nv/gfx/debug_draw.hh
===================================================================
--- /trunk/nv/gfx/debug_draw.hh	(revision 367)
+++ /trunk/nv/gfx/debug_draw.hh	(revision 368)
@@ -9,5 +9,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/interface/context.hh>
 
Index: /trunk/nv/gfx/image.hh
===================================================================
--- /trunk/nv/gfx/image.hh	(revision 367)
+++ /trunk/nv/gfx/image.hh	(revision 368)
@@ -9,5 +9,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/interface/image_data.hh>
 
Index: /trunk/nv/gfx/mesh_creator.hh
===================================================================
--- /trunk/nv/gfx/mesh_creator.hh	(revision 367)
+++ /trunk/nv/gfx/mesh_creator.hh	(revision 368)
@@ -9,5 +9,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/interface/mesh_data.hh>
 
Index: /trunk/nv/gfx/sliced_buffer.hh
===================================================================
--- /trunk/nv/gfx/sliced_buffer.hh	(revision 367)
+++ /trunk/nv/gfx/sliced_buffer.hh	(revision 368)
@@ -12,5 +12,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 
 namespace nv
Index: /trunk/nv/gfx/texture_atlas.hh
===================================================================
--- /trunk/nv/gfx/texture_atlas.hh	(revision 367)
+++ /trunk/nv/gfx/texture_atlas.hh	(revision 368)
@@ -11,5 +11,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/gfx/image.hh>
 #include <vector>
Index: /trunk/nv/gfx/texture_font.hh
===================================================================
--- /trunk/nv/gfx/texture_font.hh	(revision 367)
+++ /trunk/nv/gfx/texture_font.hh	(revision 368)
@@ -9,7 +9,7 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/string.hh>
+#include <nv/stl/string.hh>
 #include <unordered_map>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/gfx/texture_atlas.hh>
 
Index: /trunk/nv/gl/gl_enum.hh
===================================================================
--- /trunk/nv/gl/gl_enum.hh	(revision 367)
+++ /trunk/nv/gl/gl_enum.hh	(revision 368)
@@ -13,5 +13,5 @@
 #define NV_GL_ENUM_HH
 
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/interface/clear_state.hh>
 #include <nv/interface/render_state.hh>
Index: /trunk/nv/gui/gui_ascii_renderer.hh
===================================================================
--- /trunk/nv/gui/gui_ascii_renderer.hh	(revision 367)
+++ /trunk/nv/gui/gui_ascii_renderer.hh	(revision 368)
@@ -15,5 +15,5 @@
 
 #include <nv/core/position.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/interface/terminal.hh>
 #include <nv/gui/gui_renderer.hh>
Index: /trunk/nv/gui/gui_common.hh
===================================================================
--- /trunk/nv/gui/gui_common.hh	(revision 367)
+++ /trunk/nv/gui/gui_common.hh	(revision 368)
@@ -15,6 +15,6 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/handle.hh>
-#include <nv/core/flags.hh>
+#include <nv/stl/handle.hh>
+#include <nv/stl/flags.hh>
 
 namespace nv
Index: /trunk/nv/gui/gui_element.hh
===================================================================
--- /trunk/nv/gui/gui_element.hh	(revision 367)
+++ /trunk/nv/gui/gui_element.hh	(revision 368)
@@ -17,5 +17,5 @@
 #include <nv/core/position.hh>
 #include <nv/core/io_event.hh>
-#include <nv/core/string.hh>
+#include <nv/stl/string.hh>
 #include <nv/gui/gui_common.hh>
 #include <list>
Index: /trunk/nv/gui/gui_environment.hh
===================================================================
--- /trunk/nv/gui/gui_environment.hh	(revision 367)
+++ /trunk/nv/gui/gui_environment.hh	(revision 368)
@@ -19,5 +19,5 @@
 #include <nv/core/io_event.hh>
 #include <nv/interface/window.hh>
-#include <nv/core/array.hh>
+#include <nv/stl/array.hh>
 
 namespace nv
Index: /trunk/nv/gui/gui_renderer.hh
===================================================================
--- /trunk/nv/gui/gui_renderer.hh	(revision 367)
+++ /trunk/nv/gui/gui_renderer.hh	(revision 368)
@@ -15,5 +15,5 @@
 
 #include <nv/core/position.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/gui/gui_common.hh>
 #include <nv/gui/gui_style.hh>
Index: /trunk/nv/interface/animated_mesh.hh
===================================================================
--- /trunk/nv/interface/animated_mesh.hh	(revision 367)
+++ /trunk/nv/interface/animated_mesh.hh	(revision 368)
@@ -15,5 +15,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/core/transform.hh>
 #include <nv/interface/context.hh>
Index: /trunk/nv/interface/animation_key.hh
===================================================================
--- /trunk/nv/interface/animation_key.hh	(revision 367)
+++ /trunk/nv/interface/animation_key.hh	(revision 368)
@@ -12,5 +12,5 @@
 #include <nv/core/common.hh>
 #include <nv/core/transform.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 
 namespace nv
Index: /trunk/nv/interface/audio.hh
===================================================================
--- /trunk/nv/interface/audio.hh	(revision 367)
+++ /trunk/nv/interface/audio.hh	(revision 368)
@@ -14,6 +14,6 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
-#include <nv/core/handle.hh>
+#include <nv/stl/math.hh>
+#include <nv/stl/handle.hh>
 
 namespace nv
Index: /trunk/nv/interface/camera.hh
===================================================================
--- /trunk/nv/interface/camera.hh	(revision 367)
+++ /trunk/nv/interface/camera.hh	(revision 368)
@@ -14,5 +14,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 
 namespace nv
Index: /trunk/nv/interface/clear_state.hh
===================================================================
--- /trunk/nv/interface/clear_state.hh	(revision 367)
+++ /trunk/nv/interface/clear_state.hh	(revision 368)
@@ -15,5 +15,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 
 namespace nv
Index: /trunk/nv/interface/device.hh
===================================================================
--- /trunk/nv/interface/device.hh	(revision 367)
+++ /trunk/nv/interface/device.hh	(revision 368)
@@ -14,6 +14,6 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/string.hh>
-#include <nv/core/handle.hh>
+#include <nv/stl/string.hh>
+#include <nv/stl/handle.hh>
 #include <nv/interface/uniform.hh>
 #include <nv/interface/mesh_data.hh>
Index: /trunk/nv/interface/image_data.hh
===================================================================
--- /trunk/nv/interface/image_data.hh	(revision 367)
+++ /trunk/nv/interface/image_data.hh	(revision 368)
@@ -15,5 +15,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <algorithm>
 
Index: /trunk/nv/interface/interpolation_raw.hh
===================================================================
--- /trunk/nv/interface/interpolation_raw.hh	(revision 367)
+++ /trunk/nv/interface/interpolation_raw.hh	(revision 368)
@@ -12,5 +12,5 @@
 #include <nv/core/common.hh>
 #include <nv/core/transform.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/interface/animation_key.hh>
 
Index: /trunk/nv/interface/interpolation_template.hh
===================================================================
--- /trunk/nv/interface/interpolation_template.hh	(revision 367)
+++ /trunk/nv/interface/interpolation_template.hh	(revision 368)
@@ -12,5 +12,5 @@
 #include <nv/core/common.hh>
 #include <nv/core/transform.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/interface/animation_key.hh>
 
Index: /trunk/nv/interface/map_area.hh
===================================================================
--- /trunk/nv/interface/map_area.hh	(revision 367)
+++ /trunk/nv/interface/map_area.hh	(revision 368)
@@ -14,7 +14,7 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/string.hh>
-#include <nv/core/array.hh>
 #include <nv/core/position.hh>
+#include <nv/stl/string.hh>
+#include <nv/stl/array.hh>
 
 namespace nv
Index: /trunk/nv/interface/mesh_data.hh
===================================================================
--- /trunk/nv/interface/mesh_data.hh	(revision 367)
+++ /trunk/nv/interface/mesh_data.hh	(revision 368)
@@ -9,7 +9,7 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
-#include <nv/core/string.hh>
-#include <nv/core/array.hh>
+#include <nv/stl/math.hh>
+#include <nv/stl/string.hh>
+#include <nv/stl/array.hh>
 #include <nv/gfx/animation.hh>
 #include <nv/interface/vertex.hh>
Index: /trunk/nv/interface/mesh_loader.hh
===================================================================
--- /trunk/nv/interface/mesh_loader.hh	(revision 367)
+++ /trunk/nv/interface/mesh_loader.hh	(revision 368)
@@ -15,8 +15,8 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/array.hh>
+#include <nv/stl/array.hh>
 #include <unordered_map>
 #include <nv/core/transform.hh>
-#include <nv/core/string.hh>
+#include <nv/stl/string.hh>
 #include <nv/gfx/animation.hh>
 #include <nv/interface/mesh_data.hh>
Index: /trunk/nv/interface/render_state.hh
===================================================================
--- /trunk/nv/interface/render_state.hh	(revision 367)
+++ /trunk/nv/interface/render_state.hh	(revision 368)
@@ -15,7 +15,7 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/interface/clear_state.hh>
-#include <nv/core/string.hh>
+#include <nv/stl/string.hh>
 
 namespace nv
Index: /trunk/nv/interface/scene_node.hh
===================================================================
--- /trunk/nv/interface/scene_node.hh	(revision 367)
+++ /trunk/nv/interface/scene_node.hh	(revision 368)
@@ -14,7 +14,7 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/array.hh>
+#include <nv/stl/array.hh>
 #include <nv/core/transform.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/interface/render_state.hh>
 
Index: /trunk/nv/interface/uniform.hh
===================================================================
--- /trunk/nv/interface/uniform.hh	(revision 367)
+++ /trunk/nv/interface/uniform.hh	(revision 368)
@@ -15,5 +15,5 @@
 #include <nv/interface/camera.hh>
 #include <nv/core/common.hh>
-#include <nv/core/string.hh>
+#include <nv/stl/string.hh>
 #include <unordered_map>
 
Index: /trunk/nv/interface/vertex.hh
===================================================================
--- /trunk/nv/interface/vertex.hh	(revision 367)
+++ /trunk/nv/interface/vertex.hh	(revision 368)
@@ -12,5 +12,5 @@
 #include <nv/core/common.hh>
 #include <nv/core/transform.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 
 namespace nv
Index: /trunk/nv/interface/window.hh
===================================================================
--- /trunk/nv/interface/window.hh	(revision 367)
+++ /trunk/nv/interface/window.hh	(revision 368)
@@ -14,6 +14,6 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/string.hh>
 #include <nv/core/io_event.hh>
+#include <nv/stl/string.hh>
 
 namespace nv
Index: /trunk/nv/interface/window_manager.hh
===================================================================
--- /trunk/nv/interface/window_manager.hh	(revision 367)
+++ /trunk/nv/interface/window_manager.hh	(revision 368)
@@ -14,5 +14,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/string.hh>
+#include <nv/stl/string.hh>
 
 namespace nv
Index: /trunk/nv/io/string_table.hh
===================================================================
--- /trunk/nv/io/string_table.hh	(revision 367)
+++ /trunk/nv/io/string_table.hh	(revision 368)
@@ -14,5 +14,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/array.hh>
+#include <nv/stl/array.hh>
 #include <unordered_map>
 #include <nv/interface/stream.hh>
Index: /trunk/nv/lib/assimp.hh
===================================================================
--- /trunk/nv/lib/assimp.hh	(revision 367)
+++ /trunk/nv/lib/assimp.hh	(revision 368)
@@ -10,6 +10,6 @@
 #include <nv/core/common.hh>
 #include <nv/core/logging.hh>
-#include <nv/core/string.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/string.hh>
+#include <nv/stl/math.hh>
 
 #define NV_ASSIMP_DYNAMIC
Index: /trunk/nv/lua/lua_dispatch.hh
===================================================================
--- /trunk/nv/lua/lua_dispatch.hh	(revision 367)
+++ /trunk/nv/lua/lua_dispatch.hh	(revision 368)
@@ -15,5 +15,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/string.hh>
+#include <nv/stl/string.hh>
 #include <nv/lua/lua_values.hh>
 #include <nv/lua/lua_path.hh>
Index: /trunk/nv/lua/lua_flags.hh
===================================================================
--- /trunk/nv/lua/lua_flags.hh	(revision 367)
+++ /trunk/nv/lua/lua_flags.hh	(revision 368)
@@ -8,5 +8,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/flags.hh>
+#include <nv/stl/flags.hh>
 #include <nv/lua/lua_state.hh>
 #include <nv/lua/lua_values.hh>
Index: /trunk/nv/lua/lua_glm.hh
===================================================================
--- /trunk/nv/lua/lua_glm.hh	(revision 367)
+++ /trunk/nv/lua/lua_glm.hh	(revision 368)
@@ -9,5 +9,5 @@
 #include <new>
 #include <nv/core/common.hh>
-#include <nv/core/math.hh>
+#include <nv/stl/math.hh>
 #include <nv/lua/lua_values.hh>
 
Index: /trunk/nv/lua/lua_handle.hh
===================================================================
--- /trunk/nv/lua/lua_handle.hh	(revision 367)
+++ /trunk/nv/lua/lua_handle.hh	(revision 368)
@@ -8,5 +8,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/handle.hh>
+#include <nv/stl/handle.hh>
 #include <nv/lua/lua_values.hh>
 
Index: /trunk/nv/lua/lua_path.hh
===================================================================
--- /trunk/nv/lua/lua_path.hh	(revision 367)
+++ /trunk/nv/lua/lua_path.hh	(revision 368)
@@ -15,5 +15,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/string.hh>
+#include <nv/stl/string.hh>
 #include <cstring>
 
Index: /trunk/nv/lua/lua_raw.hh
===================================================================
--- /trunk/nv/lua/lua_raw.hh	(revision 367)
+++ /trunk/nv/lua/lua_raw.hh	(revision 368)
@@ -8,5 +8,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/array.hh>
+#include <nv/stl/array.hh>
 #include <nv/lib/lua.hh>
 
Index: /trunk/nv/lua/lua_state.hh
===================================================================
--- /trunk/nv/lua/lua_state.hh	(revision 367)
+++ /trunk/nv/lua/lua_state.hh	(revision 368)
@@ -13,6 +13,6 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/flags.hh>
-#include <nv/core/handle.hh>
+#include <nv/stl/flags.hh>
+#include <nv/stl/handle.hh>
 
 #include <nv/lua/lua_handle.hh>
Index: /trunk/nv/lua/lua_values.hh
===================================================================
--- /trunk/nv/lua/lua_values.hh	(revision 367)
+++ /trunk/nv/lua/lua_values.hh	(revision 368)
@@ -9,6 +9,6 @@
 
 #include <nv/core/common.hh>
-#include <nv/core/type_traits.hh>
-#include <nv/core/string.hh>
+#include <nv/stl/type_traits.hh>
+#include <nv/stl/string.hh>
 
 struct lua_State;
Index: /trunk/nv/stl/allocator.hh
===================================================================
--- /trunk/nv/stl/allocator.hh	(revision 368)
+++ /trunk/nv/stl/allocator.hh	(revision 368)
@@ -0,0 +1,61 @@
+// 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 allocator.hh
+* @author Kornel Kisielewicz
+* @brief allocator type
+*
+* Allocator concept based on:
+*
+* http://bitsquid.blogspot.com/2010/09/custom-memory-allocation-in-c.html
+* http://www.gamedev.net/page/resources/_/technical/general-programming/c-custom-memory-allocation-r3010
+*/
+
+#ifndef NV_CORE_ALLOCATOR_HH
+#define NV_CORE_ALLOCATOR_HH
+
+#include <nv/core/common.hh>
+#include <nv/core/type_traits.hh>
+
+namespace nv
+{
+
+	class allocator
+	{
+	public:
+		virtual void* allocate( size_t size, size_t alignment ) = 0;
+		virtual void deallocate( void *p ) = 0;
+		virtual void* reallocate( void* p, size_t new_size ) = 0;
+		virtual size_t allocated_size( void *p ) = 0;
+
+		virtual size_t get_allocated_count() = 0;
+		virtual size_t get_allocated_size() = 0;
+		virtual size_t get_max_allocated_count() = 0;
+		virtual size_t get_max_allocated_size() = 0;
+
+		template < class T, typename... Args > 
+		T *create( Args&&... args ) 
+		{
+			return new ( allocate( sizeof( T ), alignof( T ) ) ) T( std::forward<Args>( args )... );
+		}
+
+		template <class T> 
+		void destroy( T *p )
+		{
+			if ( p )
+			{
+				p->~T();
+				deallocate( p );
+			}
+		}
+	};
+
+
+
+}
+
+#endif // NV_CORE_ALLOCATOR_HH
Index: /trunk/nv/stl/any.hh
===================================================================
--- /trunk/nv/stl/any.hh	(revision 368)
+++ /trunk/nv/stl/any.hh	(revision 368)
@@ -0,0 +1,154 @@
+// Copyright (C) 2014 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 any.hh
+ * @author Kornel Kisielewicz
+ * @brief any type
+ *
+ * based on http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf
+ */
+
+#ifndef NV_CORE_ANY_HH
+#define NV_CORE_ANY_HH
+
+#include <nv/core/common.hh>
+#include <nv/core/type_traits.hh>
+
+namespace nv
+{
+	
+	class any
+	{
+	public:
+		any() : m_content( nullptr ) {}
+		
+		any( const any& other )
+			: m_content( other.m_content ? other.m_content->clone() : nullptr )
+		{}
+
+		template< typename T >
+		any( const T& value )
+			: m_content( new holder<T>( value ) )
+		{}
+
+		any( any&& other ) 
+			: m_content( other.m_content )
+		{}
+
+		template< typename T >
+		any( T&& value )
+			: m_content( new holder<T>( std::forward<T>(value) ) )
+		{}
+
+		~any() 
+		{ 
+			delete m_content; 
+		}
+
+		any& swap( any& rhs )
+		{
+			std::swap( m_content, rhs.m_content );
+			return *this;
+		}
+
+		any& operator=( const any& rhs )
+		{
+			return swap( any( rhs ) );
+		}
+
+		any& operator=( any&& rhs )
+		{
+			swap( rhs );
+			any().swap( rhs );
+			return *this;
+		}
+
+		template < typename T >
+		any& operator= ( T&& rhs )
+		{
+			any( std::forward<T>(rhs) ).swap(*this);
+			return *this;
+		}
+
+		operator const void* () const
+		{
+			return m_content;
+		}
+
+		template< typename T >
+		bool copy_to( T& value ) const
+		{
+			const T* copyable = to_ptr<T>();
+			if ( copyable ) value = *copyable;
+			return copyable;
+		}
+		template< typename T >
+		const T* to_ptr() const
+		{
+			return type_info() == typeid(T) ? &static_cast< holder<T> *>(m_content)->held				: nullptr;
+		}
+
+		bool empty() const
+		{
+			return !m_content;
+		}
+
+		void clear()
+		{
+			any().swap(*this);
+		}
+
+		const std::type_info &type_info() const
+		{
+			return m_content ? m_content->type_info() : typeid(void);
+		}
+	private:
+		class placeholder
+		{
+		public:
+			virtual const std::type_info& type_info() const = 0;
+			virtual placeholder *clone() const = 0;
+			virtual ~placeholder() {}
+		};
+
+		template< typename T >
+		class holder : public placeholder
+		{
+		public:
+			holder( const T& value ) : held(value)
+			{
+			}
+			holder( T&& value ) : held(std::forward<T>(value))
+			{
+			}
+			virtual const std::type_info &type_info() const
+			{
+				return typeid(T);
+			}
+			virtual placeholder *clone() const
+			{
+				return new holder(held);
+			}
+			const T held;
+		};
+		placeholder *m_content;
+	};
+
+	inline void swap( any& lhs, any& rhs )
+	{
+		lhs.swap(rhs);
+	}
+
+	template< typename T >
+	T any_cast( const any& operand )
+	{
+		const T* result = operand.to_ptr<T>();
+		return result ? *result : throw std::bad_cast();
+	}
+}
+
+#endif // NV_CORE_ANY_HH
Index: /trunk/nv/stl/array.hh
===================================================================
--- /trunk/nv/stl/array.hh	(revision 368)
+++ /trunk/nv/stl/array.hh	(revision 368)
@@ -0,0 +1,195 @@
+// Copyright (C) 2014 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 array.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief exception free array classes
+ */
+
+#ifndef NV_CORE_ARRAY_HH
+#define NV_CORE_ARRAY_HH
+
+#include <nv/core/common.hh>
+#include <nv/stl/memory.hh>
+#include <vector>
+#include <algorithm>
+#include <array>
+
+namespace nv
+{
+	using std::vector;
+	using std::array;
+
+	template< class T, std::size_t N >
+	class static_array : public detail::data_base< T, false, N >
+	{
+	public:
+		typedef T              value_type;
+		typedef T*             iterator;
+		typedef const T*       const_iterator;
+		typedef T&             reference;
+		typedef const T&       const_reference;
+		typedef std::size_t    size_type;
+		typedef std::ptrdiff_t difference_type;
+
+		typedef std::reverse_iterator<iterator>       reverse_iterator;
+		typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+// 		iterator        begin()        { return m_data; }
+// 		const_iterator  begin()  const { return m_data; }
+// 		const_iterator  cbegin() const { return m_data; }
+// 
+// 		iterator        end()        { return m_data+N; }
+// 		const_iterator  end()  const { return m_data+N; }
+// 		const_iterator  cend() const { return m_data+N; }
+// 
+// 		reverse_iterator rbegin()              { return reverse_iterator( end() ); }
+// 		const_reverse_iterator rbegin() const  { return const_reverse_iterator( end() ); }
+// 		const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); }
+// 
+// 		reverse_iterator rend()                { return reverse_iterator( begin() ); }
+// 		const_reverse_iterator rend() const    { return const_reverse_iterator( begin() ); }
+// 		const_reverse_iterator crend() const   { return const_reverse_iterator( begin() ); }
+
+		reference operator[]( size_type i ) 
+		{ 
+			NV_ASSERT( i < N, "Out of range" ); 
+			return this->m_data[i];
+		}
+
+		const_reference operator[]( size_type i ) const 
+		{     
+			NV_ASSERT( i < N, "Out of range" ); 
+			return this->m_data[i];
+		}
+
+// 		reference       front()       { return m_data[0]; }
+// 		const_reference front() const { return m_data[0]; }
+// 		reference       back()        { return m_data[N-1]; }
+// 		const_reference back() const  { return m_data[N-1]; }
+// 
+// 		static size_type size()     { return N; }
+// 		static bool      empty()    { return false; }
+// 		static size_type max_size() { return N; }
+// 
+// 		const value_type* data() const { return m_data; }
+// 		value_type*       data()       { return m_data; }
+// 
+// 		size_type   raw_size() const { return N * ELEMENT_SIZE; }
+// 		const char* raw_data() const { return (const char*)m_data; }
+// 		char*       raw_data()       { return (char*)m_data; }
+
+		void assign( const value_type& value ) { std::fill_n( this->begin(), this->size(), value ); }
+
+		static const size_type SIZE = N;
+		static const size_type ELEMENT_SIZE = sizeof(T);
+	};
+
+	template< class T >
+	class dynamic_array : public detail::data_base< T, false, 0 >
+	{
+	public:
+		typedef T              value_type;
+		typedef T*             iterator;
+		typedef const T*       const_iterator;
+		typedef T&             reference;
+		typedef const T&       const_reference;
+		typedef std::size_t    size_type;
+		typedef std::ptrdiff_t difference_type;
+
+		typedef std::reverse_iterator<iterator>       reverse_iterator;
+		typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+		dynamic_array() : detail::data_base< T, false, 0 >() {}
+//			: m_data( nullptr ), m_size(0) {}
+		explicit dynamic_array( size_type new_size ) : detail::data_base< T, false, 0 >( new value_type[new_size], new_size ) {}
+//			: m_data( new value_type[ new_size ] ), m_size( new_size ) {}
+		dynamic_array( const value_type& value, size_type size ) : detail::data_base< T, false, 0 >()
+//			: m_data( nullptr ), m_size(0) 
+		{ assign( value, size ); }
+		dynamic_array( const_iterator values, size_type size ) : detail::data_base< T, false, 0 >()
+//			: m_data( nullptr ), m_size(0) 
+		{ assign( values, size ); }
+
+		void resize( size_type new_size )
+		{
+			if ( new_size != this->m_size )
+			{
+				value_type* old_data = this->m_data;
+				this->m_data = new_size > 0 ? new value_type[new_size] : nullptr;
+				if ( old_data && this->m_data )
+				{
+					std::copy_n( old_data, new_size > this->m_size ? this->m_size : new_size, this->m_data );
+				}
+				delete[] old_data;
+				this->m_size = new_size;
+			}
+		}
+
+// 		iterator        begin()        { return m_data; }
+// 		const_iterator  begin()  const { return m_data; }
+// 		const_iterator  cbegin() const { return m_data; }
+// 
+// 		iterator        end()        { return m_data+m_size; }
+// 		const_iterator  end()  const { return m_data+m_size; }
+// 		const_iterator  cend() const { return m_data+m_size; }
+// 
+// 		reverse_iterator rbegin()              { return reverse_iterator( end() ); }
+// 		const_reverse_iterator rbegin() const  { return const_reverse_iterator( end() ); }
+// 		const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); }
+// 
+// 		reverse_iterator rend()                { return reverse_iterator( begin() ); }
+// 		const_reverse_iterator rend() const    { return const_reverse_iterator( begin() ); }
+// 		const_reverse_iterator crend() const   { return const_reverse_iterator( begin() ); }
+
+		reference operator[]( size_type i ) 
+		{ 
+			NV_ASSERT( i < this->m_size, "Out of range" );
+			return this->m_data[i];
+		}
+
+		const_reference operator[]( size_type i ) const 
+		{     
+			NV_ASSERT( i < this->m_size, "Out of range" );
+			return this->m_data[i];
+		}
+
+// 		reference       front()       { return m_data[0]; }
+// 		const_reference front() const { return m_data[0]; }
+// 		reference       back()        { return m_data[m_size-1]; }
+// 		const_reference back() const  { return m_data[m_size-1]; }
+// 
+// 		size_type        size() const     { return m_size; }
+// 		bool             empty() const    { return m_size == 0; }
+// 		static size_type max_size()       { return std::numeric_limits< size_type >::max(); }
+// 		const value_type* data() const { return m_data; }
+// 		value_type*       data()       { return m_data; }
+// 
+// 		size_type   raw_size() const { return m_size * ELEMENT_SIZE; }
+// 		const char* raw_data() const { return (const char*)m_data; }
+// 		char*       raw_data()       { return (char*)m_data; }
+
+		void assign( const value_type& value ) { std::fill_n( this->begin(), this->size(), value ); }
+		void assign( const value_type& value, size_type new_size ) 
+		{
+			resize( new_size );
+			std::fill_n( this->begin(), this->size(), value );
+		}
+		void assign( const_iterator values, size_type new_size )
+		{
+			resize( new_size );
+			std::copy_n( values, this->size(), this->m_data );
+		}
+
+		~dynamic_array() { delete[] this->m_data; }
+
+		static const size_type ELEMENT_SIZE = sizeof(T);
+	};
+
+}
+
+#endif // NV_CORE_ARRAY_HH
Index: /trunk/nv/stl/array2d.hh
===================================================================
--- /trunk/nv/stl/array2d.hh	(revision 368)
+++ /trunk/nv/stl/array2d.hh	(revision 368)
@@ -0,0 +1,356 @@
+// Copyright (C) 2012-2014 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 array2d.hh
+ * @author Kornel Kisielewicz
+ * @brief 2D array
+ */
+
+// TODO: make it work with the stl allocator
+
+#ifndef NV_CORE_ARRAY2D_HH
+#define NV_CORE_ARRAY2D_HH
+
+#include <nv/core/common.hh>
+#include <nv/stl/math.hh>
+#include <nv/stl/range.hh>
+
+namespace nv
+{
+	typedef ivec2 coord2d;
+
+	template < typename T >
+	class array2d
+	{
+	public:
+		typedef T                 value_type;
+		typedef value_type&       reference;
+		typedef const value_type& const_reference;
+		typedef value_type*       pointer;
+		typedef const value_type* const_pointer;
+		typedef pointer           iterator;
+		typedef const_pointer     const_iterator;
+
+		/**
+		 * Creates a new 2D array.
+		 */
+		array2d() : m_data( nullptr ), m_size() {}
+
+		/**
+		 * Creates a new 2D array.
+		 *
+		 * @param asize The dimensions of the new array.
+		 */
+		array2d( const ivec2& asize ) : m_data( nullptr ), m_size() { resize( asize ); }
+
+		/**
+		 * Creates a new 2D array.
+		 *
+		 * @param asize_x The width of the new array.
+		 * @param asize_y The height of the new array.
+		 */
+		array2d( const sint32 asize_x, const sint32 asize_y ) : m_data( nullptr ), m_size() { resize( new ivec2( asize_x, asize_y ) ); }
+		
+		/**
+		 * Gets the dimensions of the array.
+		 *
+		 * @returns The size of the array.
+		 */
+		const ivec2& size() const { return m_size; }
+
+		/**
+		 * Gets a pointer to the data in the array.
+		 *
+		 * @returns A pointer to the data in the array.
+		 */
+		pointer data() { return m_data; }
+
+		/**
+		 * Gets a constant pointer to the data in the array.
+		 *
+		 * @returns A constant pointer to the data in the array.
+		 */
+		const_pointer data() const { return m_data; }
+
+		/**
+		 * Changes the dimensions of the array.
+		 *
+		 * @param new_size The new dimensions of the array.
+		 * @param preserve True to keep as much of the existing data as will fit in the new array, False to discard the existing data.
+		 */
+		void resize( const ivec2& new_size, bool preserve = false ) 
+		{
+			if (new_size == m_size) return; // Don't do anything if the sizes are the same.
+
+			pointer new_data = ( (new_size.x * new_size.y != 0) ? new value_type[ new_size.x * new_size.y ] : nullptr );
+			if ( m_data != nullptr )
+			{
+				if ( new_data && preserve )
+				{
+					// Copy the data.  Truncates the bottom or right side of the data if destination is smaller.
+					for ( sint32 i = 0; i < min(new_size.y, m_size.y); i++ )
+					{
+						std::copy( m_data + m_size.x * i, m_data + m_size.x * i + min( new_size.x, m_size.x ), new_data + m_size.x * i );
+					}
+				}
+				delete[] m_data;
+			}
+			m_data = new_data;
+			m_size = new_size;
+		}
+
+		/**
+		 * Gets a pointer to the start of the array.
+		 *
+		 * @returns A pointer to the first position in the array.
+		 */
+		iterator       begin()       { return m_data; }
+
+		/**
+		 * Gets a constant pointer to the start of the array.
+		 *
+		 * @returns A constant pointer to the first position in the array.
+		 */
+		const_iterator begin() const { return m_data; }
+
+		/**
+		 * Gets a pointer to the end of the array.
+		 *
+		 * @returns A pointer to the end of the array.
+		 */
+		iterator       end()         { return m_data + ( m_size.x * m_size.y ); }
+
+		/**
+		 * Gets a constant pointer to the end of the array.
+		 *
+		 * @returns A constant pointer to the end of the array.
+		 */
+		const_iterator end() const   { return m_data + ( m_size.x * m_size.y ); }
+
+
+		/**
+		 * Looks up a position by X and Y value.
+		 *
+		 * @param x The X position of the array to look up.
+		 * @param y The Y position of the array to look up.
+		 * @returns A reference to the data at the indicated position.
+		 */
+		inline const_reference operator() ( sint32 x, sint32 y ) const
+		{
+			NV_ASSERT( x >= 0 && y >= 0 && x < m_size.x && y < m_size.y, "Bad parameters passed to array2d()" );
+			return m_data[ y * m_size.x + x ];
+		}
+
+		/**
+		 * Looks up a position by X and Y value.
+		 *
+		 * @param x The X position of the array to look up.
+		 * @param y The Y position of the array to look up.
+		 * @returns A reference to the data at the indicated position.
+		 */
+		inline reference operator() ( sint32 x, sint32 y )
+		{
+			NV_ASSERT( x >= 0 && y >= 0 && x < m_size.x && y < m_size.y, "Bad parameters passed to array2d()" );
+			return m_data[ y * m_size.x + x ];
+		}
+
+		/**
+		 * Looks up the given position in the array.
+		 *
+		 * @param c The position to look up.
+		 * @returns A reference to the data at the indicated position.
+		 */
+		inline const_reference operator[] ( const ivec2& c ) const 
+		{
+			NV_ASSERT( c.x >= 0 && c.y >= 0 && c.x < m_size.x && c.y < m_size.y, "Bad parameters passed to array2d[]" );
+			return m_data[ c.y * m_size.x + c.x ];
+		}
+
+		/**
+		 * Looks up the given position in the array.
+		 *
+		 * @param c The position to look up.
+		 * @returns A reference to the data at the indicated position.
+		 */
+		inline reference operator[] ( const ivec2& c )
+		{
+			NV_ASSERT( c.x >= 0 && c.y >= 0 && c.x < m_size.x && c.y < m_size.y, "Bad parameters passed to array2d[]" );
+			return m_data[ c.y * m_size.x + c.x ];
+		}
+
+		/**
+		 * Returns a copy of this array in a new instance.
+		 *
+		 * @returns An independent copy of this array.
+		 */
+		array2d<T> clone()
+		{
+			array2d<T> temp = new array2d<T>(m_size);
+			for ( sint32 i = 0; i < m_size.y; i++ )
+			{
+				std::copy( m_data + m_size.x * i, m_data + m_size.x * i + m_size.x, m_size.x * i );
+			}
+			return temp;
+		}
+
+		/**
+		 * Returns an array that represents a subset of the data in this array.
+		 *
+		 * @param start The upper and left bounds of data to retrieve.
+		 * @param size The width and height of the data to retrieve.
+		 * @returns A new 2D array containing the subset of data within the bounds specified.
+		 */
+		array2d<T> get_sub_array( const ivec2& start, const ivec2& size ) {	return get_sub_array( start.x, start.y, size.x, size.y ); }
+
+		/**
+		 * Returns an array that represents a subset of the data in this array.
+		 *
+		 * @param start_x The left bound of the data to retrieve.
+		 * @param start_y The upper bound of the data to retrieve.
+		 * @param size_x The width of the data to retrieve.
+		 * @param size_y The height of the data to retrieve.
+		 * @returns A new 2D array containing the subset of data within the bounds specified.
+		 */
+		array2d<T> get_sub_array( const sint32 start_x, const sint32 start_y, const sint32 size_x, const sint32 size_y)
+		{
+			// Make sure the parameters are correct and in bounds.
+			NV_ASSERT( start_x >= 0 && start_x < m_size.x && start_y >= 0 && start_y < m_size.y, "get_sub_array: start is out of bounds." );
+			NV_ASSERT( size_x >= 1 && size_x + start_x <= m_size.x && size_y >= 1 && size_y + start_y <= m_size.y, "get_sub_array: size is invalid." );
+			// Empty holder for the sub array of the correct size.
+			array2d<T> temp = new array2d<T>( size_x, size_y );
+			for ( sint32 i = start_y; i < start_y + size_y; i++ )
+			{
+				// Copy starts at start_x.
+				// Copy end is the end position.
+				// Destination is the start of the destination row.
+				//         Start                              End                                         Destination
+				std::copy( m_data + m_size().x * i + start_x, m_data + m_size().x * i + start_x + size_x, temp.m_data + temp.m_size().x * ( i - start_y ) );
+			}
+			return temp;
+		}
+
+		/**
+		 * Fills this array with another array.
+		 *
+		 * @param source The array to fill with.  If it does not fit in the destination it will be truncated.
+		 * @param dest_start The upper and left bounds of the data to fill.
+		 */
+		void set_sub_array( const array2d<T> source, const ivec2& dest_start )
+		{
+			return set_sub_array( source, dest_start.x, dest_start.y, 0, 0, source.m_size.x, source.m_size.y );
+		}
+
+		/**
+		 * Fills this array with a subset of another array.
+		 *
+		 * @param source The arrya to fill with.  If it does not fit in the destination it will be truncated.
+		 * @param dest_start The upper and left bounds of the data to fill.
+		 * @param size The size of the area to copy over.
+		 */
+		void set_sub_array( const array2d<T> source, const ivec2& dest_start, const ivec2& size )
+		{
+			return set_sub_array( source, dest_start.x, dest_start.y, 0, 0, size.x, size.y );
+		}
+
+
+		/**
+		 * Fills this array with a subset of another array.
+		 *
+		 * @param source The array to fill with.  If it does not fit in the destination it will be truncated.
+		 * @param dest_start The upper and left bounds of the data to fill.
+		 * @param source_start The upper and left bounds of the source to fill with.
+		 * @param size The size of the area to copy over.
+		 */
+		void set_sub_array( const array2d<T> source, const ivec2& dest_start, const ivec2& source_start, const ivec2& size )
+		{
+			return set_sub_array( source, dest_start.x, dest_start.y, source_start.x, source_start.y, size.x, size.y );
+		}
+
+		/**
+		 * Fills this array with another array.
+		 *
+		 * @param source The array to fill with.  If it does not fit in the area to fill, it will be truncated.
+		 * @param dest_start_x The left bound of the data to fill.
+		 * @param dest_start_y The upper bound of the data to fill.
+		 */
+		void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y )
+		{
+			return set_sub_array( source, dest_start_x, dest_start_y, 0, 0, source.m_size.x, source.m_size.y );
+		}
+
+		/**
+		 * Fills this array with another array.
+		 *
+		 * @param source The array to fill with.  If it does not fit in the area to fill, it will be truncated.
+		 * @param dest_start_x The left bound of the data to fill.
+		 * @param dest_start_y The upper bound of the data to fill.
+		 * @param size_x The width of the area to copy over.
+		 * @param size_y The height of the area to copy over.
+		 */
+		void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y, const sint32 size_x, const sint32 size_y )
+		{
+			return set_sub_array( source, dest_start_x, dest_start_y, 0, 0, size_x, size_y );
+		}
+
+		/**
+		 * Fills this array with a subset of another array.
+		 *
+		 * @param source The array to fill with.  If it does not fit in the area to fill, it will be truncated.
+		 * @param dest_start_x The left bound of the data to fill.
+		 * @param dest_start_y The upper bound of the data to fill.
+		 * @param source_start_x The left bound of the source to fill with.
+		 * @param source_start_y The upper bound of the source to fill with.
+		 * @param size_x The width of the area to copy over.
+		 * @param size_y The height of the area to copy over.
+		 */
+		void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y, const sint32 source_start_x, const sint32 source_start_y, const sint32 size_x, const sint32 size_y )
+		{
+			// Start by checking the parameters.  Make sure nothing is out of bounds.
+			NV_ASSERT( source != nullptr, "set_sub_array: no source defined." );
+			NV_ASSERT( dest_start_x >= 0 && dest_start_x < m_size.x && dest_start_y >= 0 && dest_start_y < m_size.y, "set_sub_array: destination start is out of bounds." );
+			NV_ASSERT( source_start_x >= 0 && source_start_x < source.m_size.x && source_start_y >= 0 && source_start_y < source.m_size.y, "set_sub_array: source start is out of bounds." );
+			NV_ASSERT( size_x >= 1 && size_y >= 1, "set_sub_array: invalid size specified." ); // If size is 0, nothing would be copied in the first place.
+		
+			// Warn when copied data is truncated.
+			// If the end of the copied area is beyond the bounds of the destination array, data will be truncated.
+			if ( dest_start_x + min(size_x, source.m_size.x - source_start_x) > m_size.x || dest_start_y + min(size_y, source.m_size.y - source_start_y) > m_size.y )
+			{
+				//NV_LOG_WARNING( "set_sub_array: Source area does not fit in the destination area.  Data will be truncated." );
+			}
+		
+			// Copy into THIS array from source the following.
+			// Highest row is either the size limit or the end of either array, whichever is smaller.
+			for ( uint32 i = 0; i < min( size_y , min ( m_size.y - dest_start_y, source.m_size.y - source_start_y ) ); i++ )
+			{
+				// Copy the indicated row.
+				// The start position is the beginning of the current row (which is source_start_y + i), offset by source_start_x.
+				// The end position is either the size limit or the end of either array, whichever is smaller.
+				// Destination start is the beginning of the current destination row (which is dest_start_y + i), offset by dest_start_x.
+				std::copy( source.m_data + ( source_start_y + i ) * source.m_size.x + source_start_x,  // Source Start
+						  source.m_data + ( source_start_y + i ) * source.m_size.x + min( source.m_size.x, min( source_start_x + size_x, source_start_x + m_size.x - dest_start_x ) ), // Source End
+						  m_data + (dest_start_y + i) * m_size.x + dest_start_x ); // Destination Start
+			}
+		}
+
+		/**
+		 * Destructor.
+		 */
+		~array2d()
+		{
+			if ( m_data != nullptr )
+			{
+				delete[] m_data;
+			}
+		}
+	protected:
+		pointer m_data; ///< Pointer to the data.
+		ivec2   m_size; ///< Allocated size of the data.
+	};
+
+}
+
+#endif // NV_CORE_ARRAY2D_HH
Index: /trunk/nv/stl/cstring_store.hh
===================================================================
--- /trunk/nv/stl/cstring_store.hh	(revision 368)
+++ /trunk/nv/stl/cstring_store.hh	(revision 368)
@@ -0,0 +1,146 @@
+// Copyright (C) 2014 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 cstring_store.hh
+* @author Kornel Kisielewicz
+* @brief cstring_store
+*/
+
+#ifndef NV_CORE_CSTRING_STORE_HH
+#define NV_CORE_CSTRING_STORE_HH
+
+#include <nv/core/common.hh>
+#include <nv/core/array.hh>
+#include <unordered_map>
+#include <cstring>
+#include <cstdlib>
+
+namespace nv
+{
+
+	namespace detail
+	{
+
+		inline char *cstring_duplicate( const char *s )
+		{
+			size_t length = std::strlen( s ) + 1;
+			void *result = std::malloc( length );
+			if ( result == nullptr ) return nullptr;
+			return (char *)std::memcpy( result, s, length );
+		}
+
+		struct cstring_compare
+		{
+			bool operator()( const char* lhs, const char* rhs ) const
+			{
+				return strcmp( lhs, rhs ) == 0;
+			}
+		};
+
+
+		struct cstring_hash
+		{
+			int operator()( const char* str ) const
+			{
+				int seed = 131;
+				int hash = 0;
+				while ( *str )
+				{
+					hash = ( hash * seed ) + ( *str );
+					str++;
+				}
+				return hash & ( 0x7FFFFFFF );
+			}
+		};
+	}
+
+	template < typename T >
+	using cstring_unordered_map = std::unordered_map < const char*, T, detail::cstring_hash, detail::cstring_compare > ;
+
+	struct cstring_deleter : public noncopyable
+	{
+	public:
+		cstring_deleter() {}
+
+		char* duplicate( const char* s )
+		{
+			char* result = detail::cstring_duplicate( s );
+			insert( result );
+			return result;
+		}
+
+		void insert( char * s )
+		{
+			m_array.push_back( s );
+		}
+
+		~cstring_deleter()
+		{
+			for ( auto s : m_array ) free( s );
+		}
+	private:
+		std::vector< char* > m_array;
+	};
+
+	class cstring_store : public noncopyable
+	{
+	public:
+		cstring_store() {}
+
+		bool exists( const char* cstr )
+		{
+			return m_map.find( cstr ) != std::end( m_map );
+		}
+		
+		const char* get( uint32 index )
+		{
+			return index < m_array.size() ? m_array[index] : nullptr;
+		}
+
+		uint32 resolve( const char* cstr )
+		{
+			auto it = m_map.find( cstr );
+			if ( it != std::end( m_map ) )
+			{
+				return it->second;
+			}
+			return uint32(-1);
+		}
+
+		uint32 push( const char* cstr )
+		{
+			char* duplicate = detail::cstring_duplicate( cstr );
+			m_array.push_back( duplicate );
+			uint32 index = (uint32)m_array.size() - 1;
+			m_map[duplicate] = index;
+			return index;
+		}
+
+		uint32 insert( const char* cstr )
+		{
+			auto it = m_map.find( cstr );
+			if ( it == std::end( m_map ) )
+			{
+				return push( cstr );
+			}
+			return it->second;
+		}
+
+
+
+		~cstring_store()
+		{
+			for ( auto s : m_array ) free( s );
+		}
+	private:
+		std::vector< char* >            m_array;
+		cstring_unordered_map< uint32 > m_map;
+	};
+
+}
+
+#endif // NV_CORE_STRING_STORE_HH
Index: /trunk/nv/stl/exception.hh
===================================================================
--- /trunk/nv/stl/exception.hh	(revision 368)
+++ /trunk/nv/stl/exception.hh	(revision 368)
@@ -0,0 +1,46 @@
+// Copyright (C) 2012-2014 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 exception.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief nv exception bases
+ */
+
+#ifndef NV_CORE_EXCEPTION_HH
+#define NV_CORE_EXCEPTION_HH
+
+#include <nv/core/common.hh>
+#include <string>
+#include <exception>
+#include <stdexcept>
+
+namespace nv
+{
+	/**
+	 * NV logic_error.
+	 *
+	 * Inherits std::logic_error.
+	 */
+	class logic_error : public std::logic_error
+	{
+	public:
+		explicit logic_error( const std::string& msg ) : std::logic_error( msg ) {}
+	};
+
+	/**
+	 * NV runtime_error.
+	 *
+	 * Inherits std::runtime_error.
+	 */
+	class runtime_error : public std::runtime_error
+	{
+	public:
+		explicit runtime_error( const std::string& msg ) : std::runtime_error( msg ) {}
+	};
+}
+
+#endif // NV_CORE_EXCEPTION_HH
Index: /trunk/nv/stl/flags.hh
===================================================================
--- /trunk/nv/stl/flags.hh	(revision 368)
+++ /trunk/nv/stl/flags.hh	(revision 368)
@@ -0,0 +1,221 @@
+// Copyright (C) 2012-2014 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 flags.hh
+ * @author Kornel Kisielewicz
+ * @brief flags
+ */
+
+#ifndef NV_CORE_FLAGS_HH
+#define NV_CORE_FLAGS_HH
+
+#include <nv/core/common.hh>
+#include <nv/stl/type_traits.hh>
+#include <nv/stl/array.hh>
+
+namespace nv
+{
+	template < uint32 SIZE, typename T = uint32 >
+	class flags
+	{
+	public:
+		class reference
+		{
+			friend class flags<SIZE,T>;
+		public:
+			typedef bool value_type;
+			typedef T    index_type;
+
+			reference& operator=( value_type a_value )
+			{
+				m_flags->set( m_index, a_value );
+				return (*this);
+			}
+			reference& operator=( const reference& a_value )
+			{
+				m_flags->set( m_index, bool( a_value ) );
+				return (*this);
+			}
+			operator bool() const 
+			{
+				return m_flags->test( m_index );
+			}
+
+		private:
+			reference() : m_flags( nullptr ), m_index( index_type(0) ) {}
+
+			reference( flags<SIZE,T>* a_flags, index_type a_index )
+				: m_flags( a_flags ), m_index( a_index )
+			{	
+			}
+
+		private:
+			flags<SIZE,T>* m_flags;
+			index_type     m_index;
+		};
+
+		class enumerator
+		{
+			friend class flags<SIZE,T>;
+		public:
+			typedef T              index_type;
+			typedef T              value_type;
+			typedef T*             iterator;
+			typedef const T*       const_iterator;
+			typedef T&             reference;
+			typedef const T&       const_reference;
+			typedef std::size_t    size_type;
+			typedef std::ptrdiff_t difference_type;
+
+			T operator* () const { return m_index; }
+			T const* operator-> () const { return &m_index; }
+			bool operator== ( const enumerator& rhs ) const
+			{
+				return ( m_index == rhs.m_index ) && ( m_flags == rhs.m_flags );
+			}
+			bool operator!= ( const enumerator& rhs ) const
+			{
+				return !( *this == rhs );
+			}
+			
+			enumerator& operator++ () 
+			{
+				next();
+				return *this; 
+			}
+			enumerator operator++ (int) 
+			{
+				auto result = *this; 
+				++*this; 
+				return result;
+			}
+		protected:
+			enumerator() : m_flags( nullptr ), m_index( index_type(0) ) {}
+
+			enumerator( const flags<SIZE,T>* a_flags, index_type a_index )
+				: m_flags( a_flags ), m_index( a_index )
+			{	
+				if ( a_flags && !a_flags->test( a_index ) ) next();
+			}
+
+			void next()
+			{
+				if ( m_flags )
+				do 
+				{
+					if ( raw_index_type(m_index) >= SIZE ) { m_flags = nullptr; m_index = index_type(0); return; }
+					m_index = index_type((raw_index_type)m_index + 1);
+				} while ( !m_flags->test( m_index ) );
+			}
+
+			const flags<SIZE,T>* m_flags;
+			index_type           m_index;
+		};
+
+		typedef uint8     data_type;
+		typedef T         index_type;
+		typedef uint32 size_type;
+		typedef typename base_underlying_type<T>::type raw_index_type;
+
+		static const size_type data_type_size = sizeof( data_type ) * 8;
+		static const size_type data_count     = SIZE;
+		static const size_type data_size      = (SIZE+data_type_size-1) / data_type_size;
+
+		enumerator begin()  const { return enumerator( this, index_type(0) ); }
+		enumerator cbegin() const { return enumerator( this, index_type(0) ); }
+
+		enumerator end()  const { return enumerator(); }
+		enumerator cend() const { return enumerator(); }
+
+		flags()
+		{
+			reset();
+		}
+
+		explicit flags( const data_type* a_data )
+		{
+			assign( a_data );
+		}
+
+		void assign( const data_type* a_data )
+		{
+			std::copy( a_data, a_data + data_size, m_data );
+		}
+
+		void reset()
+		{
+			std::fill( m_data, m_data + data_size, 0 );
+		}
+
+		void include( index_type i )
+		{
+			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
+			raw_index_type pos = static_cast< raw_index_type >( i ) % data_type_size;
+			m_data[ idx ] |= 1 << static_cast< data_type >( pos );
+		}
+
+		void exclude( index_type i )
+		{
+			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
+			raw_index_type pos = static_cast< raw_index_type >( i ) % data_type_size;
+			m_data[ idx ] &= ~(1 << static_cast< data_type >( pos ) );
+		}
+
+		void set( index_type i, bool value )
+		{
+			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
+			raw_index_type pos = static_cast< raw_index_type >( i ) % data_type_size;
+			if ( value )
+				m_data[ idx ] |= 1 << static_cast< data_type >( pos );
+			else
+				m_data[ idx ] &= ~(1 << static_cast< data_type >( pos ) );
+		}
+
+		bool test( index_type i ) const
+		{
+			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
+			raw_index_type pos = static_cast< raw_index_type >( i ) % data_type_size;
+			return ( m_data[ idx ] & ( 1 << static_cast< data_type >( pos ) ) ) != 0;
+		}
+
+		const data_type* data() const
+		{
+			return m_data;
+		}
+
+		data_type* data()
+		{
+			return m_data;
+		}
+
+		size_type size() const
+		{
+			return data_count;
+		}
+
+		size_type capacity() const
+		{
+			return data_size;
+		}
+
+		bool operator[]( index_type idx ) const
+		{
+			return test( idx );
+		}
+
+		reference operator[]( index_type idx )
+		{
+			return reference( this, idx );
+		}
+
+	private:
+		data_type m_data[ data_size ];
+	};
+
+} // namespace nv
+
+#endif // NV_CORE_FLAGS_HH
Index: /trunk/nv/stl/handle.hh
===================================================================
--- /trunk/nv/stl/handle.hh	(revision 368)
+++ /trunk/nv/stl/handle.hh	(revision 368)
@@ -0,0 +1,335 @@
+// Copyright (C) 2014 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 handle.hh
+ * @author Kornel Kisielewicz
+ */
+
+#ifndef NV_CORE_HANDLE_HH
+#define NV_CORE_HANDLE_HH
+
+#include <nv/core/common.hh>
+#include <nv/stl/array.hh>
+
+namespace nv
+{
+
+	template < 
+		typename T = uint32, 
+		unsigned IBITS = 16,
+		unsigned CBITS = 16,
+		typename TAG = void 
+	>
+	class handle
+	{
+	public:
+		typedef T value_type;
+		typedef TAG tag_type;
+		static const int INDEX_BITS   = IBITS;
+		static const int COUNTER_BITS = IBITS;
+		static const T MAX_INDEX   = (1 << IBITS) - 1;
+		static const T MAX_COUNTER = (1 << CBITS) - 1;
+
+		handle() : m_index(0), m_counter(0) {}
+
+		inline bool operator==(const handle& rhs) const {return m_index == rhs.m_index && m_counter == rhs.m_counter; }
+		inline bool operator!=(const handle& rhs) const {return !(*this == rhs);}
+
+		bool is_nil() const { return m_index == 0 && m_counter == 0; }
+		bool is_valid() const { return !is_nil(); }
+		T index() const { return m_index; }
+		size_t hash() const { return std::hash<T>()( T( m_counter << IBITS | m_index ) ); }
+	protected:
+		T m_index   : IBITS;
+		T m_counter : CBITS;
+
+		handle( T a_index, T a_counter ) : m_index( a_index ), m_counter( a_counter ) {}
+		template < typename H >
+		friend class handle_operator;
+	};
+
+	template < typename HANDLE >
+	class handle_operator
+	{
+	public:
+		typedef typename HANDLE::value_type value_type;
+
+		static HANDLE create( value_type index, value_type counter )
+		{
+			return HANDLE( index, counter );
+		}
+		static value_type get_counter( const HANDLE& h ) { return h.m_counter; }
+		static value_type get_index( const HANDLE& h ) { return h.m_index; }
+	};
+
+	template < typename HANDLE, typename INDEX = sint32 >
+	class handle_manager
+	{
+		typedef INDEX index_type;
+		static const index_type NONE = index_type(-1);
+		static const index_type USED = index_type(-2);
+	public:
+
+		typedef HANDLE handle;
+		typedef typename HANDLE::value_type value_type;
+
+		handle_manager() : m_first_free( NONE ), m_last_free( NONE ) {}
+
+		handle create_handle()
+		{
+			typedef handle_operator<HANDLE> hop;
+			value_type i = get_free_entry();
+			m_entries[i].counter++;
+			NV_ASSERT( m_entries[i].counter != 0, "Out of handles!" );
+			m_entries[i].next_free = USED;
+			return hop::create( i, m_entries[i].counter );
+		}
+
+		void free_handle( handle h )
+		{
+			value_type index = h.index();
+			typedef handle_operator<HANDLE> hop;
+			NV_ASSERT( m_entries[index].next_free == USED, "Unused handle freed!" );
+			NV_ASSERT( m_entries[index].counter == hop::get_counter( h ), "Handle corruption!" );
+			m_entries[index].next_free = NONE;
+			if ( m_last_free == NONE )
+			{
+				m_first_free = m_last_free = (index_type)index;
+				return;
+			}
+			m_entries[(value_type)m_last_free].next_free = (index_type)index;
+			m_last_free = (index_type)index;
+		}
+
+		bool is_valid( handle h ) const
+		{
+			typedef handle_operator<HANDLE> hop;
+			if ( h.is_nil() ) return false;
+			if ( h.index() >= m_entries.size() ) return false;
+			const index_entry& entry = m_entries[h.index()];
+			return entry.next_free == USED && entry.counter == hop::get_counter( h );
+		}
+
+	private:
+		struct index_entry
+		{
+			value_type counter;
+			index_type next_free;
+
+			index_entry() : counter( 0 ), next_free( NONE ) {}
+		};
+
+		value_type get_free_entry()
+		{
+			if ( m_first_free != NONE )
+			{
+				value_type result = (value_type)m_first_free;
+				m_first_free = m_entries[result].next_free;
+				m_entries[result].next_free = USED;
+				if ( m_first_free == NONE ) m_last_free = NONE;
+				return result;
+			}
+			m_entries.emplace_back();
+			return value_type( m_entries.size() - 1 );
+		}
+
+		index_type m_first_free;
+		index_type m_last_free;
+		std::vector< index_entry > m_entries;
+	};
+
+	template < typename T, typename HANDLE = handle<>, typename TINDEX = sint32 >
+	class packed_indexed_array
+	{
+	public:
+		typedef HANDLE                   handle;
+		typedef TINDEX                   index_type;
+		typedef std::vector< T >         storage;
+		typedef T                        value_type;
+		typedef typename storage::iterator        iterator;
+		typedef typename storage::const_iterator  const_iterator;
+		typedef typename storage::reference       reference;
+		typedef typename storage::const_reference const_reference;
+
+		packed_indexed_array() {}
+		packed_indexed_array( uint32 reserve )
+		{
+			m_data.reserve( reserve );
+			m_indexes.reserve( reserve );
+		}
+
+		T* insert( handle h )
+		{
+			resize_indexes_to( (index_type) h.index() );
+			m_indexes[ h.index() ] = (index_type) m_data.size();
+			m_handles.push_back( h );
+			m_data.emplace_back();
+			return &(m_data.back());
+		}
+
+		bool exists( handle h )
+		{
+			if ( h.is_nil() || h.index() >= m_indexes.size() ) return false;
+			return m_indexes[ h.index() ] >= 0;		
+		}
+
+		T* get( handle h )
+		{
+			if ( h.is_nil() || h.index() >= m_indexes.size() ) return nullptr;
+			index_type i = m_indexes[ h.index() ];
+			return i >= 0 ? &(m_data[ (unsigned)i ]) : nullptr;
+		}
+
+		const T* get( handle h ) const
+		{
+			if ( h.is_nil() || h.index() >= m_indexes.size() ) return nullptr;
+			index_type i = m_indexes[h.index()];
+			return i >= 0 ? &( m_data[(unsigned)i] ) : nullptr;
+		}
+
+		void remove( handle h )
+		{
+			if ( h.is_nil() || h.index() >= m_indexes.size() || m_indexes[h.index()] == -1 ) 
+				return;
+			handle swap_handle    = m_handles.back();
+			sint32 dead_eindex    = m_indexes[ h.index() ];
+			if ( dead_eindex != (sint32)m_data.size()-1 )
+			{
+				m_data[ (unsigned)dead_eindex ]    = m_data.back();
+				m_handles[ (unsigned)dead_eindex ] = swap_handle;
+				m_indexes[ swap_handle.index() ]   = dead_eindex;
+			}
+			m_data.pop_back();
+			m_handles.pop_back();
+			m_indexes[ h.index() ] = -1;
+		}
+
+		void clear()
+		{
+			m_data.clear();
+			m_handles.clear();
+			m_indexes.clear();
+		}
+
+		handle get_handle( index_type i ) const { return m_handles[(unsigned)i]; }
+
+		const value_type& operator[] ( index_type i ) const { return m_data[i]; }
+		value_type& operator[] ( index_type i ) { return m_data[i]; }
+		size_t size() const { return m_data.size(); }
+
+		iterator        begin()        { return m_data.begin(); }
+		const_iterator  begin()  const { return m_data.cbegin(); }
+		const_iterator  cbegin() const { return m_data.cbegin(); }
+
+		iterator        end()        { return m_data.end(); }
+		const_iterator  end()  const { return m_data.cend(); }
+		const_iterator  cend() const { return m_data.cend(); }
+
+	private:
+		void resize_indexes_to( index_type i )
+		{
+			index_type size = (index_type)m_indexes.size();
+			if ( i >= size )
+			{
+				if ( size == 0 ) size = 1;
+				while ( i >= size ) size = size * 2;
+				m_indexes.resize( (size_t)size, -1 );
+			}
+		}
+
+		std::vector< T >          m_data;
+		std::vector< handle >     m_handles;
+		std::vector< index_type > m_indexes;
+	};
+
+
+	template < typename T, typename HANDLE = handle<>, typename TINDEX = sint32 >
+	class handle_store
+	{
+	public:
+		typedef HANDLE                   handle;
+		typedef TINDEX                   index_type;
+		typedef std::vector< T >         storage;
+		typedef T                        value_type;
+		typedef typename storage::iterator        iterator;
+		typedef typename storage::const_iterator  const_iterator;
+		typedef typename storage::reference       reference;
+		typedef typename storage::const_reference const_reference;
+
+		handle_store() {}
+
+		explicit handle_store( uint32 reserve )
+		{
+			m_data.reserve( reserve );
+		}
+
+		handle create()
+		{
+			handle h = m_indexes.create_handle();
+			m_data.insert( h );
+			return h;
+		}
+
+		bool is_valid( handle h )
+		{
+			return m_indexes.is_valid( h );
+		}
+
+		const value_type* get( handle h ) const
+		{
+			return m_data.get( h );
+		}
+
+		value_type* get( handle h )
+		{
+			return m_data.get( h );
+		}
+
+		void destroy( handle e )
+		{
+			m_data.remove( e );
+			m_indexes.free_handle( e );
+		}
+
+		handle get_handle( index_type i ) const { return m_data.get_handle(i); }
+		const value_type& operator[] ( index_type i ) const { return m_data[(unsigned)i]; }
+		value_type& operator[] ( index_type i ) { return m_data[(unsigned)i]; }
+		size_t size() const { return m_data.size(); }
+
+		iterator        begin() { return m_data.begin(); }
+		const_iterator  begin()  const { return m_data.cbegin(); }
+		const_iterator  cbegin() const { return m_data.cbegin(); }
+
+		iterator        end() { return m_data.end(); }
+		const_iterator  end()  const { return m_data.cend(); }
+		const_iterator  cend() const { return m_data.cend(); }
+
+	private:
+		packed_indexed_array< T, handle, TINDEX > m_data;
+		handle_manager< handle >                  m_indexes;
+	};
+	
+}
+
+namespace std
+{
+	template < 
+		typename T, 
+		unsigned IBITS,
+		unsigned CBITS,
+		typename TAG
+	>
+	struct hash<nv::handle<T,IBITS,CBITS,TAG>>
+	{
+		size_t operator()(const nv::handle<T,IBITS,CBITS,TAG>& h) const
+		{
+			return h.hash();
+		}
+	};
+}
+
+#endif // NV_CORE_HANDLE_HH
Index: /trunk/nv/stl/math.hh
===================================================================
--- /trunk/nv/stl/math.hh	(revision 368)
+++ /trunk/nv/stl/math.hh	(revision 368)
@@ -0,0 +1,273 @@
+// Copyright (C) 2012-2014 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#ifndef NV_CORE_MATH_HH
+#define NV_CORE_MATH_HH
+
+#include <nv/core/common.hh>
+
+#if NV_COMPILER == NV_GNUC
+#pragma GCC system_header
+#elif NV_COMPILER == NV_CLANG
+#pragma clang system_header
+#endif
+
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/matrix_access.hpp>
+#include <glm/gtc/type_ptr.hpp>
+#include <glm/gtc/quaternion.hpp>
+#include <glm/gtx/rotate_vector.hpp>
+#include <glm/gtx/vector_angle.hpp>
+
+namespace nv
+{
+
+	typedef glm::detail::tvec2<sint8> i8vec2;
+	typedef glm::detail::tvec3<sint8> i8vec3;
+	typedef glm::detail::tvec4<sint8> i8vec4;
+
+	typedef glm::detail::tvec2<sint16> i16vec2;
+	typedef glm::detail::tvec3<sint16> i16vec3;
+	typedef glm::detail::tvec4<sint16> i16vec4;
+
+	typedef glm::detail::tvec2<uint8> u8vec2;
+	typedef glm::detail::tvec3<uint8> u8vec3;
+	typedef glm::detail::tvec4<uint8> u8vec4;
+
+	typedef glm::vec2 vec2;
+	typedef glm::vec3 vec3;
+	typedef glm::vec4 vec4;
+
+	typedef glm::ivec2 ivec2;
+	typedef glm::ivec3 ivec3;
+	typedef glm::ivec4 ivec4;
+
+	typedef glm::mat2 mat2;
+	typedef glm::mat3 mat3;
+	typedef glm::mat4 mat4;
+
+	typedef glm::quat quat;
+
+	template <typename T> 
+	struct datatype_traits 
+	{
+		typedef T type;
+		typedef T base_type;
+		static const size_t size = 1;
+	};
+
+	template <typename T> 
+	struct datatype_traits< glm::detail::tvec2<T> > 
+	{
+		typedef glm::detail::tvec2<T> type;
+		typedef typename type::value_type base_type;
+		static const size_t size = 2;
+	};
+
+	template <typename T> 
+	struct datatype_traits< glm::detail::tvec3<T> > 
+	{
+		typedef glm::detail::tvec3<T> type;
+		typedef typename type::value_type base_type;
+		static const size_t size = 3;
+	};
+
+	template <typename T> 
+	struct datatype_traits< glm::detail::tvec4<T> > 
+	{
+		typedef glm::detail::tvec4<T> type;
+		typedef typename type::value_type base_type;
+		static const size_t size = 4;
+	};
+
+	using glm::max;
+	using glm::min;
+
+	enum datatype
+	{
+		NONE,
+		INT,
+		BYTE,
+		SHORT,
+		UINT,
+		UBYTE,
+		USHORT,
+		FLOAT,
+		FLOAT_VECTOR_2,
+		FLOAT_VECTOR_3,
+		FLOAT_VECTOR_4,
+		FLOAT_MATRIX_2,
+		FLOAT_MATRIX_3,
+		FLOAT_MATRIX_4,
+		INT_VECTOR_2,
+		INT_VECTOR_3,
+		INT_VECTOR_4,
+		// unsupported gl conversion, remove?
+		BYTE_VECTOR_2, 
+		BYTE_VECTOR_3,
+		BYTE_VECTOR_4,
+		UBYTE_VECTOR_2,
+		UBYTE_VECTOR_3,
+		UBYTE_VECTOR_4,
+		QUAT,
+		TRANSFORM,
+		DATATYPE_COUNT,
+	};
+
+	struct datatype_info
+	{
+		size_t   size;
+		datatype base;
+		size_t   elements;
+	};
+
+	inline const datatype_info& get_datatype_info( datatype dt )
+	{
+		static datatype_info info[ DATATYPE_COUNT ] = {
+			{ 0, NONE, 0 },   // NONE  
+			{ 4, INT, 1 },    // INT,
+			{ 1, BYTE, 1 },   // BYTE,
+			{ 2, SHORT, 1 },  // SHORT,
+			{ 4, UINT, 1 },   // UINT,
+			{ 1, UBYTE, 1 },  // UBYTE,
+			{ 2, USHORT, 1 }, // USHORT,
+			{ 4, FLOAT, 1 },  // FLOAT
+			{ 4 * 2,  FLOAT, 2 },  // FLOAT_VECTOR_2,
+			{ 4 * 3,  FLOAT, 3 },  // FLOAT_VECTOR_3,
+			{ 4 * 4,  FLOAT, 4 },  // FLOAT_VECTOR_4,
+			{ 4 * 4,  FLOAT, 4 },  // FLOAT_MATRIX_2,
+			{ 4 * 9,  FLOAT, 9 },  // FLOAT_MATRIX_3,
+			{ 4 * 16, FLOAT, 16 }, // FLOAT_MATRIX_4,
+			{ 4 * 2,  INT, 2 },  // INT_VECTOR_2,
+			{ 4 * 3,  INT, 3 },  // INT_VECTOR_3,
+			{ 4 * 4,  INT, 4 },  // INT_VECTOR_4,
+			// unsupported gl conversion, remove?
+			{ 1 * 2,  BYTE, 2 },  // BYTE_VECTOR_2,
+			{ 1 * 3,  BYTE, 3 },  // BYTE_VECTOR_3,
+			{ 1 * 4,  BYTE, 4 },  // BYTE_VECTOR_4,
+			{ 1 * 2, UBYTE, 2 },  // UBYTE_VECTOR_2,
+			{ 1 * 3, UBYTE, 3 },  // UBYTE_VECTOR_3,
+			{ 1 * 4, UBYTE, 4 },  // UBYTE_VECTOR_4,
+			{ 4 * 4, FLOAT, 4 },      // QUAT,
+			{ 7 * 4,  FLOAT, 7 },      // TRANSFORM,
+		};
+		return info[dt];
+	}
+
+	template < datatype EnumType > struct enum_to_type {};
+
+	template <> struct enum_to_type< NONE >  { typedef void type; };
+	template <> struct enum_to_type< INT >   { typedef int type; };
+	template <> struct enum_to_type< UINT >  { typedef unsigned int type; };
+	template <> struct enum_to_type< SHORT > { typedef short type; };
+	template <> struct enum_to_type< USHORT >{ typedef unsigned short type; };
+	template <> struct enum_to_type< BYTE >  { typedef char type; };
+	template <> struct enum_to_type< UBYTE > { typedef unsigned char type; };
+	template <> struct enum_to_type< FLOAT > { typedef f32 type; };
+
+	template <> struct enum_to_type< FLOAT_VECTOR_2 > { typedef vec2 type; };
+	template <> struct enum_to_type< FLOAT_VECTOR_3 > { typedef vec3 type; };
+	template <> struct enum_to_type< FLOAT_VECTOR_4 > { typedef vec4 type; };
+
+	template <> struct enum_to_type< INT_VECTOR_2 > { typedef ivec2 type; };
+	template <> struct enum_to_type< INT_VECTOR_3 > { typedef ivec3 type; };
+	template <> struct enum_to_type< INT_VECTOR_4 > { typedef ivec4 type; };
+
+	template <> struct enum_to_type< BYTE_VECTOR_2 > { typedef i8vec2 type; };
+	template <> struct enum_to_type< BYTE_VECTOR_3 > { typedef i8vec3 type; };
+	template <> struct enum_to_type< BYTE_VECTOR_4 > { typedef i8vec4 type; };
+
+	template <> struct enum_to_type < UBYTE_VECTOR_2 > { typedef u8vec2 type; };
+	template <> struct enum_to_type < UBYTE_VECTOR_3 > { typedef u8vec3 type; };
+	template <> struct enum_to_type < UBYTE_VECTOR_4 > { typedef u8vec4 type; };
+
+	template <> struct enum_to_type< FLOAT_MATRIX_2 > { typedef mat2 type; };
+	template <> struct enum_to_type< FLOAT_MATRIX_3 > { typedef mat3 type; };
+	template <> struct enum_to_type< FLOAT_MATRIX_4 > { typedef mat4 type; };
+
+	template <> struct enum_to_type< QUAT > { typedef quat type; };
+
+	template < typename TYPE > struct type_to_enum {};
+
+	template <> struct type_to_enum< long >          { static const datatype type = INT; };
+	template <> struct type_to_enum< unsigned long > { static const datatype type = UINT; };
+	template <> struct type_to_enum< int >           { static const datatype type = INT; };
+	template <> struct type_to_enum< unsigned int >  { static const datatype type = UINT; };
+	template <> struct type_to_enum< short >         { static const datatype type = SHORT; };
+	template <> struct type_to_enum< unsigned short >{ static const datatype type = USHORT; };
+	template <> struct type_to_enum< char >          { static const datatype type = BYTE; };
+	template <> struct type_to_enum< signed char >   { static const datatype type = BYTE; };
+	template <> struct type_to_enum< unsigned char > { static const datatype type = UBYTE; };
+	template <> struct type_to_enum< f32 > { static const datatype type = FLOAT; };
+
+	template <> struct type_to_enum< vec2 > { static const datatype type = FLOAT_VECTOR_2; };
+	template <> struct type_to_enum< vec3 > { static const datatype type = FLOAT_VECTOR_3; };
+	template <> struct type_to_enum< vec4 > { static const datatype type = FLOAT_VECTOR_4; };
+
+	template <> struct type_to_enum< ivec2 > { static const datatype type = INT_VECTOR_2; };
+	template <> struct type_to_enum< ivec3 > { static const datatype type = INT_VECTOR_3; };
+	template <> struct type_to_enum< ivec4 > { static const datatype type = INT_VECTOR_4; };
+
+	template <> struct type_to_enum< i8vec2 > { static const datatype type = BYTE_VECTOR_2; };
+	template <> struct type_to_enum< i8vec3 > { static const datatype type = BYTE_VECTOR_3; };
+	template <> struct type_to_enum< i8vec4 > { static const datatype type = BYTE_VECTOR_4; };
+
+	template <> struct type_to_enum < u8vec2 > { static const datatype type = UBYTE_VECTOR_2; };
+	template <> struct type_to_enum < u8vec3 > { static const datatype type = UBYTE_VECTOR_3; };
+	template <> struct type_to_enum < u8vec4 > { static const datatype type = UBYTE_VECTOR_4; };
+
+
+	template <> struct type_to_enum< mat2 > { static const datatype type = FLOAT_MATRIX_2; };
+	template <> struct type_to_enum< mat3 > { static const datatype type = FLOAT_MATRIX_3; };
+	template <> struct type_to_enum< mat4 > { static const datatype type = FLOAT_MATRIX_4; };
+	template <> struct type_to_enum< quat > { static const datatype type = QUAT; };
+
+	template < typename T >
+	struct sizeof_type 
+	{
+		static const int result = sizeof( T );
+	};
+
+	template <>
+	struct sizeof_type< void >
+	{
+		static const int result = 0;
+	};
+
+	template < datatype T >
+	struct sizeof_enum_type 
+	{
+		static const int result = sizeof_type< typename enum_to_type<T>::type >::result;
+	};
+
+	template < typename T >
+	T interpolate( const T& lhs, const T& rhs, float f )
+	{
+		return glm::mix( lhs, rhs, f );
+	}
+
+	template <>
+	inline quat interpolate( const quat& lhs, const quat& rhs, float f )
+	{
+		return glm::slerp( lhs, rhs, f );
+	}
+
+	template <typename T>
+	glm::detail::tvec3<T> normalize_safe( 
+		const glm::detail::tvec3<T>& x, 
+		const glm::detail::tvec3<T>& def = vec3()
+	)
+	{
+		typename glm::detail::tvec3<T>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z;
+		return ( sqr > 0 ? x * glm::inversesqrt(sqr) : def );
+	}
+
+
+
+} // namespace nv
+
+#endif // NV_CORE_MATH_HH
Index: /trunk/nv/stl/memory.hh
===================================================================
--- /trunk/nv/stl/memory.hh	(revision 368)
+++ /trunk/nv/stl/memory.hh	(revision 368)
@@ -0,0 +1,233 @@
+// 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 memory.hh
+* @author Kornel Kisielewicz
+* @brief memory utilities
+*/
+
+// TODO: implement const and mutable buffer using the union trick
+
+#ifndef NV_CORE_MEMORY_HH
+#define NV_CORE_MEMORY_HH
+
+#include <nv/core/common.hh>
+#include <nv/stl/type_traits.hh>
+
+namespace nv
+{
+
+	namespace detail
+	{
+		template < typename T > 
+		class empty_base_class {};
+
+		template < typename PARENT, typename T, bool CONST, typename BASE = empty_base_class<PARENT> >
+		class pointer_iterators {};
+
+		template < typename PARENT, typename T, typename BASE >
+		class pointer_iterators< PARENT, T, true, BASE > : public BASE
+		{
+		public:
+			typedef const T* const_iterator;
+			typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+			inline const_iterator begin() const { return const_iterator( static_cast<const PARENT&>( *this ).data() ); }
+			inline const_iterator end() const { return const_iterator( static_cast<const PARENT&>( *this ).data() + static_cast<const PARENT&>( *this ).size() ); }
+			inline const_iterator cbegin() const { return const_iterator( static_cast<const PARENT&>( *this ).data() ); }
+			inline const_iterator cend() const { return const_iterator( static_cast<const PARENT&>( *this ).data() + static_cast<const PARENT&>( *this ).size() ); }
+			inline const_reverse_iterator rbegin() const { return const_reverse_iterator( end() ); }
+			inline const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); }
+			inline const_reverse_iterator rend() const { return const_reverse_iterator( begin() ); }
+			inline const_reverse_iterator crend() const { return const_reverse_iterator( begin() ); }
+			inline const_iterator iat( size_t i ) const { NV_ASSERT( i <= static_cast<const PARENT&>( *this ).size(), "Index out of range" ); return begin() + i; }
+		};
+
+		template < typename PARENT, typename T, typename BASE >
+		class pointer_iterators< PARENT, T, false, BASE > : public BASE
+		{
+		public:
+			typedef T*       iterator;
+			typedef const T* const_iterator;
+			typedef std::reverse_iterator<iterator>       reverse_iterator;
+			typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+			inline const_iterator begin() const { return const_iterator( static_cast<const PARENT&>( *this ).data() ); }
+			inline const_iterator end() const { return const_iterator( static_cast<const PARENT&>( *this ).data() + static_cast<const PARENT&>( *this ).size() ); }
+			inline iterator begin() { return iterator( static_cast<PARENT&>( *this ).data() ); }
+			inline iterator end() { return iterator( static_cast<PARENT&>( *this ).data() + static_cast<const PARENT&>( *this ).size() ); }
+			inline const_iterator cbegin() const { return const_iterator( static_cast<const PARENT&>( *this ).data() ); }
+			inline const_iterator cend() const { return const_iterator( static_cast<const PARENT&>( *this ).data() + static_cast<const PARENT&>( *this ).size() ); }
+			inline reverse_iterator rbegin() { return reverse_iterator( end() ); }
+			inline const_reverse_iterator rbegin() const { return const_reverse_iterator( end() ); }
+			inline const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); }
+			inline reverse_iterator rend() { return reverse_iterator( begin() ); }
+			inline const_reverse_iterator rend() const { return const_reverse_iterator( begin() ); }
+			inline const_reverse_iterator crend() const { return const_reverse_iterator( begin() ); }
+			inline const_iterator iat( size_t i ) const { NV_ASSERT( i <= static_cast<const PARENT&>( *this ).size(), "Index out of range" ); return begin() + i; }
+			inline iterator       iat( size_t i ) { NV_ASSERT( i <= static_cast<const PARENT&>( *this ).size(), "Index out of range" ); return begin() + i; }
+		};
+
+		template < typename T, bool CONST, size_t SIZE >
+		class data_base
+		{
+		};
+
+		template < typename T, size_t SIZE >
+		class data_base < T, true, SIZE > 
+			: public pointer_iterators< data_base < T, true, SIZE >, T, true > 
+		{
+		public:
+			typedef T                    value_type;
+			typedef const value_type*    const_pointer;
+			typedef size_t	             size_type;
+			typedef const_pointer        const_iterator;
+			typedef const value_type&    const_reference;
+
+			inline const_pointer data() const { return m_data; }
+			inline size_type size() const { return SIZE; }
+			inline bool empty() const { return false; }
+			inline size_type   raw_size() const { return SIZE * sizeof( T ); }
+			inline const char* raw_data() const { return (const char*)m_data; }
+
+			inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[0]; }
+			inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[SIZE - 1]; }
+		protected:
+			value_type m_data[SIZE];
+		};
+
+		template < typename T, size_t SIZE >
+		class data_base < T, false, SIZE >
+			: public pointer_iterators < data_base < T, false, SIZE >, T, false >
+		{
+		public:
+			typedef T                    value_type;
+			typedef value_type*          pointer;
+			typedef const value_type*    const_pointer;
+			typedef size_t	             size_type;
+			typedef pointer              iterator;
+			typedef const_pointer        const_iterator;
+			typedef value_type&		     reference;
+			typedef const value_type&    const_reference;
+
+			inline const_pointer data() const { return m_data; }
+			inline pointer data() { return m_data; }
+			inline size_type size() const { return SIZE; }
+			inline bool empty() const { return false; }
+			inline size_type   raw_size() const { return SIZE * sizeof( T ); }
+			inline const char* raw_data() const { return (const char*)m_data; }
+			inline char*       raw_data() { return (char*)m_data; }
+
+			inline reference       front() { NV_ASSERT( !empty(), "front() called on empty data!" );  return m_data[0]; }
+			inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[0]; }
+			inline reference       back() { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[SIZE - 1]; }
+			inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[SIZE - 1]; }
+		protected:
+			value_type m_data[SIZE];
+		};
+
+
+		template < typename T >
+		class data_base < T, true, 0 >
+			: public pointer_iterators < data_base < T, true, 0 >, T, true >
+		{
+		public:
+			typedef T                    value_type;
+			typedef const value_type*    const_pointer;
+			typedef size_t	             size_type;
+			typedef const_pointer        const_iterator;
+			typedef const value_type&    const_reference;
+
+			inline data_base() : m_data( nullptr ), m_size( 0 ) {}
+			inline data_base( const_pointer a_data, size_t a_size ) : m_data( a_data ), m_size( a_size ) {}
+			inline const T* data() const { return m_data; }
+			inline size_t size() const { return m_size; }
+			inline bool empty() const { return m_size != 0; }
+			inline size_type   raw_size() const { return sizeof( T ) * m_size; }
+			inline const char* raw_data() const { return (const char*)m_data; }
+
+			inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[0]; }
+			inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[m_size - 1]; }
+		protected:
+			const_pointer m_data;
+			size_type     m_size;
+		};
+
+		template < typename T >
+		class data_base < T, false, 0 >
+			: public pointer_iterators < data_base < T, false, 0 >, T, false >
+		{
+		public:
+			typedef T                    value_type;
+			typedef value_type*          pointer;
+			typedef const value_type*    const_pointer;
+			typedef size_t	             size_type;
+			typedef pointer              iterator;
+			typedef const_pointer        const_iterator;
+			typedef value_type&		     reference;
+			typedef const value_type&    const_reference;
+
+			inline data_base() : m_data( nullptr ), m_size( 0 ) {}
+			inline data_base( pointer a_data, size_t a_size ) : m_data( a_data ), m_size( a_size ) {}
+			inline const_pointer data() const { return m_data; }
+			inline pointer data() { return m_data; }
+			inline size_t size() const { return m_size; }
+			inline bool empty() const { return m_size != 0; }
+			inline size_type   raw_size() const { return sizeof( T ) * m_size; }
+			inline const char* raw_data() const { return (const char*)m_data; }
+			inline char*       raw_data() { return (char*)m_data; }
+
+			inline reference       front() { NV_ASSERT( !empty(), "front() called on empty data!" );  return m_data[0]; }
+			inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[0]; }
+			inline reference       back() { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[m_size - 1]; }
+			inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[m_size - 1]; }
+		protected:
+			pointer   m_data;
+			size_type m_size;
+		};
+
+	}
+
+	class const_mem_ref : public detail::data_base< char, true, 0 >
+	{
+	public:
+		typedef char                 value_type;
+		typedef value_type*          pointer;
+		typedef const value_type*    const_pointer;
+		typedef value_type&		     reference;
+		typedef const value_type&    const_reference;
+		typedef size_t	             size_type;
+		typedef ptrdiff_t            difference_type;
+		typedef const_pointer        const_iterator;
+	public:
+		inline const_mem_ref() : detail::data_base< char, true, 0 >() {}
+		inline const_mem_ref( const void* p, size_type n ) : detail::data_base< char, true, 0 >( (const char*)p, n ) {}
+		inline const_mem_ref( const const_mem_ref& l ) : detail::data_base< char, true, 0 >( l.data(), l.size() ) {}
+	};
+
+	class mem_ref : public detail::data_base< char, false, 0 >
+	{
+	public:
+		typedef char                 value_type;
+		typedef value_type*          pointer;
+		typedef const value_type*    const_pointer;
+		typedef value_type&		     reference;
+		typedef const value_type&    const_reference;
+		typedef size_t	             size_type;
+		typedef ptrdiff_t            difference_type;
+		typedef pointer              iterator;
+		typedef const_pointer        const_iterator;
+	public:
+		inline mem_ref() : detail::data_base< char, false, 0 >() {}
+		inline mem_ref( void* p, size_type n ) : detail::data_base< char, false, 0 >( (char*)p, n ) {}
+		inline mem_ref( const mem_ref& l ) : detail::data_base< char, false, 0 >( const_cast< char* >( l.data() ), l.size() ) {}
+	};
+
+
+}
+
+#endif // NV_CORE_MEMORY_HH
Index: /trunk/nv/stl/range.hh
===================================================================
--- /trunk/nv/stl/range.hh	(revision 368)
+++ /trunk/nv/stl/range.hh	(revision 368)
@@ -0,0 +1,233 @@
+// Copyright (C) 2014 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 range.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief range iterators
+ */
+
+#ifndef NV_CORE_RANGE_HH
+#define NV_CORE_RANGE_HH
+
+#include <nv/core/common.hh>
+#include <nv/stl/math.hh>
+#include <nv/stl/type_traits.hh>
+#include <iterator>
+
+namespace nv
+{
+
+	namespace detail
+	{
+
+		template < typename T >
+		class forward_iterator_base : public std::iterator< std::input_iterator_tag, T >
+		{
+		public:
+			forward_iterator_base( T value ) : m_value( value ) {}
+			T operator* () const { return m_value; }
+			T const* operator-> () const { return &m_value; }
+			bool operator== ( const forward_iterator_base& rhs ) const
+			{
+				return m_value == rhs.m_value;
+			}
+			bool operator!= ( const forward_iterator_base& rhs ) const
+			{
+				return !( *this == rhs );
+			}
+		protected:
+			T m_value;
+		};
+
+		template < typename T >
+		class range_iterator_base : public forward_iterator_base< T >
+		{
+		public:
+			typedef forward_iterator_base< T > base_class;
+
+			range_iterator_base( T value ) : forward_iterator_base<T>( value ) {}
+			range_iterator_base& operator++ () 
+			{
+				++base_class::m_value; 
+				return *this; 
+			}
+			range_iterator_base operator++ (int) 
+			{
+				auto result = *this; 
+				++*this; 
+				return result;
+			}
+		};
+
+		template < typename T >
+		class range2d_iterator_base 
+			: public forward_iterator_base< glm::detail::tvec2<T> >
+		{
+		public:
+			typedef forward_iterator_base< glm::detail::tvec2<T> > base_class;
+
+			range2d_iterator_base( glm::detail::tvec2<T> value, T min, T max ) 
+				: forward_iterator_base< glm::detail::tvec2<T> >( value ), m_min(min), m_max(max) {}
+			range2d_iterator_base& operator++ () 
+			{
+				++base_class::m_value.x;
+				if ( base_class::m_value.x > m_max ) 
+				{
+					++base_class::m_value.y;
+					base_class::m_value.x = m_min;
+				}
+				return *this; 
+			}
+			range2d_iterator_base operator++ (int) 
+			{
+				auto result = *this; 
+				++*this; 
+				return result;
+			}
+		protected:
+			T m_min;
+			T m_max;
+		};
+
+		template < typename T >
+		class bits_iterator_base : public forward_iterator_base< T >
+		{
+		public:
+			typedef typename base_underlying_type<T>::type base_type;
+			typedef forward_iterator_base< T > base_class;
+
+			static const T invalid = T( 0 );
+
+			bits_iterator_base( T value, T current ) : forward_iterator_base<T>( current ), m_full( value )
+			{
+				if( !( (base_type)value & (base_type)current ) )
+					next();
+			}
+			bits_iterator_base& operator++ () 
+			{
+				next();
+				return *this; 
+			}
+			bits_iterator_base operator++ (int) 
+			{
+				auto result = *this; 
+				++*this; 
+				return result;
+			}
+		private:
+			void next()
+			{
+				do
+				{
+					if ( base_class::m_value == invalid || m_full <= base_class::m_value ) { base_class::m_value = invalid; m_full = invalid; break; }
+					base_class::m_value = T((base_type)base_class::m_value << 1);
+				} while ( !( (base_type)m_full & (base_type)base_class::m_value ) );
+			}
+
+			T m_full;
+		};
+
+
+	} // namespace detail
+
+	template < typename T >
+	class range_iterator_provider
+	{
+	public:
+		class iterator : public detail::range_iterator_base<T>
+		{
+		public:
+			iterator( T value ) : detail::range_iterator_base<T>(value) {}
+		};
+
+		range_iterator_provider( T begin, T end ) : m_begin( begin ), m_end( end ) {}
+		iterator begin() { return m_begin; }
+		iterator end() { return m_end; }
+
+	protected:
+		iterator m_begin;
+		iterator m_end;
+	};
+
+	template < typename T >
+	class range2d_iterator_provider
+	{
+	public:
+		typedef T value_type;
+		typedef typename T::value_type element_type;
+
+		class iterator : public detail::range2d_iterator_base<element_type>
+		{
+		public:
+			iterator( value_type begin, element_type min, element_type max ) 
+				: detail::range2d_iterator_base<element_type>(begin, min, max) {}
+		};
+
+		range2d_iterator_provider( value_type begin, value_type end ) : m_begin( begin, begin.x, end.x ), m_end( T(begin.x, ++end.y ), begin.x, end.x ) {}
+		iterator begin() { return m_begin; }
+		iterator end() { return m_end; }
+
+	protected:
+		iterator m_begin;
+		iterator m_end;
+	};
+
+	template < typename T >
+	class bits_iterator_provider
+	{
+	public:
+		typedef typename base_underlying_type<T>::type base_type;
+		typedef detail::bits_iterator_base<T> iterator;
+		static const T invalid = T( 0 );
+
+		bits_iterator_provider( T value ) : m_value( value ) {}
+		iterator begin() { return iterator( m_value, T(1) ); }
+		iterator end() { return iterator( m_value, invalid ); }
+
+	protected:
+		T m_value;
+	};
+
+	template < typename T >
+	range_iterator_provider<T> range( T begin, T end )
+	{
+		return range_iterator_provider<T>( begin, end+1 );
+	}
+
+	template < typename T >
+	range2d_iterator_provider<T> range2d( T begin, T end )
+	{
+		return range2d_iterator_provider<T>( begin, end );
+	}
+
+	template < typename T >
+	range_iterator_provider<T> range( T end )
+	{
+		return range_iterator_provider<T>( 0, end );
+	}
+
+	template < typename T >
+	range2d_iterator_provider<T> range2d( T end )
+	{
+		return range2d_iterator_provider<T>( T(0,0), T( --end.x, --end.y ) );
+	}
+
+	template < typename C >
+	auto index( const C& c ) -> range_iterator_provider<decltype( c.size() )>
+	{
+		return range_iterator_provider<decltype( c.size() )>( 0, c.size() );
+	}
+
+	template < typename T >
+	bits_iterator_provider<T> bits( T value )
+	{
+		return bits_iterator_provider<T>( value );
+	}
+
+
+}
+
+#endif // NV_CORE_RANGE_HH
Index: /trunk/nv/stl/singleton.hh
===================================================================
--- /trunk/nv/stl/singleton.hh	(revision 368)
+++ /trunk/nv/stl/singleton.hh	(revision 368)
@@ -0,0 +1,120 @@
+// Copyright (C) 2012-2014 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 singleton.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief singleton pattern
+ */
+
+#ifndef NV_CORE_SINGLETON_HH
+#define NV_CORE_SINGLETON_HH
+
+#include <cassert>
+
+namespace nv
+{
+	/**
+	 * singleton
+	 * @brief Represents an accessible static object that will only have one instance.
+	 */
+    template <class T>
+    class singleton
+    {
+    private:
+        static T *singleton_; ///< Pointer to the instance of this object type.
+
+    protected:
+
+		/**
+		 * Creates the single instance if one doesn't already exist.
+		 */
+        singleton()
+        {
+            assert(!singleton_);
+            singleton_ = static_cast<T*>(this);
+        }
+
+		/**
+		 * Destroys the instance.
+		 */
+        ~singleton()
+        {
+            assert(singleton_);
+            singleton_ = 0;
+        }
+
+    public:
+		/**
+		 * Checks to see if the instance exists.
+		 *
+		 * @returns True if this singleton has an instance assigned, false otherwise.
+		 */
+        static bool is_valid()
+        {
+            return singleton_ != 0;
+        }
+
+		/**
+		 * Returns the pointer to the instance.
+		 *
+		 * @returns The pointer to the instance.
+		 */
+        static T *pointer()
+        {
+            assert(singleton_);
+            return singleton_;
+        }
+		/**
+		 * Returns the object referenced by this singleton.
+		 */
+        static T &reference()
+        {
+            assert(singleton_);
+            return *singleton_;
+        }
+    };
+
+    template <class T>
+    T* singleton<T>::singleton_ = 0;
+
+
+	/**
+	 * auto_singleton
+	 * @brief Represents a singleton that automatically creates an instance if one doesn't already exist.
+	 */
+    template <class T>
+    class auto_singleton : public singleton<T>
+    {
+    public:
+		/**
+		 * Returns the pointer to the instance.  Makes an instance if one doesn't already exist.
+		 */
+        static T *pointer()
+        {
+            if ( !singleton<T>::is_valid() )
+            {
+                new T();
+            }
+            return singleton<T>::pointer();
+        }
+
+		/**
+		 * Returns the object referenced by this singleton.  Makes an instance if one doesn't already exist.
+		 */
+        static T &reference()
+        {
+            if ( !singleton<T>::is_valid() )
+            {
+                new T();
+            }
+            return singleton<T>::reference();
+        }
+    };
+
+} // namespace nv
+
+#endif // NV_CORE_SINGLETON_HH
Index: /trunk/nv/stl/string.hh
===================================================================
--- /trunk/nv/stl/string.hh	(revision 368)
+++ /trunk/nv/stl/string.hh	(revision 368)
@@ -0,0 +1,643 @@
+// Copyright (C) 2012-2014 ChaosForge Ltd
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+//
+// TODO: tests for string_length
+//  * performance tests
+//  * matching tests
+//  * compatibility tests
+//  * check if we can get rid of const templates
+//
+// String reference implementation based of string_ref proposal and boost::string_ref
+//
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
+// http://www.boost.org/doc/libs/1_58_0/libs/utility/doc/html/string_ref.html
+//
+// TODO: WARNING: this code is centered around 8bit char. In particular, 
+//   const_string wont work with non-8bit chars.
+// TODO: remove templating on char type, make a string_utf8 instead.
+
+#ifndef NV_CORE_STRING_HH
+#define NV_CORE_STRING_HH
+
+#include <string>
+#include <algorithm>
+#include <cstring>
+#include <sstream>
+#include <fstream>
+#include <nv/core/common.hh>
+#include <nv/stl/memory.hh>
+#include <nv/stl/exception.hh>
+
+namespace nv
+{
+	using std::string;
+
+
+
+	/**
+	* Utility function for converting any value to string.
+	*
+	* @param value value to be converted, needs to have << operator
+	*        to stream
+	* @throw runtime_error Throws runtime_error on conversion fail
+	* @return value converted to string
+	*/
+	template < class T >
+	string to_string( const T& value )
+	{
+		std::stringstream stream;
+		stream << value;
+
+		if ( stream.fail() )
+		{
+//			NV_THROW( runtime_error, "bad cast" );
+		}
+
+		return stream.str();
+	}
+
+	/**
+	* Override function for special treatment of strings. Returns the
+	* value passed.
+	*/
+	inline string to_string( const string& value)
+	{
+		return value;
+	}
+
+	/**
+	* Utility function for converting a string to the given type
+	*
+	* @param vin the string representing the value
+	* @param vout the value to be read. Must be streamable with >>
+	* @throw runtime_error Throws runtime_error on conversion fail
+	*/
+	template < class T >
+	void from_string( const string& vin, T& vout )
+	{
+		std::istringstream value( vin );
+		value >> vout;
+
+		if ( value.fail() )
+		{
+//			NV_THROW( runtime_error, "bad cast" );
+		}
+	}
+
+	/**
+	* Utility function for converting a string to the given type
+	*
+	* @param vin the string representing the value
+	* @throw runtime_error Throws runtime_error on conversion fail
+	*/
+	template < class T >
+	T string_cast( const string& vin )
+	{
+		T vout;
+		std::istringstream value( vin );
+		value >> vout;
+
+		if ( value.fail() )
+		{
+//			NV_THROW( runtime_error, "bad cast" );
+		}
+		return vout;
+	}
+
+
+	/**
+	* Override function for special treatment of strings. Returns the
+	* value passed.
+	*/
+	inline void from_string( const string& vin, string& vout )
+	{
+		vout = vin;
+	}
+
+	/**
+	* Override function for special treatment of strings. Returns the
+	* value passed.
+	*/
+	template <>
+	inline std::string string_cast( const string& vin )
+	{
+		return vin;
+	}
+
+
+	/**
+	* Simple function for slurping a file into a string.
+	*/
+	inline std::string slurp( const std::string& filename )
+	{
+		std::ifstream input(filename);
+//		if ( !input.is_open() ) NV_THROW( std::runtime_error, "File "+filename+" not found!");
+		std::stringstream sstr;
+		while(input >> sstr.rdbuf());
+		return sstr.str();
+	}
+
+	inline bool trim( std::string& str )
+	{
+		size_t endpos = str.find_last_not_of(" \r\n\t");
+		size_t startpos = str.find_first_not_of(" \r\n\t");
+
+		if ( string::npos != endpos || string::npos != startpos )
+		{
+			if ( string::npos == startpos ) startpos = 0;
+			if ( string::npos != endpos )   endpos = endpos+1-startpos;
+			str = str.substr( startpos, endpos );
+			return true;
+		}
+		return false;
+	}
+
+	inline bool rtrim( std::string& str )
+	{
+		size_t endpos = str.find_last_not_of(" \r\n\t");
+		if ( string::npos != endpos )
+		{
+			str = str.substr( 0, endpos+1 );
+			return true;
+		}
+		return false;
+	}
+
+	inline bool ltrim( std::string& str )
+	{
+		size_t startpos = str.find_first_not_of(" \r\n\t");
+		if( string::npos != startpos )
+		{
+			str = str.substr( startpos );
+			return true;
+		}
+		return false;
+	}
+
+	inline std::string trimmed( const std::string& str )
+	{
+		size_t endpos = str.find_last_not_of(" \r\n\t");
+		size_t startpos = str.find_first_not_of(" \r\n\t");
+
+		if ( string::npos != endpos || string::npos != startpos )
+		{
+			if ( string::npos == startpos ) startpos = 0;
+			if ( string::npos != endpos )   endpos = endpos+1-startpos;
+			return str.substr( startpos, endpos );
+		}
+		return str;
+	}
+
+	inline std::string rtrimmed( const std::string& str )
+	{
+		size_t endpos = str.find_last_not_of(" \r\n\t");
+		if ( string::npos != endpos )
+		{
+			return str.substr( 0, endpos+1 );
+		}
+		return str;
+	}
+
+	inline std::string ltrimmed( const std::string& str )
+	{
+		size_t startpos = str.find_first_not_of(" \r\n\t");
+		if( string::npos != startpos )
+		{
+			return str.substr( startpos );
+		}
+		return str;
+	}
+
+	inline bool ends_with( const std::string& s, const std::string & ending )
+	{
+		if ( s.length() >= ending.length() ) {
+			return ( 0 == s.compare (s.length() - ending.length(), ending.length(), ending) );
+		} else {
+			return false;
+		}
+	}
+
+	inline std::string& remove_chars( std::string& s, const std::string& chars ) 
+	{
+		s.erase(remove_if(s.begin(), s.end(), 
+			[&chars](const char& c) {
+				return chars.find(c) != std::string::npos;
+			}), s.end());
+		return s;
+	}
+
+	inline std::string extract_extension( const std::string& filename )
+	{
+		size_t lastdot = filename.find_last_of( "." );
+		std::string ext;
+		if ( std::string::npos != lastdot )
+			ext = filename.substr( lastdot + 1 );
+		std::transform( ext.begin(), ext.end(), ext.begin(), ::tolower );
+		return ext;
+	}
+
+	inline std::string remove_chars_copy( std::string s, const std::string& chars ) 
+	{
+		return remove_chars(s, chars);
+	}
+
+	namespace detail
+	{
+		template< typename T >
+		struct string_length_impl
+		{
+			static size_t get( T ) { return 0; }
+		};
+		template< size_t S >
+		struct string_length_impl < char[S] >
+		{
+			static size_t get( const char[S] ) { return S - 1; }
+		};
+		template< size_t S >
+		struct string_length_impl < const char[S] >
+		{
+			static size_t get( const char[S] ) { return S - 1; }
+		};
+		template<>
+		struct string_length_impl < char* >
+		{
+			static size_t get( const char* s ) { return std::strlen( s ); }
+		};
+		template<>
+		struct string_length_impl < const char* >
+		{
+			static size_t get( const char* s ) { return std::strlen( s ); }
+		};
+		template<>
+		struct string_length_impl < std::string >
+		{
+			static size_t get( const std::string& s ) { return s.length(); }
+		};
+		template<>
+		struct string_length_impl < const std::string >
+		{
+			static size_t get( const std::string& s ) { return s.length(); }
+		};
+	}
+
+#if NV_COMPILER == NV_GNUC
+	template< typename T >
+	struct string_length : public detail::string_length_impl <
+		typename std::remove_cv < typename std::remove_reference< T >::type >::type >
+	{
+	};
+#else
+	template< typename T >
+	using string_length = detail::string_length_impl <
+		typename std::remove_cv < typename std::remove_reference< T >::type >::type >;
+#endif
+
+	class string_ref;
+
+	// string base class - will become a base for a string class later
+	class string_base : public detail::data_base< char, true, 0 >
+	{
+	public:
+		typedef char           value_type;
+		typedef const char*    pointer;
+		typedef const char&    reference;
+		typedef const char&    const_reference;
+		typedef pointer        const_iterator;
+		typedef const_iterator iterator;
+		typedef std::size_t    size_type;
+		typedef std::ptrdiff_t difference_type;
+
+		static NV_CONSTEXPR_CONST size_type npos = size_type( -1 );
+
+		// conversion to std::string
+ 		inline std::string to_string() const
+ 		{
+ 			return std::string( m_data, m_size );
+ 		}
+
+		inline NV_CONSTEXPR size_type length()   const { return m_size; }
+
+		// access
+		inline NV_CONSTEXPR char operator[]( size_type i ) const { return m_data[i]; }
+		inline char at( size_t i ) const
+		{
+			//	if ( i >= m_data ) NV_THROW( std::out_of_range( "string_ref::at" ) );
+			return m_data[i];
+		}
+
+		inline NV_CONSTEXPR char front()        const { return m_data[0]; }
+		inline NV_CONSTEXPR char back()         const { return m_data[m_size - 1]; }
+
+		// string operations
+		int compare( const string_base& rhs ) const
+		{
+			int cmp = std::memcmp( m_data, rhs.m_data, ( std::min )( m_size, rhs.m_size ) );
+			return cmp != 0 ? cmp : ( m_size == rhs.m_size ? 0 : m_size < rhs.m_size ? -1 : 1 );
+		}
+		bool starts_with( char c ) const { return !empty() && c == front(); }
+		bool starts_with( const string_base& s ) const
+		{
+			return m_size >= s.m_size && std::memcmp( m_data, s.m_data, s.m_size ) == 0;
+		}
+		bool ends_with( char c ) const { return !empty() && c == back(); }
+		bool ends_with( const string_base& s ) const
+		{
+			return m_size >= s.m_size && std::memcmp( m_data + m_size - s.m_size, s.m_data, s.m_size ) == 0;
+		}
+		size_type find( const string_base& s, size_type pos = 0 ) const
+		{
+			if ( pos >= m_size ) return npos;
+			const_iterator it = std::search( this->cbegin() + ( difference_type ) pos, this->cend(), s.cbegin(), s.cend() );
+			return it == this->cend() ? npos : ( size_type )std::distance( this->cbegin(), it );
+		}
+		size_type find( char c, size_type pos = 0 ) const
+		{
+			if ( pos >= m_size ) return npos;
+			const_iterator it = std::find_if( this->cbegin() + ( difference_type ) pos, this->cend(), [=] ( char val ) { return val == c; } );
+			return it == this->cend() ? npos : ( size_type )std::distance( this->cbegin(), it );
+		}
+		size_type rfind( const string_base& s, size_type pos = 0 ) const
+		{
+			if ( pos >= m_size ) return npos;
+			const_reverse_iterator it = std::search( this->crbegin() + ( difference_type ) pos, this->crend(), s.crbegin(), s.crend() );
+			return it == this->crend() ? npos : m_size - 1 - ( size_type )std::distance( this->crbegin(), it );
+		}
+		size_type rfind( char c, size_type pos = 0 ) const
+		{
+			if ( pos >= m_size ) return npos;
+			const_reverse_iterator it = std::find_if( this->crbegin() + ( difference_type ) pos, this->crend(), [=] ( char val ) { return val == c; } );
+			return it == this->crend() ? npos : m_size - 1 - ( size_type )std::distance( this->crbegin(), it );
+		}
+		size_type find_first_of( char c ) const { return find( c ); }
+		size_type find_first_of( const string_base& s ) const
+		{
+			const_iterator it = std::find_first_of( this->cbegin(), this->cend(), s.cbegin(), s.cend() );
+			return it == this->cend() ? npos : ( size_type )std::distance( this->cbegin(), it );
+		}
+		size_type find_last_of( char c )  const { return rfind( c ); }
+		size_type find_last_of( const string_base& s ) const
+		{
+			const_reverse_iterator it = std::find_first_of( this->crbegin(), this->crend(), s.cbegin(), s.cend() );
+			return it == this->crend() ? npos : m_size - 1 - ( size_type )std::distance( this->crbegin(), it );
+		}
+		size_type find_first_not_of( const string_base& s ) const
+		{
+			for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
+				if ( 0 == std::memchr( s.m_data, *it, s.m_size ) )
+					return ( size_type )std::distance( this->cbegin(), it );
+			return npos;
+		}
+		size_type find_first_not_of( char c ) const
+		{
+			for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
+				if ( c != *it )
+					return ( size_type )std::distance( this->cbegin(), it );
+			return npos;
+		}
+		size_type find_last_not_of( const string_base& s ) const
+		{
+			for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
+				if ( 0 == std::memchr( s.m_data, *it, s.m_size ) )
+					return m_size - 1 - ( size_type )std::distance( this->crbegin(), it );;
+			return npos;
+		}
+		size_type find_last_not_of( char c ) const
+		{
+			for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
+				if ( c != *it )
+					return m_size - 1 - ( size_type )std::distance( this->crbegin(), it );
+			return npos;
+		}
+
+		// string operations
+		string_ref substr( size_type p, size_type n = npos ) const;
+
+		inline std::size_t hash() const
+		{
+			const char* str = m_data;
+			size_type   sz  = m_size;
+			int seed = 131;
+			int result = 0;
+			while ( sz )
+			{
+				result = ( result * seed ) + ( *str );
+				str++;
+				sz--;
+			}
+			return result & ( 0x7FFFFFFF );
+		}
+
+	protected:
+		inline NV_CONSTEXPR string_base() : detail::data_base< char, true, 0 >() {}
+		inline NV_CONSTEXPR string_base( pointer a_data, size_type a_lenght )
+			: detail::data_base< char, true, 0 >( a_data, a_lenght ) {}
+	};
+
+	class string_ref : public string_base
+	{
+	public:
+		inline NV_CONSTEXPR string_ref() {}
+		inline NV_CONSTEXPR string_ref( const string_ref& rhs )
+			: string_base( rhs.m_data, rhs.m_size )
+		{
+		}
+		inline NV_CONSTEXPR string_ref( const string_base& rhs )
+			: string_base( rhs.data(), rhs.size() )
+		{
+		}
+
+		inline string_ref( const std::string& str )
+			: string_base( str.data(), str.size() )
+		{
+		}
+
+		inline NV_CONSTEXPR string_ref( const char* str, size_type len )
+			: string_base( str, len )
+		{
+		}
+
+		// Literal constructors
+		template< size_t N >
+		inline string_ref( char( &s )[N] ) : string_base( s, N - 1 ) {}
+		template< size_t N >
+		inline string_ref( const char( &s )[N] ) : string_base( s, N - 1 ) {}
+
+		// Non-literal constructors
+		template< typename U >
+		inline string_ref( U str, typename std::enable_if<std::is_same<U, const char*>::value>::type* = nullptr ) : string_base( str, std::strlen( str ) ) {}
+
+		// Non-literal constructors
+		template< typename U >
+		inline string_ref( U str, typename std::enable_if<std::is_same<U, char*>::value>::type* = nullptr ) : string_base( str, std::strlen( str ) ) {}
+
+		inline string_ref& operator=( const string_ref &rhs )
+		{
+			m_data = rhs.m_data;
+			m_size = rhs.m_size;
+			return *this;
+		}
+
+		// modifiers
+		inline void clear()
+		{
+			m_size = 0;
+			m_data = nullptr;
+		}
+		inline void remove_prefix( size_type n )
+		{
+			if ( n > m_size )	n = m_size;
+			m_data += n;
+			m_size -= n;
+		}
+		inline void remove_suffix( size_type n )
+		{
+			if ( n > m_size ) n = m_size;
+			m_size -= n;
+		}
+
+	};
+
+	// const string is movable but not copyable
+	class const_string : public string_base
+	{
+	public:
+		NV_CONSTEXPR const_string() {}
+		const_string( const char* str, size_type len )
+		{
+			initialize( str, len );
+		}
+		explicit const_string( const char* str )
+		{
+			initialize( str, std::strlen( str ) );
+		}
+
+		~const_string()
+		{
+			if ( m_data ) delete m_data;
+		}
+
+		inline const_string( const_string&& other )
+		{
+			m_data = other.m_data;
+			other.m_data = nullptr;
+		}
+
+		inline const_string& operator=( const_string&& other )
+		{
+			pointer temp = m_data;
+			m_data = other.m_data;
+			other.m_data = temp;
+			return *this;
+		}
+
+		// blocked copy constructor
+		const_string( const const_string & ) = delete;
+		// blocked copy operator
+		const_string& operator=( const const_string& ) = delete;
+
+	private:
+
+		void initialize( const char* p, size_type s )
+		{
+			char* data = new char[s + 1];
+			std::memcpy( data, p, s );
+			data[s] = 0;
+			m_data = data;
+		}
+	};
+
+	inline string_ref string_base::substr( size_type p, size_type n ) const
+	{
+		if ( p > size() ) return string_ref(); // NV_THROW( std::out_of_range( "substr" ) );
+		if ( n == p || p + n > size() ) n = size() - p;
+		return string_ref( data() + p, n );
+	}
+
+#define NV_STRING_BASE_CAST_OPERATORS( OPERATOR )\
+inline bool operator OPERATOR ( const string_base& lhs, const std::string& rhs )\
+{\
+	return lhs OPERATOR string_ref( rhs );\
+}\
+inline bool operator OPERATOR ( const std::string& lhs, const string_base& rhs )\
+{\
+	return string_ref( lhs ) OPERATOR rhs;\
+}\
+inline bool operator OPERATOR ( const string_base& lhs, const char* rhs )\
+{\
+	return lhs OPERATOR string_ref( rhs );\
+}\
+inline bool operator OPERATOR ( const char* lhs, const string_base& rhs )\
+{\
+	return string_ref( lhs ) OPERATOR rhs;\
+}\
+
+	// Base operators
+	inline bool operator==( const string_base& lhs, const string_base& rhs )
+	{
+		return lhs.size() != rhs.size() ? false : ( lhs.compare( rhs ) == 0 );
+	}
+	inline bool operator!=( const string_base& lhs, const string_base& rhs )
+	{
+		return lhs.size() != rhs.size() ? true : ( lhs.compare( rhs ) != 0 );
+	}
+	inline bool operator<( const string_base& lhs, const string_base& rhs )
+	{
+		return lhs.compare( rhs ) < 0;
+	}
+	inline bool operator>( const string_base& lhs, const string_base& rhs )
+	{
+		return lhs.compare( rhs ) > 0;
+	}
+	inline bool operator<=( const string_base& lhs, const string_base& rhs )
+	{
+		return lhs.compare( rhs ) <= 0;
+	}
+	inline bool operator>=( const string_base& lhs, const string_base& rhs )
+	{
+		return lhs.compare( rhs ) >= 0;
+	}
+
+NV_STRING_BASE_CAST_OPERATORS( == )
+NV_STRING_BASE_CAST_OPERATORS( != )
+NV_STRING_BASE_CAST_OPERATORS( < )
+NV_STRING_BASE_CAST_OPERATORS( > )
+NV_STRING_BASE_CAST_OPERATORS( <= )
+NV_STRING_BASE_CAST_OPERATORS( >= )
+
+	inline std::ostream& operator<<( std::ostream& os, const string_base& str )
+	{
+		if ( os.good() )
+		{
+			os.write( str.data(), static_cast<std::streamsize>( str.size() ) );
+		}
+		return os;
+	}
+
+#undef NV_STRING_REF_CAST_OPERATORS
+
+size_t sint32_to_buffer( sint32 n, char* str );
+size_t sint64_to_buffer( sint64 n, char* str );
+size_t uint32_to_buffer( uint32 n, char* str );
+size_t uint64_to_buffer( uint64 n, char* str );
+size_t f32_to_buffer( f32 n, char* str );
+size_t f64_to_buffer( f64 n, char* str );
+
+
+}
+
+namespace std
+{
+
+	template<>
+	struct hash< nv::string_base >
+	{
+		std::size_t operator()( const nv::string_base& s ) const
+		{
+			return s.hash();
+		}
+	};
+
+}
+
+#endif // NV_CORE_STRING_HH
Index: /trunk/nv/stl/type_traits.hh
===================================================================
--- /trunk/nv/stl/type_traits.hh	(revision 368)
+++ /trunk/nv/stl/type_traits.hh	(revision 368)
@@ -0,0 +1,178 @@
+// Copyright (C) 2012-2014 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 type_traits.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief type traits
+ */
+// TODO: function_traits support only up to 4 parameters because:
+//    -- if you have more than 4 params, you're doing something wrong
+//    -- once the Variadic Templates cometh, for great justice we will win!
+
+#ifndef NV_CORE_TYPE_TRAITS_HH
+#define NV_CORE_TYPE_TRAITS_HH
+
+#include <nv/core/common.hh>
+#include <type_traits>
+
+namespace nv
+{
+
+	// These could be done much better
+	template <typename T>
+	struct is_cstring
+		: public std::integral_constant<bool,
+		std::is_same<       char *, typename std::decay< T >::type >::value ||
+		std::is_same< const char *, typename std::decay< T >::type >::value >
+		{};
+
+	template <typename T>
+	struct is_stdstring
+		: public std::integral_constant<bool,
+		std::is_same< std::string, typename std::decay< T >::type >::value 
+		>
+	{};
+
+	template < typename T > struct is_string : public std::integral_constant<bool, is_stdstring<T>::value || is_cstring<T>::value> {};
+
+	// Just for once, MSVC is the good guy, and everybody else sucks.
+	// Remove, once requiring standard-compliant CLANG/GCC versions.
+#if NV_COMPILER == NV_MSVC
+	using std::underlying_type;
+#elif NV_COMPILER == NV_CLANG
+	template < typename T >
+	struct underlying_type
+	{
+		typedef __underlying_type(T) type;
+	};
+#else
+	template< typename T >
+	struct underlying_type
+	{
+		typedef typename std::conditional<
+			T( -1 ) < T( 0 ),
+			typename std::make_signed< T >::type,
+			typename std::make_unsigned< T >::type
+			>::type type;
+	};
+#endif
+
+	namespace detail
+	{
+
+		template < typename F >
+		struct function_traits_impl
+		{
+
+		};
+
+		template < typename R >
+		struct function_traits_impl< R (*)(void) >
+		{
+			typedef R (*type)();
+			typedef R        return_type;
+			typedef void     class_type;
+			static const int arg_count = 0;
+		};
+
+		template < typename R, typename... Args >
+		struct function_traits_impl < R(*)(Args...) >
+		{
+			typedef R(*type)( Args... );
+			typedef R        return_type;
+			typedef void     class_type;
+			static const int arg_count = sizeof...(Args);
+		};
+
+		template < class C, typename R >
+		struct function_traits_impl< R (C::*)() >
+		{
+			typedef R (*type)();
+			typedef R       return_type;
+			typedef C       class_type;
+			static const int arg_count = 0;
+		};
+
+		template < class C, typename R, typename... Args >
+		struct function_traits_impl < R(C::*)(Args...) >
+		{
+			typedef R(C::*type)(Args...);
+			typedef R        return_type;
+			typedef C        class_type;
+			static const int arg_count = sizeof...(Args);
+		};
+
+	}
+
+	template < typename F >
+	struct function_traits : public detail::function_traits_impl< F >
+	{
+
+	};
+
+	template < typename T >
+	struct return_type
+	{
+		typedef typename function_traits< T >::return_type type;
+	};
+
+	template < typename T >
+	struct memfn_class_type
+	{
+		typedef typename function_traits< T >::class_type type;
+	};
+
+	template<typename T>
+	struct is_container
+	{
+	private:
+		typedef char                      yes;
+		typedef struct { char array[2]; } no;
+		template<typename C> static yes test(typename C::iterator*);
+		template<typename C> static no  test(...);
+	public:
+		static const bool value = sizeof(test<T>(0)) == sizeof(yes);
+	};
+
+	template<>
+	struct is_container< std::string > {
+		static const bool value = false;
+	};
+
+	template <typename TYPE> 
+	void construct_object(void* object)
+	{
+		new (object) TYPE;
+	}
+	template <typename TYPE> 
+	void destroy_object(void* object)
+	{
+		((TYPE*)object)->TYPE::~TYPE();
+	}
+
+	template< typename T, typename IS_ENUM >
+	struct base_underlying_type_helper
+	{
+		typedef T type;
+	};
+
+	template< typename T >
+	struct base_underlying_type_helper< T, std::true_type >
+	{
+		typedef typename nv::underlying_type<T>::type type;
+	};
+
+
+	template< typename T >
+	struct base_underlying_type
+	{
+		typedef typename base_underlying_type_helper< T, typename std::is_enum<T>::type >::type type;
+	};
+
+
+}
+
+#endif // NV_CORE_TYPE_TRAITS_HH
Index: /trunk/src/core/logger.cc
===================================================================
--- /trunk/src/core/logger.cc	(revision 367)
+++ /trunk/src/core/logger.cc	(revision 368)
@@ -142,8 +142,10 @@
 void log_console_sink::log( log_level level, const string_ref& message )
 {
+	char stamp[16];
+	size_t ssize = timestamp( stamp );
+
 #if NV_PLATFORM == NV_WINDOWS 
 	if ( m_color ) SetConsoleTextAttribute( m_handle, FOREGROUND_INTENSITY );
-	string_ref stamp( timestamp() );
-	WriteConsole( m_handle, stamp.data(), stamp.size(), nullptr, nullptr );
+	WriteConsole( m_handle, stamp, ssize, nullptr, nullptr );
 	WriteConsole( m_handle, " [", 2, nullptr, nullptr );
 	if (m_color) SetConsoleTextAttribute( m_handle, log_color[( level ) / 10] );
@@ -156,5 +158,5 @@
 #else
 	if ( m_color ) fwrite( "\33[30;1m", 7, 1, stdout );
-	fwrite( stamp.data(), stamp.size(), 1, stdout );
+	fwrite( stamp, ssize, 1, stdout );
 	fwrite( " [", 2, 1, stdout );
 	if ( m_color )
@@ -176,5 +178,6 @@
 void log_handle_sink::log( log_level level, const string_ref& message )
 {
-	string_ref stamp( timestamp() );
+	char stamp[16];
+	size_t ssize = timestamp( stamp );
 #if 0 // NV_PLATFORM == NV_WINDOWS
 	// Turns out WriteFile on Windows is unbuffered and quite slower than fwrite 
@@ -182,5 +185,5 @@
 	// If we want to get rid of C runtime, this would need a buffered I/O layer.
 	DWORD unused = 0;
-	WriteFile( m_handle, stamp.data(), stamp.size(), &unused, nullptr );
+	WriteFile( m_handle, stamp, ssize, &unused, nullptr );
 	WriteFile( m_handle, " [", 2, &unused, nullptr );
 	WriteFile( m_handle, NV_LOG_LEVEL_NAME_PAD( level ), 8, &unused, nullptr );
@@ -190,5 +193,5 @@
 	//if ( m_flush ) FlushFileBuffers( m_handle );
 #else
-	fwrite( stamp.data(), stamp.size(), 1, (FILE*)m_handle );
+	fwrite( stamp, ssize, 1, (FILE*)m_handle );
 	fwrite( " [", 2, 1, (FILE*)m_handle );
 	fwrite( NV_LOG_LEVEL_NAME_PAD( level ), 8, 1, (FILE*)m_handle );
@@ -237,5 +240,5 @@
 }
 
-string_ref nv::log_sink::timestamp() const
+size_t nv::log_sink::timestamp( char* buffer ) const
 {
 	uint32 ms = get_system_ms();
@@ -245,5 +248,4 @@
 	unsigned int m    = (unsigned int)(secs / 60) % 60;
 	unsigned int s    = secs % 60;
-	static char buffer[16];
 #if NV_PLATFORM == NV_WINDOWS 
 	sprintf_s( buffer, 16, "%02d:%02d:%02d.%02d", h, m, s, mm );
@@ -251,6 +253,5 @@
 	snprintf( buffer, 16, "%02d:%02d:%02d.%02d", h, m, s, mm );
 #endif
-	buffer[11] = '\0';
-	return string_ref( buffer, 10 );
+	return 11;
 }
 
Index: unk/src/core/string.cc
===================================================================
--- /trunk/src/core/string.cc	(revision 367)
+++ 	(revision )
@@ -1,182 +1,0 @@
-// 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
-//
-// TODO: speedup conversion by doing divisions by 100
-
-#include "nv/core/string.hh"
-
-#include <cstdio>
-#include <cstdlib>
-
-using namespace nv;
-
-static const double s_power_10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
-10000000, 100000000, 1000000000 };
-
-static inline void string_reverse( char* begin, char* end )
-{
-	char temp;
-	while ( end > begin )
-	{
-		temp = *end;
-		*end-- = *begin;
-		*begin++ = temp;
-	}
-}
-
-size_t nv::sint32_to_buffer( sint32 n, char* str )
-{
-	char* s = str;
-	uint32 abs = ( n < 0 ) ? (uint32)( -n ) : (uint32)( n );
-	do
-	{
-		*s++ = (char)( '0' + ( abs % 10 ) );
-		abs /= 10;
-	} while ( abs > 0 );
-	if ( n < 0 ) *s++ = '-';
-	*s = '\0';
-	string_reverse( str, s - 1 );
-	return (size_t)( s - str );
-}
-
-size_t nv::sint64_to_buffer( sint64 n, char* str )
-{
-	char* s = str;
-	uint64 abs = ( n < 0 ) ? (uint64)( -n ) : (uint64)( n );
-	do
-	{
-		*s++ = (char)( '0' + ( abs % 10 ) );
-		abs /= 10;
-	} while ( abs > 0 );
-	if ( n < 0 ) *s++ = '-';
-	*s = '\0';
-	string_reverse( str, s - 1 );
-	return (size_t)( s - str );
-}
-
-size_t nv::uint32_to_buffer( uint32 n, char* str )
-{
-	char* s = str;
-	do
-	{
-		*s++ = (char)( '0' + ( n % 10 ) );
-		n /= 10;
-	} while ( n > 0 );
-	*s = '\0';
-	string_reverse( str, s - 1 );
-	return (size_t)( s - str );
-}
-
-size_t nv::uint64_to_buffer( uint64 n, char* str )
-{
-	char* s = str;
-	do
-	{
-		*s++ = (char)( '0' + ( n % 10 ) );
-		n /= 10;
-	} while ( n > 0 );
-	*s = '\0';
-	string_reverse( str, s - 1 );
-	return (size_t)( s - str );
-}
-
-size_t nv::f32_to_buffer( f32 n, char* str )
-{
-#if NV_COMPILER == NV_MSVC
-	sprintf_s( str, 64, "%.*g", 6, n );
-#else
-	snprintf( str, 64, "%.*g", 6, n );
-#endif
-	sprintf( str, "%g", n );
-	return strlen( str );
-}
-
-size_t nv::f64_to_buffer( f64 n, char* str )
-{
-#if NV_COMPILER == NV_MSVC
-	sprintf_s( str, 64, "%.*g", 6, n );
-#else
-	snprintf( str, 64, "%.*g", 6, n );
-#endif
-	return strlen( str );
-}
-
-sint32 buffer_to_sint32( const char* str, char** end )
-{
-	const char* s = str;
-	while ( *s == ' ' ) ++s;
-	sint32 result = 0;
-	bool positive = true;
-	switch ( *s )
-	{
-	case '-': ++s; positive = false; break;
-	case '+': ++s; break;
-	default: break;
-	}
-	while ( *s >= '0' && *s <= '9' )
-	{
-		result = ( result * 10 ) + ( *s - '0' );
-		++s;
-	}
-	if ( end != nullptr ) *end = (char*)s;
-	return positive ? result : -result;
-}
-
-sint64 buffer_to_sint64( const char* s, char** end )
-{
-	while ( *s == ' ' ) ++s;
-	sint64 result = 0;
-	bool positive = true;
-	switch ( *s )
-	{
-	case '-': ++s; positive = false; break;
-	case '+': ++s; break;
-	default: break;
-	}
-	while ( *s >= '0' && *s <= '9' )
-	{
-		result = ( result * 10 ) + ( *s - '0' );
-		++s;
-	}
-	if ( end != nullptr ) *end = (char*)s;
-	return positive ? result : -result;
-}
-
-uint32 buffer_to_uint32( const char* s, char** end )
-{
-	while ( *s == ' ' ) ++s;
-	uint32 result = 0;
-	while ( *s >= '0' && *s <= '9' )
-	{
-		result = ( result * 10 ) + ( *s - '0' );
-		++s;
-	}
-	if ( end != nullptr ) *end = (char*)s;
-	return result;
-}
-
-uint64 buffer_to_uint64( const char* s, char** end )
-{
-	while ( *s == ' ' ) ++s;
-	uint64 result = 0;
-	while ( *s >= '0' && *s <= '9' )
-	{
-		result = ( result * 10 ) + ( *s - '0' );
-		++s;
-	}
-	if ( end != nullptr ) *end = (char*)s;
-	return result;
-}
-
-float buffer_to_f32( const char* s, char** end )
-{
-	return strtof( s, end );
-}
-
-double buffer_to_f64( const char* s, char** end )
-{
-	return strtod( s, end );
-}
Index: /trunk/src/engine/program_manager.cc
===================================================================
--- /trunk/src/engine/program_manager.cc	(revision 367)
+++ /trunk/src/engine/program_manager.cc	(revision 368)
@@ -6,5 +6,5 @@
 
 #include "nv/engine/program_manager.hh"
-#include "nv/core/range.hh"
+#include "nv/stl/range.hh"
 #include "nv/core/logging.hh"
 #include "nv/lua/lua_nova.hh"
Index: /trunk/src/engine/resource_system.cc
===================================================================
--- /trunk/src/engine/resource_system.cc	(revision 367)
+++ /trunk/src/engine/resource_system.cc	(revision 368)
@@ -6,5 +6,5 @@
 
 #include "nv/engine/resource_system.hh"
-#include "nv/core/range.hh"
+#include "nv/stl/range.hh"
 #include "nv/lua/lua_nova.hh"
 
Index: /trunk/src/formats/nmd_loader.cc
===================================================================
--- /trunk/src/formats/nmd_loader.cc	(revision 367)
+++ /trunk/src/formats/nmd_loader.cc	(revision 368)
@@ -7,5 +7,5 @@
 #include "nv/formats/nmd_loader.hh"
 #include "nv/io/std_stream.hh"
-#include "nv/core/string.hh"
+#include "nv/stl/string.hh"
 
 using namespace nv;
Index: /trunk/src/lib/gl.cc
===================================================================
--- /trunk/src/lib/gl.cc	(revision 367)
+++ /trunk/src/lib/gl.cc	(revision 368)
@@ -6,5 +6,5 @@
 
 #include "nv/core/common.hh"
-#include "nv/core/range.hh"
+#include "nv/stl/range.hh"
 #include "nv/core/logging.hh"
 #include "nv/lib/gl.hh"
Index: /trunk/src/lua/lua_area.cc
===================================================================
--- /trunk/src/lua/lua_area.cc	(revision 367)
+++ /trunk/src/lua/lua_area.cc	(revision 368)
@@ -8,5 +8,5 @@
 
 #include "nv/lua/lua_raw.hh"
-#include "nv/core/string.hh"
+#include "nv/stl/string.hh"
 #include "nv/core/random.hh"
 
Index: /trunk/src/lua/lua_flags.cc
===================================================================
--- /trunk/src/lua/lua_flags.cc	(revision 367)
+++ /trunk/src/lua/lua_flags.cc	(revision 368)
@@ -8,5 +8,5 @@
 
 #include "nv/lua/lua_raw.hh"
-#include "nv/core/string.hh"
+#include "nv/stl/string.hh"
 
 
Index: /trunk/src/lua/lua_glm.cc
===================================================================
--- /trunk/src/lua/lua_glm.cc	(revision 367)
+++ /trunk/src/lua/lua_glm.cc	(revision 368)
@@ -8,5 +8,5 @@
 
 #include "nv/lua/lua_raw.hh"
-#include "nv/core/string.hh"
+#include "nv/stl/string.hh"
 #include "nv/core/random.hh"
 
Index: /trunk/src/lua/lua_map_area.cc
===================================================================
--- /trunk/src/lua/lua_map_area.cc	(revision 367)
+++ /trunk/src/lua/lua_map_area.cc	(revision 368)
@@ -6,5 +6,5 @@
 
 #include "nv/lua/lua_map_area.hh"
-#include "nv/core/flags.hh"
+#include "nv/stl/flags.hh"
 #include "nv/lua/lua_area.hh"
 #include "nv/lua/lua_glm.hh"
Index: /trunk/src/lua/lua_map_tile.cc
===================================================================
--- /trunk/src/lua/lua_map_tile.cc	(revision 367)
+++ /trunk/src/lua/lua_map_tile.cc	(revision 368)
@@ -9,5 +9,5 @@
 #include <numeric>
 #include "nv/lua/lua_map_area.hh"
-#include "nv/core/flags.hh"
+#include "nv/stl/flags.hh"
 #include "nv/core/random.hh"
 #include "nv/lua/lua_area.hh"
Index: /trunk/src/lua/lua_raw.cc
===================================================================
--- /trunk/src/lua/lua_raw.cc	(revision 367)
+++ /trunk/src/lua/lua_raw.cc	(revision 368)
@@ -7,5 +7,5 @@
 #include "nv/lua/lua_raw.hh"
 
-#include "nv/core/string.hh"
+#include "nv/stl/string.hh"
 
 std::string nlua_typecontent( lua_State* L, int idx )
Index: /trunk/src/lua/lua_state.cc
===================================================================
--- /trunk/src/lua/lua_state.cc	(revision 367)
+++ /trunk/src/lua/lua_state.cc	(revision 368)
@@ -10,5 +10,5 @@
 #include "nv/lua/lua_nova.hh"
 #include "nv/core/logging.hh"
-#include "nv/core/string.hh"
+#include "nv/stl/string.hh"
 
 using namespace nv;
Index: /trunk/src/rogue/fov_recursive_shadowcasting.cc
===================================================================
--- /trunk/src/rogue/fov_recursive_shadowcasting.cc	(revision 367)
+++ /trunk/src/rogue/fov_recursive_shadowcasting.cc	(revision 368)
@@ -7,5 +7,5 @@
 #include "nv/rogue/fov_recursive_shadowcasting.hh"
 
-#include "nv/core/math.hh"
+#include "nv/stl/math.hh"
 
 static int nv_rogue_rs_mult[4][8] = {
Index: /trunk/src/sdl/sdl_audio.cc
===================================================================
--- /trunk/src/sdl/sdl_audio.cc	(revision 367)
+++ /trunk/src/sdl/sdl_audio.cc	(revision 368)
@@ -7,5 +7,5 @@
 #include "nv/sdl/sdl_audio.hh"
 
-#include "nv/core/math.hh"
+#include "nv/stl/math.hh"
 #include "nv/lib/sdl_mixer.hh"
 #include "nv/core/logging.hh"
Index: /trunk/src/stl/string.cc
===================================================================
--- /trunk/src/stl/string.cc	(revision 368)
+++ /trunk/src/stl/string.cc	(revision 368)
@@ -0,0 +1,182 @@
+// 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
+//
+// TODO: speedup conversion by doing divisions by 100
+
+#include "nv/stl/string.hh"
+
+#include <cstdio>
+#include <cstdlib>
+
+using namespace nv;
+
+static const double s_power_10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
+10000000, 100000000, 1000000000 };
+
+static inline void string_reverse( char* begin, char* end )
+{
+	char temp;
+	while ( end > begin )
+	{
+		temp = *end;
+		*end-- = *begin;
+		*begin++ = temp;
+	}
+}
+
+size_t nv::sint32_to_buffer( sint32 n, char* str )
+{
+	char* s = str;
+	uint32 abs = ( n < 0 ) ? (uint32)( -n ) : (uint32)( n );
+	do
+	{
+		*s++ = (char)( '0' + ( abs % 10 ) );
+		abs /= 10;
+	} while ( abs > 0 );
+	if ( n < 0 ) *s++ = '-';
+	*s = '\0';
+	string_reverse( str, s - 1 );
+	return (size_t)( s - str );
+}
+
+size_t nv::sint64_to_buffer( sint64 n, char* str )
+{
+	char* s = str;
+	uint64 abs = ( n < 0 ) ? (uint64)( -n ) : (uint64)( n );
+	do
+	{
+		*s++ = (char)( '0' + ( abs % 10 ) );
+		abs /= 10;
+	} while ( abs > 0 );
+	if ( n < 0 ) *s++ = '-';
+	*s = '\0';
+	string_reverse( str, s - 1 );
+	return (size_t)( s - str );
+}
+
+size_t nv::uint32_to_buffer( uint32 n, char* str )
+{
+	char* s = str;
+	do
+	{
+		*s++ = (char)( '0' + ( n % 10 ) );
+		n /= 10;
+	} while ( n > 0 );
+	*s = '\0';
+	string_reverse( str, s - 1 );
+	return (size_t)( s - str );
+}
+
+size_t nv::uint64_to_buffer( uint64 n, char* str )
+{
+	char* s = str;
+	do
+	{
+		*s++ = (char)( '0' + ( n % 10 ) );
+		n /= 10;
+	} while ( n > 0 );
+	*s = '\0';
+	string_reverse( str, s - 1 );
+	return (size_t)( s - str );
+}
+
+size_t nv::f32_to_buffer( f32 n, char* str )
+{
+#if NV_COMPILER == NV_MSVC
+	sprintf_s( str, 64, "%.*g", 6, n );
+#else
+	snprintf( str, 64, "%.*g", 6, n );
+#endif
+	sprintf( str, "%g", n );
+	return strlen( str );
+}
+
+size_t nv::f64_to_buffer( f64 n, char* str )
+{
+#if NV_COMPILER == NV_MSVC
+	sprintf_s( str, 64, "%.*g", 6, n );
+#else
+	snprintf( str, 64, "%.*g", 6, n );
+#endif
+	return strlen( str );
+}
+
+sint32 buffer_to_sint32( const char* str, char** end )
+{
+	const char* s = str;
+	while ( *s == ' ' ) ++s;
+	sint32 result = 0;
+	bool positive = true;
+	switch ( *s )
+	{
+	case '-': ++s; positive = false; break;
+	case '+': ++s; break;
+	default: break;
+	}
+	while ( *s >= '0' && *s <= '9' )
+	{
+		result = ( result * 10 ) + ( *s - '0' );
+		++s;
+	}
+	if ( end != nullptr ) *end = (char*)s;
+	return positive ? result : -result;
+}
+
+sint64 buffer_to_sint64( const char* s, char** end )
+{
+	while ( *s == ' ' ) ++s;
+	sint64 result = 0;
+	bool positive = true;
+	switch ( *s )
+	{
+	case '-': ++s; positive = false; break;
+	case '+': ++s; break;
+	default: break;
+	}
+	while ( *s >= '0' && *s <= '9' )
+	{
+		result = ( result * 10 ) + ( *s - '0' );
+		++s;
+	}
+	if ( end != nullptr ) *end = (char*)s;
+	return positive ? result : -result;
+}
+
+uint32 buffer_to_uint32( const char* s, char** end )
+{
+	while ( *s == ' ' ) ++s;
+	uint32 result = 0;
+	while ( *s >= '0' && *s <= '9' )
+	{
+		result = ( result * 10 ) + ( *s - '0' );
+		++s;
+	}
+	if ( end != nullptr ) *end = (char*)s;
+	return result;
+}
+
+uint64 buffer_to_uint64( const char* s, char** end )
+{
+	while ( *s == ' ' ) ++s;
+	uint64 result = 0;
+	while ( *s >= '0' && *s <= '9' )
+	{
+		result = ( result * 10 ) + ( *s - '0' );
+		++s;
+	}
+	if ( end != nullptr ) *end = (char*)s;
+	return result;
+}
+
+float buffer_to_f32( const char* s, char** end )
+{
+	return strtof( s, end );
+}
+
+double buffer_to_f64( const char* s, char** end )
+{
+	return strtod( s, end );
+}
