Index: trunk/nv/core/profiler.hh
===================================================================
--- trunk/nv/core/profiler.hh	(revision 391)
+++ trunk/nv/core/profiler.hh	(revision 392)
@@ -17,5 +17,5 @@
 #include <nv/stl/singleton.hh>
 #include <nv/stl/string.hh>
-#include <unordered_map>
+#include <nv/stl/unordered_map.hh>
 
 #if NV_PROFILER 
@@ -50,5 +50,5 @@
 			~node();
 		protected:
-			typedef std::unordered_map< std::string, node* > map;
+			typedef unordered_map< std::string, node* > map;
 
 			std::string m_tag;
Index: trunk/nv/core/types.hh
===================================================================
--- trunk/nv/core/types.hh	(revision 391)
+++ trunk/nv/core/types.hh	(revision 392)
@@ -9,8 +9,8 @@
 #include <nv/stl/math.hh>
 #include <nv/stl/memory.hh>
+#include <nv/stl/vector.hh>
+#include <nv/stl/unordered_map.hh>
 #include <nv/stl/cstring_store.hh>
 #include <nv/stl/type_traits/properties.hh>
-#include <unordered_map>
-#include <vector>
 
 namespace nv
@@ -78,6 +78,6 @@
 		size_t                  size;        //!< Result of sizeof(type) operation
 		type_entry*             base_type;   //!< Base type
-		std::vector<type_field> field_list;  //!< Field list
-		std::vector<type_enum>  enum_list;   //!< Enum list
+		vector<type_field> field_list;  //!< Field list
+		vector<type_enum>  enum_list;   //!< Enum list
 		cstring_store names;
 	};
@@ -154,6 +154,6 @@
 		}
 	private:
-		typedef std::vector<type_entry*>                   type_list;
-		typedef std::unordered_map<type_hash, type_entry*> type_info_map;
+		typedef vector<type_entry*>                   type_list;
+		typedef unordered_map<type_hash, type_entry*> type_info_map;
 		cstring_store m_names;
 		type_list     m_type_list;
Index: trunk/nv/core/uid.hh
===================================================================
--- trunk/nv/core/uid.hh	(revision 391)
+++ trunk/nv/core/uid.hh	(revision 392)
@@ -15,5 +15,5 @@
 
 #include <nv/core/common.hh>
-#include <unordered_map>
+#include <nv/stl/unordered_map.hh>
 
 namespace nv
@@ -74,5 +74,5 @@
 
 	protected:
-		typedef std::unordered_map< uid, void* > map;
+		typedef unordered_map< uid, void* > map;
 		map m_map; ///< The hash map everything is stored in.
 		uid m_current; ///< The last UID assigned.
Index: trunk/nv/engine/particle_engine.hh
===================================================================
--- trunk/nv/engine/particle_engine.hh	(revision 391)
+++ trunk/nv/engine/particle_engine.hh	(revision 392)
@@ -10,5 +10,6 @@
 #include <nv/core/common.hh>
 #include <nv/stl/math.hh>
-#include <nv/stl/array.hh>
+#include <nv/stl/vector.hh>
+#include <nv/stl/unordered_map.hh>
 #include <nv/stl/handle.hh>
 #include <nv/lua/lua_state.hh>
@@ -194,8 +195,8 @@
 
 		handle_store< particle_system_info, particle_system >      m_systems;
-		std::unordered_map< std::string, uint32 >                  m_names;
-		std::vector< particle_system_data >                        m_data; 
-		std::unordered_map< std::string, particle_emmiter_func >   m_emmiters;
-		std::unordered_map< std::string, particle_affector_funcs > m_affectors;
+		unordered_map< std::string, uint32 >                  m_names;
+		vector< particle_system_data >                        m_data; 
+		unordered_map< std::string, particle_emmiter_func >   m_emmiters;
+		unordered_map< std::string, particle_affector_funcs > m_affectors;
 	};
 
Index: trunk/nv/fmod/fmod_audio.hh
===================================================================
--- trunk/nv/fmod/fmod_audio.hh	(revision 391)
+++ trunk/nv/fmod/fmod_audio.hh	(revision 392)
@@ -34,5 +34,5 @@
 			virtual channel play_sound( sound a_sound, float volume = 1.0f, float pan = 0.0f );
 			virtual channel play_sound( sound a_sound, vec3 position );
-			virtual sound load_sound( const std::string& a_path );
+			virtual sound load_sound( const string_ref& a_path );
 			virtual void release( sound a_sound );
 			virtual void set_orientation( vec3 forward, vec3 up );
Index: trunk/nv/formats/md2_loader.hh
===================================================================
--- trunk/nv/formats/md2_loader.hh	(revision 391)
+++ trunk/nv/formats/md2_loader.hh	(revision 392)
@@ -15,5 +15,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/stl/array.hh>
+#include <nv/stl/vector.hh>
 #include <nv/interface/mesh_loader.hh>
 
Index: trunk/nv/formats/md3_loader.hh
===================================================================
--- trunk/nv/formats/md3_loader.hh	(revision 391)
+++ trunk/nv/formats/md3_loader.hh	(revision 392)
@@ -15,6 +15,4 @@
 
 #include <nv/core/common.hh>
-#include <unordered_map>
-#include <nv/stl/array.hh>
 #include <nv/core/transform.hh>
 #include <nv/interface/mesh_data.hh>
Index: trunk/nv/formats/nmd_loader.hh
===================================================================
--- trunk/nv/formats/nmd_loader.hh	(revision 391)
+++ trunk/nv/formats/nmd_loader.hh	(revision 392)
@@ -11,4 +11,5 @@
 #include <nv/interface/mesh_loader.hh>
 #include <nv/interface/mesh_data.hh>
+#include <nv/stl/vector.hh>
 #include <nv/io/string_table.hh>
 
@@ -86,7 +87,7 @@
 		mesh_node_data*           m_node_array;
 		string_table*             m_strings;
-		std::vector< uint16 >     m_mesh_names;
-		std::vector< uint16 >     m_node_names;
-		std::vector< mesh_data* > m_meshes;
+		vector< uint16 >          m_mesh_names;
+		vector< uint16 >          m_node_names;
+		vector< mesh_data* >      m_meshes;
 	};
 
Index: trunk/nv/formats/obj_loader.hh
===================================================================
--- trunk/nv/formats/obj_loader.hh	(revision 391)
+++ trunk/nv/formats/obj_loader.hh	(revision 392)
@@ -17,4 +17,5 @@
 #include <nv/interface/mesh_loader.hh>
 #include <nv/interface/mesh_data.hh>
+#include <nv/stl/vector.hh>
 
 namespace nv 
Index: trunk/nv/gfx/animation.hh
===================================================================
--- trunk/nv/gfx/animation.hh	(revision 391)
+++ trunk/nv/gfx/animation.hh	(revision 392)
@@ -9,5 +9,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/stl/array.hh>
+#include <nv/stl/vector.hh>
 #include <nv/interface/stream.hh>
 #include <nv/stl/math.hh>
@@ -198,5 +198,5 @@
 	private:
 		key_descriptor m_final_key;
-		std::vector< key_raw_channel* > m_channels;
+		vector< key_raw_channel* > m_channels;
 	};
 
Index: trunk/nv/gfx/debug_draw.hh
===================================================================
--- trunk/nv/gfx/debug_draw.hh	(revision 391)
+++ trunk/nv/gfx/debug_draw.hh	(revision 392)
@@ -10,4 +10,5 @@
 #include <nv/core/common.hh>
 #include <nv/stl/math.hh>
+#include <nv/stl/vector.hh>
 #include <nv/interface/context.hh>
 
@@ -37,8 +38,8 @@
 		~debug_data();
 	private:
-		context*                 m_context;
-		program                  m_program;
-		vertex_array             m_va;
-		std::vector< debug_vtx > m_data;
+		context*            m_context;
+		program             m_program;
+		vertex_array        m_va;
+		vector< debug_vtx > m_data;
 	};
 
Index: trunk/nv/gfx/skeletal_mesh.hh
===================================================================
--- trunk/nv/gfx/skeletal_mesh.hh	(revision 391)
+++ trunk/nv/gfx/skeletal_mesh.hh	(revision 392)
@@ -90,5 +90,5 @@
 	protected:
 		const mesh_nodes_data* m_node_data;
-		std::vector< uint32 >* m_children;
+		vector< uint32 >* m_children;
 		sint16* m_bone_ids;
 		mat4* m_offsets;
Index: trunk/nv/gfx/sliced_buffer.hh
===================================================================
--- trunk/nv/gfx/sliced_buffer.hh	(revision 391)
+++ trunk/nv/gfx/sliced_buffer.hh	(revision 392)
@@ -13,4 +13,5 @@
 #include <nv/core/common.hh>
 #include <nv/stl/math.hh>
+#include <vector> // TODO: remove
 
 namespace nv
@@ -23,8 +24,9 @@
 	{
 	public:
-		typedef sliced_buffer<T> cache;
-		typedef std::vector<T>  vector;
-
-		buffer_slice( cache* c ) 
+		typedef sliced_buffer<T> cache_type;
+		typedef std::vector<T>   vector_type;
+		typedef size_t           size_type;
+
+		buffer_slice( cache_type* c ) 
 			: m_cache( c ), m_offset( 0 ), m_cached_size( 0 ), m_locked( true )
 		{
@@ -63,10 +65,10 @@
 		}
 
-		vector& lock()
+		vector_type& lock()
 		{
 			m_locked = true;
 			return m_data;
 		}
-		const vector& data() 
+		const vector_type& data() 
 		{ 
 			return m_data; 
@@ -77,9 +79,9 @@
 		}
 	public:
-		vector m_data;
-		cache* m_cache;
-		size_t m_offset;
-		size_t m_cached_size;
-		bool   m_locked;
+		vector_type m_data;
+		cache_type* m_cache;
+		size_type   m_offset;
+		size_type   m_cached_size;
+		bool        m_locked;
 	};
 
@@ -88,5 +90,5 @@
 	{
 	public:
-		typedef std::vector<T>  vector;
+		typedef std::vector<T>  vector_type;
 		typedef T               value_type;
 		static const size_t value_type_size = sizeof(T);
@@ -106,5 +108,5 @@
 		}
 
-		bool commit( const vector& bv, bool updated, bool resized, size_t& offset )
+		bool commit( const vector_type& bv, bool updated, bool resized, size_t& offset )
 		{
 			if ( !m_full_update && resized )
@@ -121,5 +123,6 @@
 			else if ( updated )
 			{
-				std::copy( bv.cbegin(), bv.cend(), m_data.begin() + (int)offset );
+//				raw_copy( bv.cbegin(), bv.cend(), m_data.begin() + (int)offset );
+				raw_copy( bv.data(), bv.data() + bv.size(), m_data.data() + (int)offset );
 				m_min = nv::min<size_t>( m_min, offset );
 				m_max = nv::max<size_t>( m_max, offset + bv.size() );
@@ -208,5 +211,5 @@
 		buffer_hint m_hint;
 		bool        m_full_update;
-		vector      m_data;
+		vector_type m_data;
 		uint32      m_capacity;
 
@@ -224,6 +227,6 @@
 		typedef buffer_slice<T> vertex_slice;
 		typedef buffer_slice<I> index_slice;
-		typedef typename vertex_slice::vector vertex_vector;
-		typedef typename index_slice::vector  index_vector;
+		typedef typename vertex_slice::vector_type vertex_vector;
+		typedef typename index_slice::vector_type  index_vector;
 
 		indexed_buffer_slice( cache* c )
Index: trunk/nv/gui/gui_environment.hh
===================================================================
--- trunk/nv/gui/gui_environment.hh	(revision 391)
+++ trunk/nv/gui/gui_environment.hh	(revision 392)
@@ -19,5 +19,4 @@
 #include <nv/core/io_event.hh>
 #include <nv/interface/window.hh>
-#include <nv/stl/array.hh>
 
 namespace nv
Index: trunk/nv/interface/audio.hh
===================================================================
--- trunk/nv/interface/audio.hh	(revision 391)
+++ trunk/nv/interface/audio.hh	(revision 392)
@@ -14,4 +14,5 @@
 
 #include <nv/core/common.hh>
+#include <nv/stl/string.hh>
 #include <nv/stl/math.hh>
 #include <nv/stl/handle.hh>
@@ -31,5 +32,5 @@
 		virtual channel play_sound( sound a_sound, vec3 position ) = 0;
 		// temporary - use streams later
-		virtual sound load_sound( const std::string& a_path ) = 0;
+		virtual sound load_sound( const string_ref& a_path ) = 0;
 		virtual void release( sound a_sound ) = 0;
 		virtual void set_orientation( vec3 forward, vec3 up ) = 0;
Index: trunk/nv/interface/context.hh
===================================================================
--- trunk/nv/interface/context.hh	(revision 391)
+++ trunk/nv/interface/context.hh	(revision 392)
@@ -124,10 +124,10 @@
 
 		template < typename VTX, slot SLOT >
-		void add_vertex_buffer_impl( vertex_array, buffer, const std::false_type& )
+		void add_vertex_buffer_impl( vertex_array, buffer, const false_type& )
 		{
 		}
 
 		template < typename VTX, slot SLOT >
-		void add_vertex_buffer_impl( vertex_array va, buffer vb, const std::true_type& )
+		void add_vertex_buffer_impl( vertex_array va, buffer vb, const true_type& )
 		{
 			typedef vertex_slot_info< VTX, SLOT > vinfo;
@@ -139,5 +139,5 @@
 		void add_vertex_buffer( vertex_array va, buffer vb )
 		{
-			add_vertex_buffer_impl< VTX, SLOT >( va, vb, std::integral_constant< bool, vertex_has_slot< VTX, SLOT >::value >() );
+			add_vertex_buffer_impl< VTX, SLOT >( va, vb, bool_constant< vertex_has_slot< VTX, SLOT >::value >() );
 		}
 
@@ -164,4 +164,18 @@
 		}
 
+		template < typename VTXDATA >
+		enable_if_t< is_class< VTXDATA >::value, vertex_array >
+		create_vertex_array( const VTXDATA& data, buffer_hint hint )
+		{
+			return create_vertex_array( data.data(), data.size(), hint );
+		}
+
+		template < typename VTXDATA, typename IDXDATA >
+		enable_if_t< is_class< VTXDATA >::value && is_class< IDXDATA >::value, vertex_array >
+		create_vertex_array( const VTXDATA& data, const IDXDATA& idata, buffer_hint hint )
+		{
+			return create_vertex_array( data.data(), data.size(), idata.data(), idata.size(), hint );
+		}
+
 		template < typename VTX >
 		vertex_array create_vertex_array( const VTX* v, size_t count, buffer_hint hint )
@@ -174,10 +188,4 @@
 		}
 
-		template < typename VTX >
-		vertex_array create_vertex_array( const std::vector< VTX >& data, buffer_hint hint )
-		{
-			return create_vertex_array( data.data(), data.size(), hint );
-		}
-
 		template < typename VTX, typename IDX >
 		vertex_array create_vertex_array( const VTX* v, size_t vcount, const IDX* i, size_t icount, buffer_hint hint )
@@ -187,10 +195,4 @@
 			set_index_buffer( va, ib, type_to_enum< IDX >::type, true );
 			return va;
-		}
-
-		template < typename VTX, typename IDX >
-		vertex_array create_vertex_array( const std::vector< VTX >& data, const std::vector< IDX >& idata, buffer_hint hint )
-		{
-			return create_vertex_array( data.data(), data.size(), idata.data(), idata.size(), hint );
 		}
 
Index: trunk/nv/interface/device.hh
===================================================================
--- trunk/nv/interface/device.hh	(revision 391)
+++ trunk/nv/interface/device.hh	(revision 392)
@@ -73,5 +73,5 @@
 	};
 
-	typedef std::unordered_map< std::string, attribute >    attribute_map;
+	typedef unordered_map< std::string, attribute >    attribute_map;
 
 	struct texture_tag {};
@@ -143,7 +143,7 @@
 	struct program_info
 	{
-		attribute_map       m_attribute_map;
-		uniform_map	        m_uniform_map;
-		engine_uniform_list m_engine_uniforms;
+		attribute_map*       m_attribute_map;
+		uniform_map*	     m_uniform_map;
+		engine_uniform_list* m_engine_uniforms;
 	};
 
@@ -204,5 +204,5 @@
 
 		template < typename T >
-		void set_opt_uniform_array( program p, const std::string& name, const std::vector<T>& value )
+		void set_opt_uniform_array( program p, const std::string& name, const const_array_ref<T>& value )
 		{
 			set_uniform_array( p, name, (const T*)value.data(), value.size(), false );
Index: trunk/nv/interface/map_area.hh
===================================================================
--- trunk/nv/interface/map_area.hh	(revision 391)
+++ trunk/nv/interface/map_area.hh	(revision 392)
@@ -16,5 +16,4 @@
 #include <nv/core/position.hh>
 #include <nv/stl/string.hh>
-#include <nv/stl/array.hh>
 #include <string>
 
Index: trunk/nv/interface/mesh_data.hh
===================================================================
--- trunk/nv/interface/mesh_data.hh	(revision 391)
+++ trunk/nv/interface/mesh_data.hh	(revision 392)
@@ -11,5 +11,4 @@
 #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 391)
+++ trunk/nv/interface/mesh_loader.hh	(revision 392)
@@ -15,6 +15,4 @@
 
 #include <nv/core/common.hh>
-#include <nv/stl/array.hh>
-#include <unordered_map>
 #include <nv/core/transform.hh>
 #include <nv/stl/string.hh>
Index: trunk/nv/interface/scene_node.hh
===================================================================
--- trunk/nv/interface/scene_node.hh	(revision 391)
+++ trunk/nv/interface/scene_node.hh	(revision 392)
@@ -14,5 +14,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/stl/array.hh>
+#include <nv/stl/vector.hh>
 #include <nv/core/transform.hh>
 #include <nv/stl/math.hh>
@@ -25,5 +25,5 @@
 	{
 	public:
-		typedef std::vector< scene_node* > list;
+		typedef vector< scene_node* > list;
 		
 		scene_node() {}
Index: trunk/nv/interface/uniform.hh
===================================================================
--- trunk/nv/interface/uniform.hh	(revision 391)
+++ trunk/nv/interface/uniform.hh	(revision 392)
@@ -16,6 +16,5 @@
 #include <nv/core/common.hh>
 #include <nv/stl/string.hh>
-#include <unordered_map>
-#include <string>
+#include <nv/stl/unordered_map.hh>
 
 namespace nv
@@ -149,8 +148,9 @@
 	};
 
-	typedef std::unordered_map< std::string, uniform_base* >                uniform_map;
-	typedef std::vector< engine_uniform_base* >                        engine_uniform_list;
-	typedef std::unordered_map< std::string, engine_uniform_factory_base* > engine_uniform_factory_map;
-	typedef std::unordered_map< std::string, engine_link_uniform_base* >    engine_link_uniform_factory_map;
+	typedef nv::unordered_map< std::string, uniform_base* >                uniform_map;
+	typedef nv::vector< engine_uniform_base* >                        engine_uniform_list;
+	// TODO - change to literal type map
+	typedef nv::unordered_map< string_ref, engine_uniform_factory_base* > engine_uniform_factory_map;
+	typedef nv::unordered_map< string_ref, engine_link_uniform_base* >    engine_link_uniform_factory_map;
 
 	class engine_uniform_m_view : public engine_uniform< mat4 >
Index: trunk/nv/io/string_table.hh
===================================================================
--- trunk/nv/io/string_table.hh	(revision 391)
+++ trunk/nv/io/string_table.hh	(revision 392)
@@ -14,6 +14,7 @@
 
 #include <nv/core/common.hh>
-#include <nv/stl/array.hh>
-#include <unordered_map>
+#include <nv/stl/vector.hh>
+#include <nv/stl/string.hh>
+#include <nv/stl/unordered_map.hh>
 #include <nv/interface/stream.hh>
 
@@ -86,7 +87,7 @@
 		void clear();
 	private:
-		std::unordered_map< std::string, index > m_map;
-		std::vector< offset > m_offsets;
-		std::vector< char >   m_data;
+		unordered_map< std::string, index > m_map;
+		vector< offset > m_offsets;
+		vector< char >   m_data;
 	};
 
Index: trunk/nv/lua/lua_raw.hh
===================================================================
--- trunk/nv/lua/lua_raw.hh	(revision 391)
+++ trunk/nv/lua/lua_raw.hh	(revision 392)
@@ -8,6 +8,7 @@
 
 #include <nv/core/common.hh>
-#include <nv/stl/array.hh>
+#include <nv/stl/vector.hh>
 #include <nv/lib/lua.hh>
+#include <string>
 
 void nlua_toflags_set( lua_State *L, int index, nv::uint8* data, nv::uint32 count );
Index: trunk/nv/sdl/sdl_audio.hh
===================================================================
--- trunk/nv/sdl/sdl_audio.hh	(revision 391)
+++ trunk/nv/sdl/sdl_audio.hh	(revision 392)
@@ -32,5 +32,5 @@
 			virtual channel play_sound( sound a_sound, float volume = 1.0f, float pan = 0.0f );
 			virtual channel play_sound( sound a_sound, vec3 position );
-			virtual sound load_sound( const std::string& a_path );
+			virtual sound load_sound( const string_ref& a_path );
 			virtual void release( sound a_sound );
 			virtual void set_orientation( vec3 forward, vec3 up );
Index: trunk/nv/stl/cstring_store.hh
===================================================================
--- trunk/nv/stl/cstring_store.hh	(revision 391)
+++ trunk/nv/stl/cstring_store.hh	(revision 392)
@@ -15,7 +15,7 @@
 
 #include <nv/core/common.hh>
+#include <nv/stl/unordered_map.hh>
 #include <nv/stl/array.hh>
 #include <nv/stl/capi.hh>
-#include <unordered_map>
 
 namespace nv
@@ -59,5 +59,5 @@
 
 	template < typename T >
-	using cstring_unordered_map = std::unordered_map < const char*, T, detail::cstring_hash, detail::cstring_compare > ;
+	using cstring_unordered_map = unordered_map < const char*, T, detail::cstring_hash, detail::cstring_compare > ;
 
 	class cstring_store : public noncopyable
@@ -112,5 +112,5 @@
 		}
 	private:
-		std::vector< char* >            m_array;
+		vector< char* >                 m_array;
 		cstring_unordered_map< uint32 > m_map;
 	};
Index: trunk/nv/stl/handle.hh
===================================================================
--- trunk/nv/stl/handle.hh	(revision 391)
+++ trunk/nv/stl/handle.hh	(revision 392)
@@ -14,5 +14,5 @@
 
 #include <nv/core/common.hh>
-#include <nv/stl/array.hh>
+#include <nv/stl/vector.hh>
 
 namespace nv
Index: trunk/nv/stl/string.hh
===================================================================
--- trunk/nv/stl/string.hh	(revision 391)
+++ trunk/nv/stl/string.hh	(revision 392)
@@ -28,4 +28,5 @@
 #include <nv/stl/exception.hh>
 #include <nv/stl/algorithm.hh>
+#include <nv/stl/functional/hash.hh>
 
 namespace nv
@@ -37,4 +38,14 @@
 // 	string64
 // 	string
+
+	template<>
+	struct hash< std::string, size_t >
+	{
+		static size_t get( const std::string& value )
+		{
+			return hash_string< size_t >( value.c_str(), value.length() );
+		}
+		inline size_t operator()( const std::string& value ) const { return get( value ); }
+	};
 
 
@@ -188,15 +199,5 @@
 		inline size_t hash() const
 		{
-			const char* str = data();
-			size_type   sz  = size();
-			int seed = 131;
-			int result = 0;
-			while ( sz )
-			{
-				result = ( result * seed ) + ( *str );
-				str++;
-				sz--;
-			}
-			return result & ( 0x7FFFFFFF );
+			return hash_string< size_t >( data(), size() );
 		}
 
@@ -217,4 +218,28 @@
 		}
 	};
+
+	template< typename H >
+	struct hash< string_base, H >
+	{
+		static H get( const string_base& value )
+		{
+			return hash_string< H >( value.data(), value.length() );
+		}
+		inline H operator()( const string_base& value ) const { return get( value ); }
+	};
+
+	class literal_string : public string_base
+	{
+	public:
+		// Literal constructors
+		template< size_t N >
+		inline literal_string( char( &s )[N] ) : string_base( s, N - 1 ) {}
+		template< size_t N >
+		inline literal_string( const char( &s )[N] ) : string_base( s, N - 1 ) {}
+	};
+
+	template< typename H >
+	struct hash< literal_string, H > : hash< string_base, H >{};
+
 
 	class string_ref : public string_base
@@ -280,4 +305,7 @@
 
 	};
+
+	template< typename H >
+	struct hash< string_ref, H > : hash< string_base, H >{};
 
 	// const string is movable but not copyable
Index: trunk/nv/stl/type_traits/common.hh
===================================================================
--- trunk/nv/stl/type_traits/common.hh	(revision 391)
+++ trunk/nv/stl/type_traits/common.hh	(revision 392)
@@ -185,5 +185,5 @@
 
 	template < typename T >
-	constexpr T&& forward( typename remove_reference<T>::type& t )
+	constexpr T&& forward( typename remove_reference<T>::type& t ) noexcept
 	{
 		return static_cast<T&&>( t );
Index: trunk/src/fmod/fmod_audio.cc
===================================================================
--- trunk/src/fmod/fmod_audio.cc	(revision 391)
+++ trunk/src/fmod/fmod_audio.cc	(revision 392)
@@ -88,9 +88,9 @@
 
 
-nv::sound fmod::audio::load_sound( const std::string& a_path )
+nv::sound fmod::audio::load_sound( const string_ref& a_path )
 {
 	FMOD_SYSTEM* system = (FMOD_SYSTEM*)m_system;
 	FMOD_SOUND* sample;
-	FMOD_RESULT fm_result = FMOD_System_CreateSound( system, a_path.c_str(), FMOD_3D, 0, &sample );
+	FMOD_RESULT fm_result = FMOD_System_CreateSound( system, a_path.data(), FMOD_3D, 0, &sample );
 	if ( fm_result != FMOD_OK )
 	{
Index: trunk/src/formats/assimp_loader.cc
===================================================================
--- trunk/src/formats/assimp_loader.cc	(revision 391)
+++ trunk/src/formats/assimp_loader.cc	(revision 392)
@@ -6,6 +6,5 @@
 
 #include "nv/formats/assimp_loader.hh"
-#include <unordered_map>
-#include "nv/io/std_stream.hh"
+#include "nv/stl/unordered_map.hh"
 #include "nv/gfx/mesh_creator.hh"
 #include "nv/lib/assimp.hh"
@@ -286,5 +285,5 @@
 	const aiScene* scene = (const aiScene*)m_scene;
 	vector< mesh_node_data > final_bones;
-	std::unordered_map< std::string, uint16 > names;
+	unordered_map< std::string, uint16 > names;
 	for ( unsigned int m = 0; m < m_mesh_count; ++m )
 	{
@@ -334,5 +333,5 @@
 	}
 	mesh_node_data* bones = new mesh_node_data[ final_bones.size() ];
-	nv::raw_copy( final_bones.begin(), final_bones.end(), bones );
+	raw_copy( final_bones.begin(), final_bones.end(), bones );
 	return new mesh_nodes_data( "bones", final_bones.size(), bones );
 }
Index: trunk/src/formats/md5_loader.cc
===================================================================
--- trunk/src/formats/md5_loader.cc	(revision 391)
+++ trunk/src/formats/md5_loader.cc	(revision 392)
@@ -6,4 +6,5 @@
 
 #include "nv/core/logging.hh"
+#include "nv/stl/vector.hh"
 #include "nv/io/std_stream.hh"
 
Index: trunk/src/gfx/skeletal_mesh.cc
===================================================================
--- trunk/src/gfx/skeletal_mesh.cc	(revision 391)
+++ trunk/src/gfx/skeletal_mesh.cc	(revision 392)
@@ -7,4 +7,5 @@
 #include "nv/interface/context.hh"
 #include "nv/interface/device.hh"
+#include "nv/stl/unordered_map.hh"
 
 nv::skeletal_mesh_cpu::skeletal_mesh_cpu( context* a_context, const mesh_data* a_mesh_data, const mesh_nodes_data* bones )
@@ -89,5 +90,5 @@
 	if ( !m_node_data->is_flat() )
 	{
-		m_children = new std::vector< uint32 >[ node_count ];
+		m_children = new vector< uint32 >[ node_count ];
 		for ( uint32 n = 0; n < node_count; ++n )
 		{
@@ -132,5 +133,5 @@
 {
 	if ( m_prepared ) return;
-	std::unordered_map< std::string, nv::uint16 > bone_names;
+	unordered_map< std::string, nv::uint16 > bone_names;
 	m_offsets = new mat4[ bones->get_count() ];
 	for ( nv::uint16 bi = 0; bi < bones->get_count(); ++bi )
Index: trunk/src/gl/gl_context.cc
===================================================================
--- trunk/src/gl/gl_context.cc	(revision 391)
+++ trunk/src/gl/gl_context.cc	(revision 392)
@@ -713,5 +713,5 @@
 	if ( info )
 	{
-		for ( auto u : info->m_engine_uniforms )
+		for ( auto& u : *info->m_engine_uniforms )
 		{
 			u->set( this, &s );
Index: trunk/src/gl/gl_device.cc
===================================================================
--- trunk/src/gl/gl_device.cc	(revision 391)
+++ trunk/src/gl/gl_device.cc	(revision 392)
@@ -17,7 +17,7 @@
 	m_shader_header  = "#version 120\n";
 	for ( auto& i : get_uniform_factory() ) 
-		m_shader_header += "uniform "+datatype_to_glsl_type( i.second->get_datatype() )+" "+i.first+";\n";
+		m_shader_header += "uniform "+datatype_to_glsl_type( i.second->get_datatype() )+" "+ i.first.to_string() +";\n";
 	for ( auto& i : get_link_uniform_factory() ) 
-		m_shader_header += "uniform sampler2D "+i.first+";\n";
+		m_shader_header += "uniform sampler2D "+i.first.to_string() +";\n";
 }
 
@@ -26,4 +26,8 @@
 	program result = m_programs.create();
 	gl_program_info* info = m_programs.get( result );
+
+	info->m_attribute_map   = new attribute_map;
+	info->m_engine_uniforms = new engine_uniform_list;
+	info->m_uniform_map     = new uniform_map;
 
 	info->glid = glCreateProgram();
@@ -179,5 +183,5 @@
 	if ( info )
 	{
-		for ( auto& i : info->m_uniform_map )
+		for ( auto& i : *info->m_uniform_map )
 			delete i.second;
 
@@ -188,4 +192,8 @@
 		glDeleteProgram( info->glid );
 
+		delete info->m_attribute_map;
+		delete info->m_engine_uniforms;
+		delete info->m_uniform_map;
+
 		m_programs.destroy( p );
 	}
@@ -200,5 +208,5 @@
 		auto& lmap = get_link_uniform_factory();
 
-		for ( auto& i : info->m_uniform_map )
+		for ( auto& i : *info->m_uniform_map )
 		{
 			auto j = lmap.find( i.first );
@@ -211,5 +219,5 @@
 			if ( k != map.end() )
 			{
-				info->m_engine_uniforms.push_back( k->second->create( i.second ) );
+				info->m_engine_uniforms->push_back( k->second->create( i.second ) );
 			}				
 		}
@@ -221,6 +229,6 @@
 	const gl_program_info* info = m_programs.get( p );
 	{
-		nv::uniform_map::const_iterator i = info->m_uniform_map.find( name );
-		if ( i != info->m_uniform_map.end() )
+		nv::uniform_map::const_iterator i = info->m_uniform_map->find( name );
+		if ( i != info->m_uniform_map->end() )
 		{
 			return i->second;
@@ -240,6 +248,6 @@
 	if ( info )
 	{
-		attribute_map::const_iterator i = info->m_attribute_map.find( name );
-		if ( i != info->m_attribute_map.end() )
+		attribute_map::const_iterator i = info->m_attribute_map->find( name );
+		if ( i != info->m_attribute_map->end() )
 		{
 			return i->second.location;
@@ -307,7 +315,7 @@
 void nv::gl_device::update_uniforms( gl_program_info* p )
 {
-	for ( uniform_map::iterator i = p->m_uniform_map.begin(); 	i != p->m_uniform_map.end(); ++i ) 
-	{
-		uniform_base* ubase = i->second;
+	for ( auto& i : *p->m_uniform_map )
+	{
+		uniform_base* ubase = i.second;
 		if ( ubase->is_dirty() )
 		{
@@ -354,5 +362,5 @@
 		int attr_loc = glGetAttribLocation( p->glid, name.c_str() );
 
-		attribute& attr = p->m_attribute_map[ name ];
+		attribute& attr = (*p->m_attribute_map)[ name ];
 		attr.name     = name;
 		attr.location = attr_loc;
@@ -393,5 +401,5 @@
 		uniform_base* u = uniform_base::create( utype, name, uni_loc, uni_len );
 		NV_ASSERT( u, "Unknown uniform type!" );
-		p->m_uniform_map[ name ] = u;
+		(*p->m_uniform_map)[ name ] = u;
 	}
 }
Index: trunk/src/gui/gui_environment.cc
===================================================================
--- trunk/src/gui/gui_environment.cc	(revision 391)
+++ trunk/src/gui/gui_environment.cc	(revision 392)
@@ -14,5 +14,5 @@
 	TODO: parse a lua stylesheet as per Trac wiki
 
-	IDEA: Store everything in std::unordered_maps, with lua_value's?
+	IDEA: Store everything in unordered_maps, with lua_value's?
 
 	A lua_value is a variant stores strings as const char* that deletes them on destructor?
Index: trunk/src/io/string_table.cc
===================================================================
--- trunk/src/io/string_table.cc	(revision 391)
+++ trunk/src/io/string_table.cc	(revision 392)
@@ -6,5 +6,4 @@
 
 #include "nv/io/string_table.hh"
-#include <array>
 
 nv::string_table_creator::string_table_creator()
@@ -24,6 +23,8 @@
 	NV_ASSERT( m_offsets.size() < index(-1), "Too many strings!" );
 	index  result  = (index)m_offsets.size();
-	m_offsets.push_back( m_data.size() );
-	std::copy( cs, cs + cs_size, std::back_inserter( m_data ) );
+	size_t dsize = m_data.size();
+	m_offsets.push_back( dsize );
+	m_data.resize( dsize + cs_size );
+	raw_copy( cs, cs + cs_size, m_data.data() + dsize );
 	m_map[ s ] = result;
 	return result;
@@ -34,6 +35,6 @@
 	offset* offsets = new offset[m_offsets.size()];
 	char*   data    = new char [m_data.size()];
-	std::copy( m_offsets.begin(), m_offsets.end(), offsets );
-	std::copy( m_data.begin(),    m_data.end(),    data );
+	raw_copy( m_offsets.begin(), m_offsets.end(), offsets );
+	raw_copy( m_data.begin(),    m_data.end(),    data );
 	return new string_table( data, m_data.size(), offsets, (index)m_offsets.size() );
 }
Index: trunk/src/sdl/sdl_audio.cc
===================================================================
--- trunk/src/sdl/sdl_audio.cc	(revision 391)
+++ trunk/src/sdl/sdl_audio.cc	(revision 392)
@@ -85,5 +85,5 @@
 }
 
-nv::sound nv::sdl::audio::load_sound( const std::string& a_path )
+nv::sound nv::sdl::audio::load_sound( const string_ref& a_path )
 {
 	// TODO: this is a really weird error - if we remove this check, all hell gets loose
@@ -92,5 +92,5 @@
 		NV_LOG_ERROR( "SDL_mixer not loaded!" );
 	}
-	Mix_Chunk *sample = Mix_LoadWAV_RW(SDL_RWFromFile(a_path.c_str(), "rb"), 1);
+	Mix_Chunk *sample = Mix_LoadWAV_RW(SDL_RWFromFile(a_path.data(), "rb"), 1);
 	if ( sample == nullptr )
 	{
