Index: trunk/nv/core/string.hh
===================================================================
--- trunk/nv/core/string.hh	(revision 359)
+++ trunk/nv/core/string.hh	(revision 360)
@@ -2,4 +2,19 @@
 // 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 and TRAITS, make a string_utf8 instead.
 
 #ifndef NV_CORE_STRING_HH
@@ -225,34 +240,385 @@
 	}
 
+	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(); }
+		};
+	}
+
 	template< typename T >
-	struct string_length
-	{
-		static size_t get( T ) { return 0; }
+	using string_length = detail::string_length_impl <
+		typename std::remove_cv < typename std::remove_reference< T >::type >::type >;
+
+	template<typename T, typename TRAITS = std::char_traits<T> > class basic_string_ref;
+	
+	// string base class - will become a base for a string class later
+	template<typename T, typename TRAITS = std::char_traits<T> >
+	class basic_string_base
+	{
+	public:
+		typedef T              value_type;
+		typedef const T*       pointer;
+		typedef const T&       reference;
+		typedef const T&       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
+ 		std::basic_string<T, TRAITS> to_string() const
+ 		{
+ 			return std::basic_string<T, TRAITS>( m_data, m_size );
+ 		}
+
+		// iterators
+		NV_CONSTEXPR const_iterator  cbegin() const { return m_data; }
+		NV_CONSTEXPR const_iterator    cend() const { return m_data + m_size; }
+		const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); }
+		const_reverse_iterator   crend() const { return const_reverse_iterator( begin() ); }
+
+		NV_CONSTEXPR size_type size()     const { return m_size; }
+		NV_CONSTEXPR size_type length()   const { return m_size; }
+		NV_CONSTEXPR size_type max_size() const { return m_size; }
+		NV_CONSTEXPR bool empty()         const { return m_size == 0; }
+
+		// access
+		NV_CONSTEXPR const T& operator[]( size_type i ) const { return m_data[i]; }
+		const T& at( size_t i ) const
+		{
+			//	if ( i >= m_data ) NV_THROW( std::out_of_range( "string_ref::at" ) );
+			return m_data[i];
+		}
+
+		NV_CONSTEXPR const T& front() const { return m_data[0]; }
+		NV_CONSTEXPR const T& back()  const { return m_data[m_size - 1]; }
+		NV_CONSTEXPR const T* data()  const { return m_data; }
+
+		// string operations
+		int compare( basic_string_base rhs ) const
+		{
+			int cmp = TRAITS::compare( 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( T c ) const { return !empty() && TRAITS::eq( c, front() ); }
+		bool starts_with( basic_string_base s ) const
+		{
+			return m_size >= s.m_size && TRAITS::compare( m_data, s.m_data, s.m_size ) == 0;
+		}
+		bool ends_with( T c ) const { return !empty() && TRAITS::eq( c, back() ); }
+		bool ends_with( basic_string_base s ) const
+		{
+			return m_size >= s.m_size && TRAITS::compare( m_data + m_size - s.m_size, s.m_data, s.m_size ) == 0;
+		}
+		size_type find( basic_string_base s, size_type pos = 0 ) const
+		{
+			if ( pos >= m_size ) return npos;
+			const_iterator it = std::search( this->cbegin() + pos, this->cend(), s.cbegin(), s.cend(), TRAITS::eq );
+			return it == this->cend() ? npos : std::distance( this->cbegin(), it );
+		}
+		size_type find( T c, size_type pos = 0 ) const
+		{
+			if ( pos >= m_size ) return npos;
+			const_iterator it = std::find_if( this->cbegin() + pos, this->cend(), [=] ( T val ) { return TRAITS::eq( val, c ); } );
+			return it == this->cend() ? npos : std::distance( this->cbegin(), it );
+		}
+		size_type rfind( basic_string_base s, size_type pos = 0 ) const
+		{
+			if ( pos >= m_size ) return npos;
+			const_reverse_iterator it = std::search( this->crbegin() + pos, this->crend(), s.crbegin(), s.crend(), TRAITS::eq );
+			return it == this->crend() ? npos : m_size - 1 - std::distance( this->crbegin(), it );
+		}
+		size_type rfind( T c, size_type pos = 0 ) const
+		{
+			if ( pos >= m_size ) return npos;
+			const_reverse_iterator it = std::find_if( this->crbegin() + pos, this->crend(), [=] ( T val ) { return TRAITS::eq( val, c ); } );
+			return it == this->crend() ? npos : m_size - 1 - std::distance( this->crbegin(), it );
+		}
+		size_type find_first_of( T c ) const { return find( c ); }
+		size_type find_first_of( basic_string_base s ) const
+		{
+			const_iterator it = std::find_first_of( this->cbegin(), this->cend(), s.cbegin(), s.cend(), TRAITS::eq );
+			return it == this->cend() ? npos : std::distance( this->cbegin(), it );
+		}
+		size_type find_last_of( T c )  const { return rfind( c ); }
+		size_type find_last_of( basic_string_base s ) const
+		{
+			const_reverse_iterator it = std::find_first_of( this->crbegin(), this->crend(), s.cbegin(), s.cend(), TRAITS::eq );
+			return it == this->crend() ? npos : m_size - 1 - std::distance( this->crbegin(), it );
+		}
+		size_type find_first_not_of( basic_string_base s ) const
+		{
+			for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
+				if ( 0 == TRAITS::find( s.m_data, s.m_size, *first ) )
+					return std::distance( this->cbegin(), it );
+			return npos;
+		}
+		size_type find_first_not_of( T c ) const
+		{
+			for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
+				if ( !TRAITS::eq( c, *it ) )
+					return std::distance( this->cbegin(), it );
+			return npos;
+		}
+		size_type find_last_not_of( basic_string_base s ) const
+		{
+			for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
+				if ( 0 == TRAITS::find( s.m_data, s.m_size, *it ) )
+					return m_size - 1 - std::distance( this->crbegin(), it );;
+			return npos;
+		}
+		size_type find_last_not_of( T c ) const
+		{
+			for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
+				if ( !TRAITS::eq( c, *it ) )
+					return m_size - 1 - std::distance( this->crbegin(), it );
+			return npos;
+		}
+
+		// string operations
+		basic_string_ref< T, TRAITS > substr( size_type p, size_type n = npos ) const
+		{
+			if ( p > size() ) return basic_string_ref< T, TRAITS >(); // NV_THROW( std::out_of_range( "substr" ) );
+			if ( n == p || p + n > size() ) n = size() - p;
+			return basic_string_ref< T, TRAITS >( data() + p, n );
+		}
+
+	protected:
+		NV_CONSTEXPR basic_string_base() : m_data( nullptr ), m_size( 0 ) {}
+		NV_CONSTEXPR basic_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;
 	};
-	template< size_t S >
-	struct string_length< char[S] >
-	{
-		static size_t get( const char[S] ) { return S-1; }
+
+#define NV_STRING_BASE_CAST_OPERATORS( OPERATOR )\
+template < typename T, typename TRAITS, typename ALLOCATOR >\
+inline bool operator OPERATOR ( basic_string_base< T, TRAITS > lhs, const std::basic_string< T, TRAITS, ALLOCATOR >& rhs )\
+		{\
+	return lhs OPERATOR basic_string_base< T, TRAITS >( rhs );\
+		}\
+template < typename T, typename TRAITS, typename ALLOCATOR >\
+inline bool operator OPERATOR ( const std::basic_string< T, TRAITS, ALLOCATOR >& lhs, basic_string_base< T, TRAITS > rhs )\
+		{\
+	return basic_string_base< T, TRAITS >( lhs ) OPERATOR rhs;\
+		}\
+template < typename T, typename TRAITS >\
+inline bool operator OPERATOR ( basic_string_base<T, TRAITS> lhs, const T* rhs )\
+		{\
+	return lhs OPERATOR basic_string_base< T, TRAITS >( rhs );\
+		}\
+template < typename T, typename TRAITS >\
+inline bool operator OPERATOR ( const T* lhs, basic_string_base< T, TRAITS > rhs )\
+		{\
+	return basic_string_base< T, TRAITS >( lhs ) OPERATOR rhs;\
+		}\
+
+	// Base operators
+	template < typename T, typename TRAITS >
+	inline bool operator==( basic_string_base< T, TRAITS > lhs, basic_string_base< T, TRAITS > rhs )
+	{
+		return lhs.size() != rhs.size() ? false : ( lhs.compare( rhs ) == 0 );
+	}
+	template < typename T, typename TRAITS >
+	inline bool operator!=( basic_string_base< T, TRAITS > lhs, basic_string_base< T, TRAITS > rhs )
+	{
+		return lhs.size() != rhs.size() ? true : ( lhs.compare( rhs ) != 0 );
+	}
+	template < typename T, typename TRAITS >
+	inline bool operator<( basic_string_base< T, TRAITS > lhs, basic_string_base< T, TRAITS > rhs )
+	{
+		return lhs.compare( rhs ) < 0;
+	}
+	template < typename T, typename TRAITS >
+	inline bool operator>( basic_string_base< T, TRAITS > lhs, basic_string_base< T, TRAITS > rhs )
+	{
+		return lhs.compare( rhs ) > 0;
+	}
+	template < typename T, typename TRAITS >
+	inline bool operator<=( basic_string_base< T, TRAITS > lhs, basic_string_base< T, TRAITS > rhs )
+	{
+		return lhs.compare( rhs ) <= 0;
+	}
+	template < typename T, typename TRAITS >
+	inline bool operator>=( basic_string_base< T, TRAITS > lhs, basic_string_base< T, TRAITS > 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( >= )
+
+	template < class T, class TRAITS >
+	inline std::basic_ostream<T, TRAITS>& operator<<( std::basic_ostream<T, TRAITS>& os, const basic_string_base<T, TRAITS>& str )
+	{
+		if ( os.good() )
+		{
+			os.write( str.data(), str.size() );
+		}
+		return os;
+	}
+
+#undef NV_STRING_REF_CAST_OPERATORS
+
+	template<typename T, typename TRAITS>
+	class basic_string_ref : public basic_string_base < T, TRAITS >
+	{
+	public:
+
+		NV_CONSTEXPR basic_string_ref() {}
+		NV_CONSTEXPR basic_string_ref( const basic_string_ref &rhs )
+			: basic_string_base( rhs.m_data, rhs.m_size )
+		{
+		}
+		NV_CONSTEXPR basic_string_ref( const basic_string_base< T, TRAITS > &rhs )
+			: basic_string_base( rhs.m_data, rhs.m_size )
+		{
+		}
+
+		template< typename ALLOCATOR >
+		basic_string_ref( const std::basic_string<T, TRAITS, ALLOCATOR>& str )
+			: basic_string_base( str.data(), str.length() )
+		{
+		}
+
+		NV_CONSTEXPR basic_string_ref( const T* str, size_type len )
+			: basic_string_base( str, len )
+		{
+		}
+
+		// Literal constructors
+		template< size_t N, typename std::enable_if<std::is_same<T, char>::value>::type* = nullptr >
+		basic_string_ref( T( &s )[N] ) : basic_string_base( s, N - 1 ) {}
+		template< size_t N, typename std::enable_if<std::is_same<T, char>::value>::type* = nullptr >
+		basic_string_ref( const T( &s )[N] ) : basic_string_base( s, N - 1 ) {}
+
+		// Non-literal constructors
+		template< typename U, typename std::enable_if<std::is_same<U, const char*>::value>::type* = nullptr >
+		basic_string_ref( U str ) : basic_string_base( str, TRAITS::length( str ) ) {}
+
+		basic_string_ref& operator=( const basic_string_ref &rhs )
+		{
+			m_data = rhs.m_data;
+			m_size = rhs.m_size;
+			return *this;
+		}
+
+		// iterators
+		NV_CONSTEXPR const_iterator   begin() const { return m_data; }
+		NV_CONSTEXPR const_iterator     end() const { return m_data + m_size; }
+		const_reverse_iterator  rbegin() const { return const_reverse_iterator( end() ); }
+		const_reverse_iterator    rend() const { return const_reverse_iterator( begin() ); }
+
+		// modifiers
+		void clear()
+		{
+			m_size = 0;
+			m_data = nullptr;
+		}
+		void remove_prefix( size_type n )
+		{
+			if ( n > m_size )	n = m_size;
+			m_data += n;
+			m_size -= n;
+		}
+		void remove_suffix( size_type n )
+		{
+			if ( n > m_size ) n = m_size;
+			m_size -= n;
+		}
+
 	};
-	template< size_t S >
-	struct string_length< const char[S] >
-	{
-		static size_t get( const char[S] ) { return S-1; }
+
+	typedef basic_string_ref<char, std::char_traits<char> > string_ref;
+
+	// const string is movable but not copyable
+	template<typename T, typename TRAITS>
+	class basic_const_string : public basic_string_base < T, TRAITS >
+	{
+	public:
+		basic_const_string() {}
+		basic_const_string( const T* str, size_type len )
+		{
+			initialize( str, len );
+		}
+		explicit basic_const_string( const T* str )
+		{
+			initialize( str, TRAITS::length( str ) );
+		}
+
+		~basic_const_string()
+		{
+			if ( m_data ) delete m_data;
+		}
+
+		basic_const_string( const basic_const_string&& other )
+		{
+			std::swap( m_data, other.m_data );
+			return *this;
+		}
+
+		basic_const_string& operator=( const basic_const_string&& other )
+		{
+			std::swap( m_data, other.m_data );
+			return *this;
+		}
+
+	private:
+		// blocked copy constructor
+		basic_const_string( const basic_const_string & );
+		// blocked copy operator
+		basic_const_string& operator=( const basic_const_string& );
+
+		void assign( const T* p, size_type s )
+		{
+			m_data = new T[s + 1];
+			TRAITS::copy( m_data, p, s );
+			m_data[s] = 0;
+		}
 	};
-	template<>
-	struct string_length< char* >
-	{
-		static size_t get( const char* s ) { return std::strlen( s ); }
-	};
-	template<>
-	struct string_length< const char* >
-	{
-		static size_t get( const char* s ) { return std::strlen( s ); }
-	};
-	template<>
-	struct string_length< std::string >
-	{
-		static size_t get( const std::string& s ) { return s.length(); }
-	};
 
 
Index: trunk/nv/core/string_ref.hh
===================================================================
--- trunk/nv/core/string_ref.hh	(revision 359)
+++ 	(revision )
@@ -1,290 +1,0 @@
-// Copyright (C) 2015 ChaosForge Ltd
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-// 
-// 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
-
-
-#ifndef NV_CORE_STRING_REF_HH
-#define NV_CORE_STRING_REF_HH
-
-#include <nv/core/common.hh>
-#include <nv/core/exception.hh>
-#include <nv/core/string.hh>
-
-namespace nv
-{
-
-	template<typename T, typename TRAITS = std::char_traits<T> > class basic_string_ref;
-
-	typedef basic_string_ref<char, std::char_traits<char> > string_ref;
-
-	template<typename T, typename TRAITS>
-	class basic_string_ref
-	{
-	public:
-		typedef T              value_type;
-		typedef const T*       pointer;
-		typedef const T&       reference;
-		typedef const T&       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 );
-
-		NV_CONSTEXPR basic_string_ref() : m_data( nullptr ), m_length( 0 ) {}
-		NV_CONSTEXPR basic_string_ref( const basic_string_ref &rhs ) : m_data( rhs.m_data ), m_length( rhs.m_length ) {}
-
-		template< typename ALLOCATOR >
-		basic_string_ref( const std::basic_string<T, TRAITS, ALLOCATOR>& str )
-			: m_data( str.data() ), m_length( str.length() ) {}
-
-		NV_CONSTEXPR basic_string_ref( const T* str, size_type len )
-			: m_data( str ), m_length( len ) {}
-
-		// Literal constructors
-		template< size_t N, typename std::enable_if<std::is_same<T, char>::value>::type* = nullptr >
-		basic_string_ref( T( &s )[N] ) : m_data( s ), m_length( N - 1 ) {}
-		template< size_t N, typename std::enable_if<std::is_same<T, char>::value>::type* = nullptr >
-		basic_string_ref( const T( &s )[N] ) : m_data( s ), m_length( N - 1 ) {}
-
-		// Non-literal constructors
-		template< typename U, typename std::enable_if<std::is_same<U,const char*>::value>::type* = nullptr >
-		basic_string_ref( U str )
-			: m_data( str ), m_length( TRAITS::length( str ) ) {}
-
-		basic_string_ref& operator=( const basic_string_ref &rhs )
-		{
-			m_data = rhs.m_data;
-			m_length = rhs.m_length;
-			return *this;
-		}
-
-		// conversion to std::string
-		template<typename ALLOCATOR>
-		explicit operator std::basic_string<T, TRAITS, ALLOCATOR>() const
-		{
-			return std::basic_string<T, TRAITS, ALLOCATOR>( m_data, m_length );
-		}
-		std::basic_string<T, TRAITS> to_string() const
-		{
-			return std::basic_string<T, TRAITS>( m_data, m_length );
-		}
-
-		// iterators
-		NV_CONSTEXPR const_iterator   begin() const { return m_data; }
-		NV_CONSTEXPR const_iterator  cbegin() const { return m_data; }
-		NV_CONSTEXPR const_iterator     end() const { return m_data + m_length; }
-		NV_CONSTEXPR const_iterator    cend() const { return m_data + m_length; }
-		const_reverse_iterator  rbegin() const { return const_reverse_iterator( end() ); }
-		const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); }
-		const_reverse_iterator    rend() const { return const_reverse_iterator( begin() ); }
-		const_reverse_iterator   crend() const { return const_reverse_iterator( begin() ); }
-
-		NV_CONSTEXPR size_type size()     const { return m_length; }
-		NV_CONSTEXPR size_type length()   const { return m_length; }
-		NV_CONSTEXPR size_type max_size() const { return m_length; }
-		NV_CONSTEXPR bool empty()         const { return m_length == 0; }
-
-		// access
-		NV_CONSTEXPR const T& operator[]( size_type i ) const { return m_data[i]; }
-		const T& at( size_t i ) const
-		{
-		//	if ( i >= m_data ) NV_THROW( std::out_of_range( "string_ref::at" ) );
-			return m_data[i];
-		}
-
-		NV_CONSTEXPR const T& front() const { return m_data[ 0 ]; }
-		NV_CONSTEXPR const T& back()  const { return m_data[ m_length - 1 ]; }
-		NV_CONSTEXPR const T* data()  const { return m_data; }
-
-		// modifiers
-		void clear()
-		{
-			m_length = 0;
-			m_data   = nullptr;
-		}
-		void remove_prefix( size_type n )
-		{
-			if ( n > m_length )	n = m_length;
-			m_data   += n;
-			m_length -= n;
-		}
-		void remove_suffix( size_type n )
-		{
-			if ( n > m_length ) n = m_length;
-			m_length -= n;
-		}
-
-		// string operations
-		basic_string_ref substr( size_type p, size_type n = npos ) const
-		{
-			if ( p > size() ) return basic_string_ref(); // NV_THROW( std::out_of_range( "substr" ) );
-			if ( n == p || p + n > size() ) n = size() - p;
-			return basic_string_ref( data() + p, n );
-		}
-		int compare( basic_string_ref rhs ) const
-		{
-			int cmp = TRAITS::compare( m_data, rhs.m_data, ( std::min )( m_length, rhs.m_length ) );
-			return cmp != 0 ? cmp : ( m_length == rhs.m_length ? 0 : m_length < rhs.m_length ? -1 : 1 );
-		}
-		bool starts_with( T c ) const { return !empty() && TRAITS::eq( c, front() ); }
-		bool starts_with( basic_string_ref s ) const
-		{
-			return m_length >= s.m_length && TRAITS::compare( m_data, s.m_data, s.m_length ) == 0;
-		}
-		bool ends_with( T c ) const { return !empty() && TRAITS::eq( c, back() ); }
-		bool ends_with( basic_string_ref s ) const
-		{
-			return m_length >= s.m_length && TRAITS::compare( m_data + m_length - s.m_length, s.m_data, s.m_length ) == 0;
-		}
-		size_type find( basic_string_ref s ) const
-		{
-			const_iterator it = std::search( this->cbegin(), this->cend(), s.cbegin(), s.cend(), TRAITS::eq );
-			return it == this->cend() ? npos : std::distance( this->cbegin(), it );
-		}
-		size_type find( T c ) const
-		{
-			const_iterator it = std::find_if( this->cbegin(), this->cend(), [=] ( T val ) { return TRAITS::eq( val, c ); } );
-			return it == this->cend() ? npos : std::distance( this->cbegin(), it );
-		}
-		size_type rfind( basic_string_ref s ) const
-		{
-			const_reverse_iterator it = std::search( this->crbegin(), this->crend(), s.crbegin(), s.crend(), TRAITS::eq );
-			return it == this->crend() ? npos : m_length - 1 - std::distance( this->crbegin(), it );
-		}
-		size_type rfind( T c ) const
-		{
-			const_reverse_iterator it = std::find_if( this->crbegin(), this->crend(), [=] ( T val ) { return TRAITS::eq( val, c ); } );
-			return it == this->crend() ? npos : m_length - 1 - std::distance( this->crbegin(), it );
-		}
-		size_type find_first_of( T c ) const { return find( c ); }
-		size_type find_first_of( basic_string_ref s ) const
-		{ 
-			const_iterator it = std::find_first_of( this->cbegin(), this->cend(), s.cbegin(), s.cend(), TRAITS::eq );
-			return it == this->cend() ? npos : std::distance( this->cbegin(), it );
-		}
-		size_type find_last_of( T c )  const { return rfind( c ); }
-		size_type find_last_of( basic_string_ref s ) const
-		{
-			const_reverse_iterator it = std::find_first_of( this->crbegin(), this->crend(), s.cbegin(), s.cend(), TRAITS::eq );
-			return it == this->crend() ? npos : m_length - 1 - std::distance( this->crbegin(), it );
-		}
-		size_type find_first_not_of( basic_string_ref s ) const
-		{
-			for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
-				if ( 0 == TRAITS::find( s.m_data, s.m_length, *first ) )
-					return std::distance( this->cbegin(), it );
-			return npos;
-		}
-		size_type find_first_not_of( T c ) const
-		{
-			for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
-				if ( !TRAITS::eq( c, *it ) )
-					return std::distance( this->cbegin(), it );
-			return npos;
-		}
-		size_type find_last_not_of( basic_string_ref s ) const
-		{
-			for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
-				if ( 0 == TRAITS::find( s.m_data, s.m_length, *it ) )
-					return m_length - 1 - std::distance( this->crbegin(), it );;
-			return npos;
-		}
-		size_type find_last_not_of( T c ) const
-		{
-			for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
-				if ( !TRAITS::eq( c, *it ) )
-					return m_length - 1 - std::distance( this->crbegin(), it );
-			return npos;
-		}
-
-	private:
-		pointer   m_data;
-		size_type m_length;
-	};
-
-#define NV_STRING_REF_CAST_OPERATORS( OPERATOR )\
-template < typename T, typename TRAITS, typename ALLOCATOR >\
-inline bool operator OPERATOR ( basic_string_ref< T, TRAITS > lhs, const std::basic_string< T, TRAITS, ALLOCATOR >& rhs )\
-{\
-	return lhs OPERATOR basic_string_ref< T, TRAITS >( rhs );\
-}\
-template < typename T, typename TRAITS, typename ALLOCATOR >\
-inline bool operator OPERATOR ( const std::basic_string< T, TRAITS, ALLOCATOR >& lhs, basic_string_ref< T, TRAITS > rhs )\
-{\
-	return basic_string_ref< T, TRAITS >( lhs ) OPERATOR rhs;\
-}\
-template < typename T, typename TRAITS >\
-inline bool operator OPERATOR ( basic_string_ref<T, TRAITS> lhs, const T* rhs )\
-{\
-	return lhs OPERATOR basic_string_ref< T, TRAITS >( rhs );\
-}\
-template < typename T, typename TRAITS >\
-inline bool operator OPERATOR ( const T* lhs, basic_string_ref< T, TRAITS > rhs )\
-{\
-	return basic_string_ref< T, TRAITS >( lhs ) OPERATOR rhs;\
-}\
-
-	// Base operators
-	template < typename T, typename TRAITS >
-	inline bool operator==( basic_string_ref< T, TRAITS > lhs, basic_string_ref< T, TRAITS > rhs )
-	{
-		return lhs.size() != rhs.size() ? false : ( lhs.compare( rhs ) == 0 );
-	}
-	template < typename T, typename TRAITS >
-	inline bool operator!=( basic_string_ref< T, TRAITS > lhs, basic_string_ref< T, TRAITS > rhs )
-	{
-		return lhs.size() != rhs.size() ? true : ( lhs.compare( rhs ) != 0 );
-	}
-	template < typename T, typename TRAITS >
-	inline bool operator<( basic_string_ref< T, TRAITS > lhs, basic_string_ref< T, TRAITS > rhs )
-	{
-		return lhs.compare( rhs ) < 0;
-	}
-	template < typename T, typename TRAITS >
-	inline bool operator>( basic_string_ref< T, TRAITS > lhs, basic_string_ref< T, TRAITS > rhs )
-	{
-		return lhs.compare( rhs ) > 0;
-	}
-	template < typename T, typename TRAITS >
-	inline bool operator<=( basic_string_ref< T, TRAITS > lhs, basic_string_ref< T, TRAITS > rhs )
-	{
-		return lhs.compare( rhs ) <= 0;
-	}
-	template < typename T, typename TRAITS >
-	inline bool operator>=( basic_string_ref< T, TRAITS > lhs, basic_string_ref< T, TRAITS > rhs )
-	{
-		return lhs.compare( rhs ) >= 0;
-	}
-
-NV_STRING_REF_CAST_OPERATORS( == )
-NV_STRING_REF_CAST_OPERATORS( != )
-NV_STRING_REF_CAST_OPERATORS( < )
-NV_STRING_REF_CAST_OPERATORS( > )
-NV_STRING_REF_CAST_OPERATORS( <= )
-NV_STRING_REF_CAST_OPERATORS( >= )
-
-	template < class T, class TRAITS >
-	inline std::basic_ostream<T, TRAITS>& operator<<( std::basic_ostream<T, TRAITS>& os, const basic_string_ref<T, TRAITS>& str )
-	{
-		if ( os.good() )
-		{
-			os.write( str.data(), str.size() );
-		}
-		return os;
-	}
-
-#undef NV_STRING_REF_CAST_OPERATORS
-
-}
-
-#endif // NV_CORE_STRING_REF_HH
Index: trunk/nv/lua/lua_path.hh
===================================================================
--- trunk/nv/lua/lua_path.hh	(revision 359)
+++ trunk/nv/lua/lua_path.hh	(revision 360)
@@ -16,5 +16,4 @@
 #include <nv/core/common.hh>
 #include <nv/core/string.hh>
-#include <nv/core/string_ref.hh>
 #include <cstring>
 
Index: trunk/nv/lua/lua_state.hh
===================================================================
--- trunk/nv/lua/lua_state.hh	(revision 359)
+++ trunk/nv/lua/lua_state.hh	(revision 360)
@@ -15,5 +15,4 @@
 #include <nv/core/flags.hh>
 #include <nv/core/handle.hh>
-#include <nv/core/string_ref.hh>
 #include <istream>
 #include <map>
@@ -23,5 +22,5 @@
 #include <nv/lua/lua_values.hh>
 #include <nv/lua/lua_dispatch.hh>
-#include <string>
+
 
 #ifdef NV_DEBUG
@@ -130,8 +129,8 @@
 			}
 			bool is_defined( const path& p ) { return is_defined( p, m_global ); }
-			void register_native_function( lfunction f, const char* name );
+			void register_native_function( lfunction f, string_ref name );
 
 			template < typename F, F f >
-			void register_function( const char* name )
+			void register_function( string_ref name )
 			{
 				register_native_function( detail::function_wrapper< F, f >, name );
@@ -139,11 +138,5 @@
 
 			template < typename C, typename F, F f >
-			struct register_member
-			{
-				register_member( const char* ) { }
-			};
-
-			template < typename C, typename F, F f >
-			void register_function( const char* name )
+			void register_function( string_ref name )
 			{
 				register_native_function( detail::object_method_wrapper< C, F, f >, name );
@@ -199,21 +192,21 @@
 			explicit state( bool load_libs = false );
 			explicit state( lua_State* state );
-			bool do_string( const std::string& code, const std::string& name, int rvalues = 0 );
-			bool do_stream( std::istream& stream, const std::string& name );
-			bool do_file( const std::string& filename );
+			bool do_string( string_ref code, string_ref name, int rvalues = 0 );
+			bool do_stream( std::istream& stream, string_ref name );
+			bool do_file( string_ref filename );
 			int get_stack_size();
 			void log_stack();
 			lua_State* get_raw();
-			ref register_object( void* o, const char* lua_name );
-			ref register_proto( const char* id, const char* storage );
-			void store_metadata( ref object_index, const std::string& metaname, void* pointer );
+			ref register_object( void* o, string_ref lua_name );
+			ref register_proto( string_ref id, string_ref storage );
+			void store_metadata( ref object_index, string_ref metaname, void* pointer );
 			void unregister_object( ref object_index );
 
-			void register_enum( const char* name, int value );
-			void register_singleton( const char* name, void* o );
-
-			void register_native_object_method( const char* lua_name, const char* name, lfunction f );
+			void register_enum( string_ref name, int value );
+			void register_singleton( string_ref name, void* o );
+
+			void register_native_object_method( string_ref lua_name, string_ref name, lfunction f );
 			template < typename F, F f >
-			void register_object_method( const char* lua_name, const char* name )
+			void register_object_method( string_ref lua_name, string_ref name )
 			{
 				register_native_object_method( lua_name, name, detail::object_method_wrapper< typename memfn_class_type<F>::type, F, f > );
@@ -232,5 +225,5 @@
 			}
 			template < typename H >
-			ref register_handle_component( const H& handle, const std::string& id )
+			ref register_handle_component( const H& handle, string_ref id )
 			{
 				nv::lua::push_handle( m_state, handle );
@@ -238,5 +231,5 @@
 			}
 			template < typename H >
-			ref register_handle_component( const H& handle, const std::string& id, const path& proto )
+			ref register_handle_component( const H& handle, string_ref id, const path& proto )
 			{
 				if ( !proto.resolve( m_state, true ) )
@@ -248,5 +241,5 @@
 			}
 			template < typename H >
-			void unregister_handle_component( const H& handle, const std::string& id )
+			void unregister_handle_component( const H& handle, string_ref id )
 			{
 				nv::lua::push_handle( m_state, handle );
@@ -285,11 +278,11 @@
 
 		private:
-			ref register_handle_component_impl( const std::string& id, bool empty );
-			void unregister_handle_component_impl( const std::string& id );
-
-			int load_string( const std::string& code, const std::string& name );
-			int load_stream( std::istream& stream, const std::string& name );
-			int load_file( const std::string& filename );
-			int do_current( const std::string& name, int rvalues = 0 );
+			ref register_handle_component_impl( string_ref id, bool empty );
+			void unregister_handle_component_impl( string_ref id );
+
+			int load_string( string_ref code, string_ref name );
+			int load_stream( std::istream& stream, string_ref name );
+			int load_file( string_ref filename );
+			int do_current( string_ref name, int rvalues = 0 );
 			void deep_pointer_copy( int index, void* obj );
 		};
@@ -302,16 +295,16 @@
 			virtual ~table_guard();
 			size_t get_size();
-			bool has_field( const std::string& element );
-			std::string get_string( const std::string& element, const std::string& defval = "" );
-			char get_char( const std::string& element, char defval = ' ' );
-			int get_integer( const std::string& element, int defval = 0 );
-			unsigned get_unsigned( const std::string& element, unsigned defval = 0 );
-			double get_double( const std::string& element, double defval = 0.0 );
-			float get_float( const std::string& element, float defval = 0.0 );
-			bool get_boolean( const std::string& element, bool defval = false );
-			bool is_table( const std::string& element );
-			bool is_number( const std::string& element );
-			bool is_boolean( const std::string& element );
-			bool is_string( const std::string& element );
+			bool has_field( string_ref element );
+			std::string get_string( string_ref element, string_ref defval = string_ref() );
+			char get_char( string_ref element, char defval = ' ' );
+			int get_integer( string_ref element, int defval = 0 );
+			unsigned get_unsigned( string_ref element, unsigned defval = 0 );
+			double get_double( string_ref element, double defval = 0.0 );
+			float get_float( string_ref element, float defval = 0.0 );
+			bool get_boolean( string_ref element, bool defval = false );
+			bool is_table( string_ref element );
+			bool is_number( string_ref element );
+			bool is_boolean( string_ref element );
+			bool is_string( string_ref element );
 		private:
 			int m_level;
Index: trunk/nv/lua/lua_values.hh
===================================================================
--- trunk/nv/lua/lua_values.hh	(revision 359)
+++ trunk/nv/lua/lua_values.hh	(revision 360)
@@ -11,5 +11,4 @@
 #include <nv/core/type_traits.hh>
 #include <nv/core/string.hh>
-#include <nv/core/string_ref.hh>
 
 struct lua_State;
Index: trunk/src/lua/lua_map_area.cc
===================================================================
--- trunk/src/lua/lua_map_area.cc	(revision 359)
+++ trunk/src/lua/lua_map_area.cc	(revision 360)
@@ -57,5 +57,5 @@
 	if ( lua_istable( L , index ) )
 	{
-		lua_pushstring( L, "__map_area_ptr" );
+		lua_pushliteral( L, "__map_area_ptr" );
 		lua_rawget( L, index );
 		if ( lua_isuserdata( L, -1 ) )
@@ -96,5 +96,5 @@
 static int nlua_map_area_tostring( lua_State* L )
 {
-	lua_pushstring( L, "map_area" );
+	lua_pushliteral ( L, "map_area" );
 	return 1;
 }
@@ -236,5 +236,5 @@
 {
 	lua_rawgeti( L, LUA_REGISTRYINDEX, object_index.get() );
-	lua_pushstring( L, "__map_area_ptr" );
+	lua_pushliteral( L, "__map_area_ptr" );
 	lua_pushlightuserdata( L, (map_area*)area );
 	lua_rawset( L, -3 );
Index: trunk/src/lua/lua_path.cc
===================================================================
--- trunk/src/lua/lua_path.cc	(revision 359)
+++ trunk/src/lua/lua_path.cc	(revision 360)
@@ -18,5 +18,5 @@
 	size_t point = spath.find( '.' );
 
-	while ( point != std::string::npos )
+	while ( point != string_ref::npos )
 	{
 		m_elements[m_count].str    = spath.data();
Index: trunk/src/lua/lua_state.cc
===================================================================
--- trunk/src/lua/lua_state.cc	(revision 359)
+++ trunk/src/lua/lua_state.cc	(revision 360)
@@ -80,9 +80,9 @@
 }
 
-void lua::state_wrapper::register_native_function( lfunction f, const char* name )
+void lua::state_wrapper::register_native_function( lfunction f, string_ref name )
 {
 	if ( m_global ) push_global_table();
 	lua_pushcfunction( m_state, f );
-	lua_setfield( m_state, -2, name );
+	lua_setfield( m_state, -2, name.data() );
 	if ( m_global ) pop_global_table();
 }
@@ -129,7 +129,6 @@
 	if ( status != 0 )
 	{
-		std::string error = lua_tostring( m_state, -1 );
+		NV_LOG( LOG_ERROR, "Lua error : " << lua_tostring( m_state, -1 ) );
 		lua_pop( m_state, 1 );
-		NV_LOG( LOG_ERROR, "Lua error : " << error )
 	}
 	return status;
@@ -172,7 +171,7 @@
 }
 
-bool lua::table_guard::has_field( const string& element )
-{
-	lua_getfield( m_state, -1, element.c_str() );
+bool lua::table_guard::has_field( string_ref element )
+{
+	lua_getfield( m_state, -1, element.data() );
 	bool result = !( lua_isnil( m_state, -1 ) );
 	lua_pop( m_state, 1 );
@@ -180,15 +179,15 @@
 }
 
-string lua::table_guard::get_string( const string& element, const string& defval /*= "" */ )
-{
-	lua_getfield( m_state, -1, element.c_str() );
-	string result( ( lua_type( m_state, -1 ) == LUA_TSTRING ) ? lua_tostring( m_state, -1 ) : defval );
-	lua_pop( m_state, 1 );
-	return result;
-}
-
-char lua::table_guard::get_char( const string& element, char defval /*= "" */ )
-{
-	lua_getfield( m_state, -1, element.c_str() );
+string lua::table_guard::get_string( string_ref element, string_ref defval /*= string_ref() */ )
+{
+	lua_getfield( m_state, -1, element.data() );
+	string result( ( lua_type( m_state, -1 ) == LUA_TSTRING ) ? lua_tostring( m_state, -1 ) : defval.to_string() );
+	lua_pop( m_state, 1 );
+	return result;
+}
+
+char lua::table_guard::get_char( string_ref element, char defval /*= "" */ )
+{
+	lua_getfield( m_state, -1, element.data() );
 	char result = ( lua_type( m_state, -1 ) == LUA_TSTRING && lua_rawlen( m_state, -1 ) > 0 ) ? lua_tostring( m_state, -1 )[0] : defval;
 	lua_pop( m_state, 1 );
@@ -196,7 +195,7 @@
 }
 
-int lua::table_guard::get_integer( const string& element, int defval /*= "" */ )
-{
-	lua_getfield( m_state, -1, element.c_str() );
+int lua::table_guard::get_integer( string_ref element, int defval /*= "" */ )
+{
+	lua_getfield( m_state, -1, element.data() );
 	lua_Integer result = lua_type( m_state, -1 ) == LUA_TNUMBER ? lua_tointeger( m_state, -1 ) : defval;
 	lua_pop( m_state, 1 );
@@ -204,7 +203,7 @@
 }
 
-unsigned lua::table_guard::get_unsigned( const string& element, unsigned defval /*= "" */ )
-{
-	lua_getfield( m_state, -1, element.c_str() );
+unsigned lua::table_guard::get_unsigned( string_ref element, unsigned defval /*= "" */ )
+{
+	lua_getfield( m_state, -1, element.data() );
 	unsigned result = lua_type( m_state, -1 ) == LUA_TNUMBER ? lua_tounsigned( m_state, -1 ) : defval;
 	lua_pop( m_state, 1 );
@@ -212,7 +211,7 @@
 }
 
-double lua::table_guard::get_double( const string& element, double defval /*= "" */ )
-{
-	lua_getfield( m_state, -1, element.c_str() );
+double lua::table_guard::get_double( string_ref element, double defval /*= "" */ )
+{
+	lua_getfield( m_state, -1, element.data() );
 	double result = lua_type( m_state, -1 ) == LUA_TNUMBER ? lua_tonumber( m_state, -1 ) : defval;
 	lua_pop( m_state, 1 );
@@ -221,7 +220,7 @@
 
 
-float nv::lua::table_guard::get_float( const std::string& element, float defval /*= 0.0 */ )
-{
-	lua_getfield( m_state, -1, element.c_str() );
+float nv::lua::table_guard::get_float( string_ref element, float defval /*= 0.0 */ )
+{
+	lua_getfield( m_state, -1, element.data() );
 	float result = lua_type( m_state, -1 ) == LUA_TNUMBER ? (float)lua_tonumber( m_state, -1 ) : defval;
 	lua_pop( m_state, 1 );
@@ -229,7 +228,7 @@
 }
 
-bool lua::table_guard::get_boolean( const string& element, bool defval /*= "" */ )
-{
-	lua_getfield( m_state, -1, element.c_str() );
+bool lua::table_guard::get_boolean( string_ref element, bool defval /*= "" */ )
+{
+	lua_getfield( m_state, -1, element.data() );
 	bool result = lua_type( m_state, -1 ) == LUA_TBOOLEAN ? lua_toboolean( m_state, -1 ) != 0 : defval;
 	lua_pop( m_state, 1 );
@@ -237,7 +236,7 @@
 }
 
-bool nv::lua::table_guard::is_table( const std::string& element )
-{
-	lua_getfield( m_state, -1, element.c_str() );
+bool nv::lua::table_guard::is_table( string_ref element )
+{
+	lua_getfield( m_state, -1, element.data() );
 	bool result = lua_type( m_state, -1 ) == LUA_TTABLE;
 	lua_pop( m_state, 1 );
@@ -245,7 +244,7 @@
 }
 
-bool nv::lua::table_guard::is_number( const std::string& element )
-{
-	lua_getfield( m_state, -1, element.c_str() );
+bool nv::lua::table_guard::is_number( string_ref element )
+{
+	lua_getfield( m_state, -1, element.data() );
 	bool result = lua_type( m_state, -1 ) == LUA_TNUMBER;
 	lua_pop( m_state, 1 );
@@ -253,7 +252,7 @@
 }
 
-bool nv::lua::table_guard::is_boolean( const std::string& element )
-{
-	lua_getfield( m_state, -1, element.c_str() );
+bool nv::lua::table_guard::is_boolean( string_ref element )
+{
+	lua_getfield( m_state, -1, element.data() );
 	bool result = lua_type( m_state, -1 ) == LUA_TBOOLEAN;
 	lua_pop( m_state, 1 );
@@ -261,7 +260,7 @@
 }
 
-bool nv::lua::table_guard::is_string( const std::string& element )
-{
-	lua_getfield( m_state, -1, element.c_str() );
+bool nv::lua::table_guard::is_string( string_ref element )
+{
+	lua_getfield( m_state, -1, element.data() );
 	bool result = lua_type( m_state, -1 ) == LUA_TSTRING;
 	lua_pop( m_state, 1 );
@@ -321,11 +320,11 @@
 }
 
-int lua::state::load_string( const std::string& code, const std::string& name )
+int lua::state::load_string( string_ref code, string_ref name )
 {
 	NV_LOG( nv::LOG_TRACE, "Loading Lua string '" << name << "'");
-	return luaL_loadbuffer( m_state, code.c_str(), code.length(), name.c_str() );
-}
-
-int lua::state::load_stream( std::istream& stream, const std::string& name )
+	return luaL_loadbuffer( m_state, code.data(), code.length(), name.data() );
+}
+
+int lua::state::load_stream( std::istream& stream, string_ref name )
 {
 	NV_LOG( nv::LOG_NOTICE, "Loading Lua stream '" << name << "'");
@@ -335,11 +334,11 @@
 }
 
-int lua::state::load_file( const std::string& filename )
+int lua::state::load_file( string_ref filename )
 {
 	NV_LOG( nv::LOG_NOTICE, "Loading Lua file '" << filename << "'");
-	return luaL_loadfile( m_state, filename.c_str() );
-}
-
-bool lua::state::do_string( const std::string& code, const std::string& name, int rvalues )
+	return luaL_loadfile( m_state, filename.data() );
+}
+
+bool lua::state::do_string( string_ref code, string_ref name, int rvalues )
 {
 	lua::stack_guard( this );
@@ -353,5 +352,5 @@
 }
 
-bool lua::state::do_stream( std::istream& stream, const std::string& name )
+bool lua::state::do_stream( std::istream& stream, string_ref name )
 {
 	lua::stack_guard( this );
@@ -365,5 +364,5 @@
 }
 
-bool lua::state::do_file( const std::string& filename )
+bool lua::state::do_file( string_ref filename )
 {
 	lua::stack_guard( this );
@@ -377,5 +376,5 @@
 }
 
-int lua::state::do_current( const std::string& name, int rvalues )
+int lua::state::do_current( string_ref name, int rvalues )
 {
 	int result = lua_pcall(m_state, 0, rvalues, 0);
@@ -408,12 +407,12 @@
 }
 
-lua::ref lua::state::register_object( void* o, const char* lua_name )
+lua::ref lua::state::register_object( void* o, string_ref lua_name )
 {
 	if ( o == nullptr ) return lua::ref( lua::ref::none );
 	stack_guard guard( this );
-	lua_getglobal( m_state, lua_name );
+	lua_getglobal( m_state, lua_name.data() );
 	if ( lua_isnil( m_state, -1 ) )
 	{
-		NV_THROW( runtime_error, std::string( lua_name ) + " type not registered!" );
+		NV_THROW( runtime_error, lua_name.to_string() + " type not registered!" );
 	}
 	deep_pointer_copy( -1, o );
@@ -421,30 +420,30 @@
 }
 
-lua::ref lua::state::register_proto( const char* id, const char* storage )
+lua::ref lua::state::register_proto( string_ref id, string_ref storage )
 {
 	stack_guard guard( this );
-	lua_getglobal( m_state, storage );
+	lua_getglobal( m_state, storage.data() );
 	if ( lua_isnil( m_state, -1 ) )
 	{
-		NV_THROW( runtime_error, std::string( storage ) + " storage not registered!" );
-	}
-	lua_getfield( m_state, -1, id );
+		NV_THROW( runtime_error, storage.to_string() + " storage not registered!" );
+	}
+	lua_getfield( m_state, -1, id.data() );
 	if ( lua_isnil( m_state, -1 ) )
 	{
-		NV_THROW( runtime_error, std::string( id ) + " not found in " + std::string( storage ) + " storage!" );
+		NV_THROW( runtime_error, id.to_string() + " not found in " + storage.to_string() + " storage!" );
 	}
 	return lua::ref( luaL_ref( m_state, LUA_REGISTRYINDEX ) );
 }
 
-void lua::state::register_native_object_method( const char* lua_name, const char* name, lfunction f )
+void lua::state::register_native_object_method( string_ref lua_name, string_ref name, lfunction f )
 {
 	stack_guard guard( this );
-	lua_getglobal( m_state, lua_name );
+	lua_getglobal( m_state, lua_name.data() );
 	if ( lua_isnil( m_state, -1 ) )
 	{
-		NV_THROW( runtime_error, std::string( lua_name ) + " type not registered!" );
+		NV_THROW( runtime_error, lua_name.to_string() + " type not registered!" );
 	}
 	lua_pushcfunction( m_state, f );
-	lua_setfield( m_state, -2, name );
+	lua_setfield( m_state, -2, name.data() );
 }
 
@@ -454,5 +453,5 @@
 	stack_guard guard( this );
 	lua_rawgeti( m_state, LUA_REGISTRYINDEX, object_index.get() );
-	lua_pushstring( m_state, "__ptr" );
+	lua_pushliteral( m_state, "__ptr" );
 	lua_pushboolean( m_state, false );
 	lua_rawset( m_state, -3 );
@@ -499,9 +498,9 @@
 }
 
-void nv::lua::state::store_metadata( ref object_index, const std::string& metaname, void* pointer )
+void nv::lua::state::store_metadata( ref object_index, string_ref metaname, void* pointer )
 {
 	if ( !object_index.is_valid() ) return;
 	lua_rawgeti( m_state, LUA_REGISTRYINDEX, object_index.get() );
-	lua_pushstring( m_state, metaname.c_str() );
+	lua_pushlstring( m_state, metaname.data(), metaname.size() );
 	lua_pushlightuserdata( m_state, pointer );
 	lua_rawset( m_state, -3 );
@@ -509,11 +508,11 @@
 }
 
-void nv::lua::state::register_enum( const char* name, int value )
+void nv::lua::state::register_enum( string_ref name, int value )
 {
 	lua_pushinteger( m_state, value );
-	lua_setglobal( m_state, name );
-}
-
-nv::lua::ref nv::lua::state::register_handle_component_impl( const std::string& id, bool empty )
+	lua_setglobal( m_state, name.data() );
+}
+
+nv::lua::ref nv::lua::state::register_handle_component_impl( string_ref id, bool empty )
 {
 	int args = empty ? 1 : 2;
@@ -529,5 +528,5 @@
 	else
 		nlua_deepcopy( m_state, -2 );
-	lua_pushstring( m_state, id.c_str() );
+	lua_pushlstring( m_state, id.data(), id.size() );
 	lua_pushvalue( m_state, -2 );
 	lua_rawset( m_state, -4 );
@@ -538,5 +537,5 @@
 }
 
-void nv::lua::state::unregister_handle_component_impl( const std::string& id )
+void nv::lua::state::unregister_handle_component_impl( string_ref id )
 {
 	NV_LUA_STACK_ASSERT( m_state, -1 );
@@ -547,5 +546,5 @@
 		return;
 	}
-	lua_pushstring( m_state, id.c_str() );
+	lua_pushlstring( m_state, id.data(), id.size() );
 	lua_pushnil( m_state );
 	lua_rawset( m_state, -3 );
@@ -553,15 +552,15 @@
 }
 
-void nv::lua::state::register_singleton( const char* name, void* o )
+void nv::lua::state::register_singleton( string_ref name, void* o )
 {
 	if ( o == nullptr ) return;
 	stack_guard guard( this );
-	lua_getglobal( m_state, name );
+	lua_getglobal( m_state, name.data() );
 	if ( lua_isnil( m_state, -1 ) )
 	{
-		NV_THROW( runtime_error, std::string( name ) + " type not registered!" );
+		NV_THROW( runtime_error, name.to_string() + " type not registered!" );
 	}
 	deep_pointer_copy( -1, o );
-	lua_setglobal( m_state, name );
-}
-
+	lua_setglobal( m_state, name.data() );
+}
+
Index: trunk/src/lua/lua_values.cc
===================================================================
--- trunk/src/lua/lua_values.cc	(revision 359)
+++ trunk/src/lua/lua_values.cc	(revision 360)
@@ -191,5 +191,5 @@
 	if ( lua_istable( L , index ) )
 	{
-		lua_pushstring( L, "__ptr" );
+		lua_pushliteral( L, "__ptr" );
 		lua_rawget( L, index );
 		if ( lua_isuserdata( L, -1 ) )
