Index: /trunk/nv/lua/lua_area.hh
===================================================================
--- /trunk/nv/lua/lua_area.hh	(revision 448)
+++ /trunk/nv/lua/lua_area.hh	(revision 449)
@@ -20,11 +20,16 @@
 		void register_area( lua_State* L );
 
+		template<>
+		struct pass_traits< rectangle > : metatable_pass_traits< rectangle >
+		{
+			static const char* metatable() { return "area"; }
+		};
+
 		namespace detail
 		{
-			extern const char* AREA_METATABLE;
-			inline bool is_area( lua_State* L, int index ) { return is_userdata( L, index, AREA_METATABLE ); }
-			inline rectangle to_area( lua_State* L, int index ) { return *reinterpret_cast<rectangle*>( check_userdata( L, index, AREA_METATABLE ) ); }
-			inline rectangle* to_parea( lua_State* L, int index ) { return reinterpret_cast<rectangle*>( check_userdata( L, index, AREA_METATABLE ) ); }
-			inline void push_area( lua_State* L, const rectangle& v ) { push_userdata( L, v, AREA_METATABLE ); }
+			inline bool is_area( lua_State* L, int index ) { return is_userdata( L, index, pass_traits<rectangle>::metatable() ); }
+			inline rectangle to_area( lua_State* L, int index ) { return pass_traits<rectangle>::to( L, index ); }
+			inline rectangle* to_parea( lua_State* L, int index ) { return to_userdata<rectangle>( L, index ); }
+			inline void push_area( lua_State* L, const rectangle& v ) { pass_traits<rectangle>::push( L, v ); }
 
 			inline bool is_coord( lua_State* L, int index ) { return is_vec<ivec2>( L, index ); }
@@ -32,13 +37,6 @@
 			inline ivec2* to_pcoord( lua_State* L, int index ) { return to_pvec<ivec2>( L, index ); }
 			inline void push_coord( lua_State* L, const ivec2& v ) { push_vec<ivec2>( L, v ); }
-
 		}
 
-		template<>
-		struct pass_traits< rectangle >
-		{
-			static void push( lua_State *L, const rectangle& p ) { detail::push_area( L, p ); }
-			static rectangle to( lua_State *L, int index ) { return detail::to_area( L, index ); }
-		};
 	}
 
Index: /trunk/nv/lua/lua_dispatch.hh
===================================================================
--- /trunk/nv/lua/lua_dispatch.hh	(revision 448)
+++ /trunk/nv/lua/lua_dispatch.hh	(revision 449)
@@ -19,5 +19,4 @@
 	namespace lua
 	{
-		typedef int (__cdecl *lfunction) (struct lua_State *L);
 
 		namespace detail
Index: /trunk/nv/lua/lua_glm.hh
===================================================================
--- /trunk/nv/lua/lua_glm.hh	(revision 448)
+++ /trunk/nv/lua/lua_glm.hh	(revision 449)
@@ -18,18 +18,17 @@
 		void register_glm( lua_State* L );
 
+		template<> struct pass_traits< vec2 >  : metatable_pass_traits< vec2 >  { static const char* metatable() { return "vec2"; } };
+		template<> struct pass_traits< vec3 >  : metatable_pass_traits< vec3 >  { static const char* metatable() { return "vec3"; } };
+		template<> struct pass_traits< vec4 >  : metatable_pass_traits< vec4 >  { static const char* metatable() { return "vec4"; } };
+		template<> struct pass_traits< ivec2 > : metatable_pass_traits< ivec2 > { static const char* metatable() { return "ivec2"; } };
+		template<> struct pass_traits< ivec3 > : metatable_pass_traits< ivec3 > { static const char* metatable() { return "ivec2"; } };
+		template<> struct pass_traits< ivec4 > : metatable_pass_traits< ivec4 > { static const char* metatable() { return "ivec2"; } };
+
 		namespace detail
 		{
-			template< typename T > inline const char* glm_metatable_name() { static_assert(sizeof(T) == 0, "Type not implemented!"); return NULL; }
-			template<> inline const char* glm_metatable_name< nv::ivec2 >() { return "ivec2"; }
-			template<> inline const char* glm_metatable_name< nv::ivec3 >() { return "ivec3"; }
-			template<> inline const char* glm_metatable_name< nv::ivec4 >() { return "ivec4"; }
-			template<> inline const char* glm_metatable_name< nv::vec2  >() { return "vec2"; }
-			template<> inline const char* glm_metatable_name< nv::vec3  >() { return "vec3"; }
-			template<> inline const char* glm_metatable_name< nv::vec4  >() { return "vec4"; }
-
 			template< typename T >
 			bool is_vec( lua_State* L, int index )
 			{
-				return is_userdata( L, index, detail::glm_metatable_name<T>() );
+				return is_userdata( L, index, pass_traits<T>::metatable() );
 			}
 
@@ -37,5 +36,5 @@
 			T to_vec( lua_State* L, int index )
 			{
-				return *reinterpret_cast<T*>( check_userdata( L, index, detail::glm_metatable_name<T>() ) );
+				return pass_traits<T>::to( L, index );
 			}
 
@@ -43,5 +42,5 @@
 			T to_vec( lua_State* L, int index, const T& def )
 			{
-				return ( is_vec<T>( L, index ) ? *reinterpret_cast<T*>( to_pointer( L, index ) ) : def );
+				return pass_traits<T>::to( L, index, def );
 			}
 
@@ -49,5 +48,5 @@
 			T* to_pvec( lua_State* L, int index )
 			{
-				return reinterpret_cast<T*>( check_userdata( L, index, detail::glm_metatable_name<T>() ) );
+				return to_userdata<T>( L, index );
 			}
 
@@ -55,34 +54,9 @@
 			void push_vec( lua_State* L, const T& v )
 			{
-				push_userdata( L, v, detail::glm_metatable_name<T>() );
+				pass_traits<T>::push( L, v );
 			}
+
 		}
 
-		template< typename T >
-		struct pass_traits< tvec2<T> >
-		{
-			typedef tvec2<T> value_type;
-			static void push( lua_State *L, const value_type& p ) { detail::push_vec< value_type >( L, p ); }
-			static value_type to( lua_State *L, int index ) { return detail::to_vec< value_type >( L, index ); }
-			static value_type to( lua_State *L, int index, const value_type& def ) { return detail::to_vec< value_type >( L, index, def ); }
-		};
-
-		template< typename T >
-		struct pass_traits< tvec3<T> >
-		{
-			typedef tvec3<T> value_type;
-			static void push( lua_State *L, const value_type& p ) { detail::push_vec< value_type >( L, p ); }
-			static value_type to( lua_State *L, int index ) { return detail::to_vec< value_type >( L, index ); }
-			static value_type to( lua_State *L, int index, const value_type& def ) { return detail::to_vec< value_type >( L, index, def ); }
-		};
-
-		template< typename T >
-		struct pass_traits< tvec4<T> >
-		{
-			typedef tvec4<T> value_type;
-			static void push( lua_State *L, const value_type& p ) { detail::push_vec< value_type >( L, p ); }
-			static value_type to( lua_State *L, int index ) { return detail::to_vec< value_type >( L, index ); }
-			static value_type to( lua_State *L, int index, const value_type& def ) { return detail::to_vec< value_type >( L, index, def ); }
-		};
 	}
 
Index: /trunk/nv/lua/lua_values.hh
===================================================================
--- /trunk/nv/lua/lua_values.hh	(revision 448)
+++ /trunk/nv/lua/lua_values.hh	(revision 449)
@@ -35,32 +35,9 @@
 		typedef unsigned long lunsigned;
 		typedef double        lnumber;
-
-//  		struct passer
-// 		{
-// 			virtual void push( lua_State *L ) const = 0;
-// 			virtual ~passer(){}
-// 		};
-// 
-// 		template < typename T >
-// 		struct returner
-// 		{
-// 			returner( lua_State *, int ) : value() {}
-// 			returner( lua_State *, int, const T& ) : value() {}
-// 			operator T() { return value; }
-// 			operator const T() const { return value; }
-// 			virtual returner<T> to( lua_State *L, int index ) = 0;
-// 			virtual returner<T> to( lua_State *L, int index, const T& def ) = 0;
-// 			virtual ~returner(){}
-// 		protected:
-// 			T value;
-// 		};
-
-		template < typename T >
-		struct pass_traits
-		{
-			static void push( lua_State *L, const T& p ) { p.push( L ); }
-			static T to( lua_State *L, int index ) { return T( L, index ); }
-			static T to( lua_State *L, int index, const T& def ) { return T( L, index, def ); }
-		};
+		typedef int( __cdecl *lfunction ) ( struct lua_State *L );
+
+
+		template < typename T, class Enable = void >
+		struct pass_traits;
 
 		namespace detail
@@ -74,5 +51,4 @@
 			void push_bool       ( lua_State *L, bool v );
 			void push_string_view( lua_State *L, string_view s );
-			void push_cstring    ( lua_State *L, const char* s );
 			void push_pointer    ( lua_State *L, void* p );
 			void push_ref_object ( lua_State *L, ref object );
@@ -82,5 +58,4 @@
 			lnumber     to_number     ( lua_State *L, int index );
 			bool        to_bool       ( lua_State *L, int index );
-//			const char* to_cstring    ( lua_State *L, int index );
 			string_view to_string_view( lua_State *L, int index );
 			void*       to_pointer    ( lua_State *L, int index );
@@ -91,5 +66,4 @@
 			lnumber     to_number     ( lua_State *L, int index, lnumber def );
 			bool        to_bool       ( lua_State *L, int index, bool def );
-//			const char* to_cstring    ( lua_State *L, int index, const char* def );
 			string_view to_string_view( lua_State *L, int index, string_view def );
 			void*       to_pointer    ( lua_State *L, int index, void* def );
@@ -98,12 +72,46 @@
 			void pop_and_discard( lua_State *L, int count );
 			bool is_userdata( lua_State *L, int index, const char* metatable );
-			void* check_userdata( lua_State *L, int index, const char* metatable );
-			void* allocate_userdata( lua_State *L, size_t size, const char* metatable );
+			void* raw_check_userdata( lua_State *L, int index, const char* metatable );
+			void* raw_allocate_userdata( lua_State *L, size_t size, const char* metatable );
+
 			template <typename T>
 			void push_userdata( lua_State *L, const T& v, const char* metatable )
 			{
-				new (allocate_userdata(L, sizeof(T), metatable)) T(v);
+				new ( raw_allocate_userdata( L, sizeof( T ), metatable ) ) T( v );
+			}
+
+			template <typename T>
+			T* to_userdata( lua_State *L, int index, const char* metatable )
+			{
+				return reinterpret_cast<T*>( raw_check_userdata( L, index, metatable ) );
+			}
+
+			template <typename T>
+			T* to_userdata( lua_State *L, int index )
+			{
+				return reinterpret_cast<T*>( raw_check_userdata( L, index, pass_traits<T>::metatable() ) );
 			}
 		}
+
+		template < typename T >
+		struct metatable_pass_traits
+		{
+			typedef T value_type;
+			static void push( lua_State *L, const value_type& v )
+			{
+				detail::push_userdata< value_type >( L, v, pass_traits< value_type >::metatable() );
+			}
+			static value_type to( lua_State *L, int index )
+			{
+				// TODO: ASSERT?
+				value_type* result = detail::to_userdata< value_type >( L, index, pass_traits< value_type >::metatable() );
+				return result ? *result : value_type();
+			}
+			static value_type to( lua_State *L, int index, const value_type& def )
+			{
+				value_type* result = detail::to_userdata< value_type >( L, index, pass_traits< value_type >::metatable() );
+				return result ? *result : def;
+			}
+		};
 
 		template <>
@@ -139,12 +147,4 @@
 		};
 
-// 		template <>
-// 		struct pass_traits<const char*>
-// 		{
-// 			static void push( lua_State *L, const char* s ) { detail::push_cstring( L, s ); }
-// 			static const char* to( lua_State *L, int index ) { return detail::to_cstring( L, index ); }
-// 			static const char* to( lua_State *L, int index, const char* def ) { return detail::to_cstring( L, index, def ); }
-// 		};
-
 		template <>
 		struct pass_traits < string_view >
@@ -163,10 +163,22 @@
 		};
 
-		template <>
-		struct pass_traits < string128 >
-		{
-			static void push( lua_State *L, const string128& s ) { detail::push_string_view( L, s ); }
-			static string128 to( lua_State *L, int index ) { return string128( detail::to_string_view( L, index ) ); }
-			static string128 to( lua_State *L, int index, const string_view& def ) { return string128( detail::to_string_view( L, index, def ) ); }
+		// TODO: might be better to pass only string_views? 
+		//       or maybe make them all decay to them?
+		template < size_t N >
+		struct pass_traits < short_string<N> >
+		{
+			typedef short_string<N> value_type;
+			static void push( lua_State *L, const value_type& s ) { detail::push_string_view( L, s ); }
+			static value_type to( lua_State *L, int index ) { return value_type( detail::to_string_view( L, index ) ); }
+			static value_type to( lua_State *L, int index, const string_view& def ) { return value_type( detail::to_string_view( L, index, def ) ); }
+		};
+
+		template <>
+		struct pass_traits < string_buffer >
+		{
+			typedef string_buffer value_type;
+			static void push( lua_State *L, const value_type& s ) { detail::push_string_view( L, s ); }
+			static value_type to( lua_State *L, int index ) { return value_type( detail::to_string_view( L, index ) ); }
+			static value_type to( lua_State *L, int index, const string_view& def ) { return value_type( detail::to_string_view( L, index, def ) ); }
 		};
 
@@ -181,5 +193,5 @@
 		{
 
-			template <typename T, class ENABLE = void >
+			template <typename T, class Enable = void >
 			struct lua_type_impl
 			{
@@ -240,11 +252,11 @@
 			void push_values(lua_State *L, T&& p)
 			{
-				push_value( L, forward<T>(p) );
+				push_value( L, ::nv::forward<T>(p) );
 			}
 			template < typename T, typename ...Ts >
 			void push_values(lua_State *L, T&& p, Ts&& ...ps)
 			{
-				push_value(L, forward<T>(p));
-				push_values(L, forward<Ts>(ps)...);
+				push_value(L, ::nv::forward<T>(p));
+				push_values(L, ::nv::forward<Ts>(ps)...);
 			}
 
@@ -276,5 +288,5 @@
 			}
 			template < typename T >
-			inline converted_type_t<T> pop_return_value( lua_State *L, const T& def )
+			inline T pop_return_value( lua_State *L, const T& def )
 			{
 				T ret = static_cast<T>( pass_traits< converted_type_t<T> >::to( L, -1, def ) );
Index: /trunk/src/lua/lua_area.cc
===================================================================
--- /trunk/src/lua/lua_area.cc	(revision 448)
+++ /trunk/src/lua/lua_area.cc	(revision 449)
@@ -9,6 +9,4 @@
 #include "nv/lua/lua_raw.hh"
 #include "nv/core/random.hh"
-
-const char* nv::lua::detail::AREA_METATABLE = "area";
 
 using nv::lua::detail::is_coord;
@@ -446,5 +444,5 @@
 	};
 
-	luaL_newmetatable( L, nv::lua::detail::AREA_METATABLE );
+	luaL_newmetatable( L, nv::lua::pass_traits< nv::rectangle >::metatable() );
 	nlua_register( L, nlua_area_m, -1 );
 	lua_createtable( L, 0, 0 );
Index: /trunk/src/lua/lua_glm.cc
===================================================================
--- /trunk/src/lua/lua_glm.cc	(revision 448)
+++ /trunk/src/lua/lua_glm.cc	(revision 449)
@@ -339,5 +339,5 @@
 	};
 
-	luaL_newmetatable( L, nv::lua::detail::glm_metatable_name<T>() );
+	luaL_newmetatable( L, nv::lua::pass_traits<T>::metatable() );
 	nlua_register( L, nlua_vec_m, -1 );
 	lua_createtable( L, 0, 0 );
Index: /trunk/src/lua/lua_raw.cc
===================================================================
--- /trunk/src/lua/lua_raw.cc	(revision 448)
+++ /trunk/src/lua/lua_raw.cc	(revision 449)
@@ -24,5 +24,5 @@
 	{
 		nv::string64 buffer;
-		size_t l = nv::uint64_to_buffer( buffer, nv::uint64( lua_touserdata( L, idx ) ) );
+		buffer.append( nv::uint64( lua_touserdata( L, idx ) ) );
 		return buffer;
 	}
@@ -30,5 +30,5 @@
 	{
 		nv::string64 buffer;
-		size_t l = nv::f64_to_buffer( buffer, lua_tonumber( L, idx ) );
+		buffer.append( nv::uint64( lua_touserdata( L, idx ) ) );
 		return buffer;
 	}
Index: /trunk/src/lua/lua_values.cc
===================================================================
--- /trunk/src/lua/lua_values.cc	(revision 448)
+++ /trunk/src/lua/lua_values.cc	(revision 449)
@@ -23,10 +23,10 @@
 }
 
-void* nv::lua::detail::check_userdata( lua_State *L, int index, const char* metatable )
+void* nv::lua::detail::raw_check_userdata( lua_State *L, int index, const char* metatable )
 {
 	return luaL_checkudata( L, index, metatable );
 }
 
-void* nv::lua::detail::allocate_userdata( lua_State *L, size_t size, const char* metatable )
+void* nv::lua::detail::raw_allocate_userdata( lua_State *L, size_t size, const char* metatable )
 {
 	void* result = lua_newuserdata(L, size);
@@ -63,9 +63,4 @@
 {
 	lua_pushboolean( L, v );
-}
-
-void nv::lua::detail::push_cstring ( lua_State *L, const char* s )
-{
-	lua_pushstring( L, s );
 }
 
@@ -105,9 +100,4 @@
 	return lua_toboolean( L, index ) != 0;
 }
-
-// const char* nv::lua::detail::to_cstring ( lua_State *L, int index )
-// {
-// 	return lua_tolstring( L, index, nullptr );
-// }
 
 nv::string_view nv::lua::detail::to_string_view( lua_State *L, int index )
@@ -164,9 +154,4 @@
 }
 
-// const char* nv::lua::detail::to_cstring ( lua_State *L, int index, const char* def )
-// {
-// 	return ( lua_type( L, index ) == LUA_TSTRING ? lua_tostring( L, index ) : def );
-// }
-
 void*       nv::lua::detail::to_pointer ( lua_State *L, int index, void* def )
 {
