diff --git a/sol/function.hpp b/sol/function.hpp index 42b60278..5c66dfbb 100644 --- a/sol/function.hpp +++ b/sol/function.hpp @@ -66,7 +66,7 @@ public: o.L = nullptr; o.index = 0; o.returncount = 0; - o.popcount = 0; + o.popcount = 0; o.error = call_error::runtime; } function_result& operator=(function_result&& o) { @@ -80,7 +80,7 @@ public: o.L = nullptr; o.index = 0; o.returncount = 0; - o.popcount = 0; + o.popcount = 0; o.error = call_error::runtime; return *this; } @@ -111,91 +111,91 @@ public: class fast_function : public reference { private: - void luacall( std::ptrdiff_t argcount, std::ptrdiff_t resultcount ) const { - lua_callk( lua_state( ), static_cast( argcount ), static_cast( resultcount ), 0, nullptr ); - } + void luacall( std::ptrdiff_t argcount, std::ptrdiff_t resultcount ) const { + lua_callk( lua_state( ), static_cast( argcount ), static_cast( resultcount ), 0, nullptr ); + } - template - std::tuple invoke( indices, types, std::ptrdiff_t n ) const { - luacall( n, sizeof...( Ret ), h ); - int nreturns = static_cast( sizeof...( Ret ) ); - int stacksize = lua_gettop( lua_state( ) ); - int firstreturn = std::max( 0, stacksize - nreturns ) + 1; - auto r = std::make_tuple( stack::get( lua_state( ), firstreturn + I )... ); - lua_pop( lua_state( ), nreturns ); - return r; - } + template + std::tuple invoke( indices, types, std::ptrdiff_t n ) const { + luacall( n, sizeof...( Ret ), h ); + int nreturns = static_cast( sizeof...( Ret ) ); + int stacksize = lua_gettop( lua_state( ) ); + int firstreturn = std::max( 0, stacksize - nreturns ) + 1; + auto r = std::make_tuple( stack::get( lua_state( ), firstreturn + I )... ); + lua_pop( lua_state( ), nreturns ); + return r; + } - template - Ret invoke( indices, types, std::ptrdiff_t n ) const { - luacall( n, 1 ); - return stack::pop( lua_state( ) ); - } + template + Ret invoke( indices, types, std::ptrdiff_t n ) const { + luacall( n, 1 ); + return stack::pop( lua_state( ) ); + } - template - void invoke( indices, types, std::ptrdiff_t n ) const { - luacall( n, 0 ); - } + template + void invoke( indices, types, std::ptrdiff_t n ) const { + luacall( n, 0 ); + } - function_result invoke( indices<>, types<>, std::ptrdiff_t n ) const { - int stacksize = lua_gettop( lua_state( ) ); - int firstreturn = std::max( 0, stacksize - static_cast( n ) - 1 ); - int poststacksize = 0; - int returncount = 0; - try { - luacall( n, LUA_MULTRET ); - poststacksize = lua_gettop( lua_state( ) ); - returncount = poststacksize - firstreturn; - } - // Handle C++ errors thrown from C++ functions bound inside of lua - catch ( const std::exception& error ) { - stack::push( lua_state( ), error.what( ) ); - return function_result( lua_state( ), firstreturn, 0, 1, call_error::runtime ); - } - catch ( ... ) { - throw; - } - - return function_result( lua_state( ), firstreturn, returncount, returncount, call_error::ok ); - } + function_result invoke( indices<>, types<>, std::ptrdiff_t n ) const { + int stacksize = lua_gettop( lua_state( ) ); + int firstreturn = std::max( 0, stacksize - static_cast( n ) - 1 ); + int poststacksize = 0; + int returncount = 0; + try { + luacall( n, LUA_MULTRET ); + poststacksize = lua_gettop( lua_state( ) ); + returncount = poststacksize - firstreturn; + } + // Handle C++ errors thrown from C++ functions bound inside of lua + catch ( const std::exception& error ) { + stack::push( lua_state( ), error.what( ) ); + return function_result( lua_state( ), firstreturn, 0, 1, call_error::runtime ); + } + catch ( ... ) { + throw; + } + + return function_result( lua_state( ), firstreturn, returncount, returncount, call_error::ok ); + } public: - fast_function( ) = default; - fast_function( lua_State* L, int index = -1 ) : reference( L, index ) { - type_assert( L, index, type::function ); - } - fast_function( const fast_function& ) = default; - fast_function& operator=( const fast_function& ) = default; - fast_function( fast_function&& ) = default; - fast_function& operator=( fast_function&& ) = default; + fast_function( ) = default; + fast_function( lua_State* L, int index = -1 ) : reference( L, index ) { + type_assert( L, index, type::function ); + } + fast_function( const fast_function& ) = default; + fast_function& operator=( const fast_function& ) = default; + fast_function( fast_function&& ) = default; + fast_function& operator=( fast_function&& ) = default; - template - function_result operator()( Args&&... args ) const { - return call<>( std::forward( args )... ); - } + template + function_result operator()( Args&&... args ) const { + return call<>( std::forward( args )... ); + } - template - auto operator()( types, Args&&... args ) const - -> decltype( invoke( types( ), types( ), 0, std::declval( ) ) ) { - return call( std::forward( args )... ); - } + template + auto operator()( types, Args&&... args ) const + -> decltype( invoke( types( ), types( ), 0, std::declval( ) ) ) { + return call( std::forward( args )... ); + } - template - auto call( Args&&... args ) const - -> decltype( invoke( types( ), types( ), 0 ) ) { - push( ); - int pushcount = stack::push_args( lua_state( ), std::forward( args )... ); - auto tr = types( ); - return invoke( tr, tr, pushcount ); - } + template + auto call( Args&&... args ) const + -> decltype( invoke( types( ), types( ), 0 ) ) { + push( ); + int pushcount = stack::push_args( lua_state( ), std::forward( args )... ); + auto tr = types( ); + return invoke( tr, tr, pushcount ); + } }; class safe_function : public reference { private: - static reference& handler_storage() { - static sol::reference h; - return h; - } + static reference& handler_storage() { + static sol::reference h; + return h; + } public: static const reference& get_default_handler () { @@ -253,21 +253,21 @@ private: bool handlerpushed = error_handler.valid(); int stacksize = lua_gettop(lua_state()); int firstreturn = std::max(0, stacksize - static_cast(n) - 1); - int returncount = 0; - call_error code = call_error::ok; - + int returncount = 0; + call_error code = call_error::ok; + try { code = static_cast(luacall(n, LUA_MULTRET, h)); - int poststacksize = lua_gettop( lua_state( ) ); - returncount = poststacksize - firstreturn; - } + int poststacksize = lua_gettop( lua_state( ) ); + returncount = poststacksize - firstreturn; + } // Handle C++ errors thrown from C++ functions bound inside of lua catch (const std::exception& error) { code = call_error::runtime; - h.stackindex = 0; + h.stackindex = 0; stack::push(lua_state(), error.what()); return function_result( lua_state( ), firstreturn, 0, 1, call_error::runtime ); - } + } catch (...) { throw; } @@ -376,7 +376,7 @@ struct pusher> { template static void set_reference_fx(std::false_type, lua_State* L, Fx&& fx, T&& obj) { typedef typename std::remove_pointer>::type clean_fx; - std::unique_ptr sptr(new member_function(std::forward(obj), std::forward(fx))); + std::unique_ptr sptr(new member_function>(std::forward(obj), std::forward(fx))); return set_fx(L, std::move(sptr)); } @@ -411,7 +411,7 @@ struct pusher> { template static void set_fx(lua_State* L, std::unique_ptr luafunc) { - auto&& metakey = usertype_traits>::metatable; + const auto& metakey = usertype_traits>::metatable; const char* metatablename = std::addressof(metakey[0]); base_function* target = luafunc.release(); void* userdata = reinterpret_cast(target); diff --git a/sol/function_types.hpp b/sol/function_types.hpp index 765d18dd..51799bf5 100644 --- a/sol/function_types.hpp +++ b/sol/function_types.hpp @@ -168,7 +168,7 @@ struct static_function { template static int typed_call(types, types ta, function_type* fx, lua_State* L) { typedef typename return_type::type return_type; - typedef decltype(stack::call(L, 0, types(), ta, fx)) ret_t; + typedef decltype(stack::call(L, 0, types(), ta, fx)) ret_t; ret_t r = stack::call(L, 0, types(), ta, fx); int nargs = static_cast(sizeof...(Args)); lua_pop(L, nargs); @@ -373,7 +373,8 @@ struct member_function : public base_function { template return_type operator()(Args&&... args) { - return (member.*invocation)(std::forward(args)...); + auto& mem = unwrapper(unref(member)); + return (mem.*invocation)(std::forward(args)...); } } fx; diff --git a/sol/proxy.hpp b/sol/proxy.hpp index e02e0708..3dbe5939 100644 --- a/sol/proxy.hpp +++ b/sol/proxy.hpp @@ -47,7 +47,7 @@ public: template proxy& set_function(Args&&... args) { tbl.set_function(key, std::forward(args)...); - return *this; + return *this; } template>> = 0> @@ -73,17 +73,17 @@ public: template>, is_lua_primitive> = 0> operator T ( ) const { - return get( ); + return get( ); } template>, Not>> = 0> operator T& ( ) const { - return get( ); + return get( ); } template decltype(auto) operator[](K&& key) const { - return get()[std::forward(key)]; + return get
()[std::forward(key)]; } template diff --git a/sol/table.hpp b/sol/table.hpp index 622a1a42..43a91a39 100644 --- a/sol/table.hpp +++ b/sol/table.hpp @@ -25,7 +25,7 @@ #include "table_core.hpp" namespace sol { - typedef table_core table; + typedef table_core table; } // sol #endif // SOL_TABLE_HPP diff --git a/sol/table_core.hpp b/sol/table_core.hpp index 0ecd1e85..d68b9052 100644 --- a/sol/table_core.hpp +++ b/sol/table_core.hpp @@ -29,195 +29,195 @@ namespace sol { namespace detail { - struct global_overload_tag { } const global_overload; + struct global_overload_tag { } const global_overload; } // detail template class table_core : public reference { - friend class state; - template>>, Bool> = 0> - stack::get_return single_get( Key&& key ) const { - lua_getglobal( lua_state( ), &key[ 0 ] ); - stack::get_return result = stack::pop( lua_state( ) ); - return result; - } + friend class state; + template>>, Bool> = 0> + stack::get_return single_get( Key&& key ) const { + lua_getglobal( lua_state( ), &key[ 0 ] ); + stack::get_return result = stack::pop( lua_state( ) ); + return result; + } - template>>, Bool> = 0> - stack::get_return single_get( Key&& key ) const { - push( ); - stack::push( lua_state( ), std::forward( key ) ); - lua_gettable( lua_state( ), -2 ); - stack::get_return result = stack::pop( lua_state( ) ); - pop( ); - return result; - } + template>>, Bool> = 0> + stack::get_return single_get( Key&& key ) const { + push( ); + stack::push( lua_state( ), std::forward( key ) ); + lua_gettable( lua_state( ), -2 ); + stack::get_return result = stack::pop( lua_state( ) ); + pop( ); + return result; + } - template - stack::get_return tuple_get( types, indices, Keys&& keys ) const { - return stack::get_return( single_get( std::get( keys ) )... ); - } + template + stack::get_return tuple_get( types, indices, Keys&& keys ) const { + return stack::get_return( single_get( std::get( keys ) )... ); + } - template - stack::get_return tuple_get( types, indices, Keys&& keys ) const { - return single_get( std::get( keys ) ); - } + template + stack::get_return tuple_get( types, indices, Keys&& keys ) const { + return single_get( std::get( keys ) ); + } #if SOL_LUA_VERSION < 502 - table_core( detail::global_overload_tag, const table_core& reg ) noexcept : reference( reg.lua_state(), LUA_GLOBALSINDEX ) { } + table_core( detail::global_overload_tag, const table_core& reg ) noexcept : reference( reg.lua_state(), LUA_GLOBALSINDEX ) { } #else - table_core( detail::global_overload_tag, const table& reg ) noexcept : reference( reg.get
( LUA_RIDX_GLOBALS ) ) { } + table_core( detail::global_overload_tag, const table& reg ) noexcept : reference( reg.get
( LUA_RIDX_GLOBALS ) ) { } #endif public: - table_core( ) noexcept : reference( ) { } - table_core( const table_core& global ) : reference( global ) { } - table_core( lua_State* L, int index = -1 ) : reference( L, index ) { - type_assert( L, index, type::table ); - } + table_core( ) noexcept : reference( ) { } + table_core( const table_core& global ) : reference( global ) { } + table_core( lua_State* L, int index = -1 ) : reference( L, index ) { + type_assert( L, index, type::table ); + } - template - stack::get_return get( Keys&&... keys ) const { - return tuple_get( types( ), build_indices( ), std::tie( keys... ) ); - } + template + stack::get_return get( Keys&&... keys ) const { + return tuple_get( types( ), build_indices( ), std::tie( keys... ) ); + } - template - table_core& set( T&& key, U&& value ) { - if ( top_level ) { - stack::push( lua_state( ), std::forward( value ) ); - lua_setglobal( lua_state( ), &key[0] ); - } - else { - push( ); - stack::push( lua_state( ), std::forward( key ) ); - stack::push( lua_state( ), std::forward( value ) ); - lua_settable( lua_state( ), -3 ); - pop( ); - } - return *this; - } + template + table_core& set( T&& key, U&& value ) { + if ( top_level ) { + stack::push( lua_state( ), std::forward( value ) ); + lua_setglobal( lua_state( ), &key[0] ); + } + else { + push( ); + stack::push( lua_state( ), std::forward( key ) ); + stack::push( lua_state( ), std::forward( value ) ); + lua_settable( lua_state( ), -3 ); + pop( ); + } + return *this; + } - template - SOL_DEPRECATED table_core& set_userdata( usertype& user ) { - return set_usertype( user ); - } + template + SOL_DEPRECATED table_core& set_userdata( usertype& user ) { + return set_usertype( user ); + } - template - SOL_DEPRECATED table_core& set_userdata( Key&& key, usertype& user ) { - return set_usertype( std::forward( key ), user ); - } + template + SOL_DEPRECATED table_core& set_userdata( Key&& key, usertype& user ) { + return set_usertype( std::forward( key ), user ); + } - template - table_core& set_usertype( usertype& user ) { - return set_usertype( usertype_traits::name, user ); - } + template + table_core& set_usertype( usertype& user ) { + return set_usertype( usertype_traits::name, user ); + } - template - table_core& set_usertype( Key&& key, usertype& user ) { - if ( top_level ) { - stack::push( lua_state( ), user ); - lua_setglobal( lua_state( ), &key[ 0 ] ); - pop( ); - } - else { - push( ); - stack::push( lua_state( ), std::forward( key ) ); - stack::push( lua_state( ), user ); - lua_settable( lua_state( ), -3 ); - pop( ); - } - return *this; - } + template + table_core& set_usertype( Key&& key, usertype& user ) { + if ( top_level ) { + stack::push( lua_state( ), user ); + lua_setglobal( lua_state( ), &key[ 0 ] ); + pop( ); + } + else { + push( ); + stack::push( lua_state( ), std::forward( key ) ); + stack::push( lua_state( ), user ); + lua_settable( lua_state( ), -3 ); + pop( ); + } + return *this; + } - template - void for_each( Fx&& fx ) const { - push( ); - stack::push( lua_state( ), nil ); - while ( lua_next( this->lua_state( ), -2 ) ) { - sol::object key( lua_state( ), -2 ); - sol::object value( lua_state( ), -1 ); - fx( key, value ); - lua_pop( lua_state( ), 1 ); - } - pop( ); - } + template + void for_each( Fx&& fx ) const { + push( ); + stack::push( lua_state( ), nil ); + while ( lua_next( this->lua_state( ), -2 ) ) { + sol::object key( lua_state( ), -2 ); + sol::object value( lua_state( ), -1 ); + fx( key, value ); + lua_pop( lua_state( ), 1 ); + } + pop( ); + } - size_t size( ) const { - push( ); - size_t result = lua_rawlen( lua_state( ), -1 ); - pop( ); - return result; - } + size_t size( ) const { + push( ); + size_t result = lua_rawlen( lua_state( ), -1 ); + pop( ); + return result; + } - template - proxy operator[]( T&& key ) { - return proxy( *this, std::forward( key ) ); - } + template + proxy operator[]( T&& key ) { + return proxy( *this, std::forward( key ) ); + } - template - proxy operator[]( T&& key ) const { - return proxy( *this, std::forward( key ) ); - } + template + proxy operator[]( T&& key ) const { + return proxy( *this, std::forward( key ) ); + } - void pop( int n = 1 ) const noexcept { - lua_pop( lua_state( ), n ); - } + void pop( int n = 1 ) const noexcept { + lua_pop( lua_state( ), n ); + } - template - table_core& set_function( Key&& key, R fun_ptr( Args... ) ) { - set_resolved_function( std::forward( key ), fun_ptr ); - return *this; - } + template + table_core& set_function( Key&& key, R fun_ptr( Args... ) ) { + set_resolved_function( std::forward( key ), fun_ptr ); + return *this; + } - template - table_core& set_function( Key&& key, Sig* fun_ptr ) { - set_resolved_function( std::forward( key ), fun_ptr ); - return *this; - } + template + table_core& set_function( Key&& key, Sig* fun_ptr ) { + set_resolved_function( std::forward( key ), fun_ptr ); + return *this; + } - template - table_core& set_function( Key&& key, R( C::*mem_ptr )( Args... ), T&& obj ) { - set_resolved_function( std::forward( key ), mem_ptr, std::forward( obj ) ); - return *this; - } + template + table_core& set_function( Key&& key, R( C::*mem_ptr )( Args... ), T&& obj ) { + set_resolved_function( std::forward( key ), mem_ptr, std::forward( obj ) ); + return *this; + } - template - table_core& set_function( Key&& key, Sig C::* mem_ptr, T&& obj ) { - set_resolved_function( std::forward( key ), mem_ptr, std::forward( obj ) ); - return *this; - } + template + table_core& set_function( Key&& key, Sig C::* mem_ptr, T&& obj ) { + set_resolved_function( std::forward( key ), mem_ptr, std::forward( obj ) ); + return *this; + } - template - table_core& set_function( Key&& key, Fx&& fx ) { - set_fx( types( ), std::forward( key ), std::forward( fx ) ); - return *this; - } + template + table_core& set_function( Key&& key, Fx&& fx ) { + set_fx( types( ), std::forward( key ), std::forward( fx ) ); + return *this; + } private: - template::type> - void set_fx( types, Key&& key, Fx&& fx ) { - set_resolved_function( std::forward( key ), std::forward( fx ) ); - } + template::type> + void set_fx( types, Key&& key, Fx&& fx ) { + set_resolved_function( std::forward( key ), std::forward( fx ) ); + } - template - void set_fx( types<>, Key&& key, Fx&& fx ) { - typedef Unqualified> fx_t; - typedef decltype( &fx_t::operator() ) Sig; - set_fx( types>( ), std::forward( key ), std::forward( fx ) ); - } + template + void set_fx( types<>, Key&& key, Fx&& fx ) { + typedef Unqualified> fx_t; + typedef decltype( &fx_t::operator() ) Sig; + set_fx( types>( ), std::forward( key ), std::forward( fx ) ); + } - template>>, Bool> = 0> - void set_resolved_function( Key&& key, Args&&... args ) { - stack::push>( lua_state( ), std::forward( args )... ); - lua_setglobal( lua_state( ), &key[ 0 ] ); - } + template>>, Bool> = 0> + void set_resolved_function( Key&& key, Args&&... args ) { + stack::push>( lua_state( ), std::forward( args )... ); + lua_setglobal( lua_state( ), &key[ 0 ] ); + } - template>>, Bool> = 0> - void set_resolved_function( Key&& key, Args&&... args ) { - push( ); - int tabletarget = lua_gettop( lua_state( ) ); - stack::push>( lua_state( ), std::forward( args )... ); - lua_setfield( lua_state( ), tabletarget, &key[ 0 ] ); - pop( ); - } + template>>, Bool> = 0> + void set_resolved_function( Key&& key, Args&&... args ) { + push( ); + int tabletarget = lua_gettop( lua_state( ) ); + stack::push>( lua_state( ), std::forward( args )... ); + lua_setfield( lua_state( ), tabletarget, &key[ 0 ] ); + pop( ); + } }; } // sol diff --git a/sol/traits.hpp b/sol/traits.hpp index 707be1be..c55ded3c 100644 --- a/sol/traits.hpp +++ b/sol/traits.hpp @@ -24,6 +24,7 @@ #include "tuple.hpp" #include +#include #include namespace sol { @@ -324,6 +325,35 @@ Unwrap unwrapper(std::reference_wrapper arg) { return arg.get(); } +template +T& unref(T& item) { + return item; +} + +template +T& unref(T* item) { + return *item; +} + +template +T& unref(std::unique_ptr& item) { + return *item; +} + +template +T& unref(std::shared_ptr& item) { + return *item; +} + +template +T& unref(const std::unique_ptr& item) { + return *item; +} + +template +T& unref(const std::shared_ptr& item) { + return *item; +} } // sol #endif // SOL_TRAITS_HPP diff --git a/sol/types.hpp b/sol/types.hpp index b7dc0d90..b46ef8ff 100644 --- a/sol/types.hpp +++ b/sol/types.hpp @@ -64,11 +64,11 @@ enum class call_syntax { }; enum class call_error : int { - ok = LUA_OK, - runtime = LUA_ERRRUN, - memory = LUA_ERRMEM, - handler = LUA_ERRERR, - gc = LUA_ERRGCMM + ok = LUA_OK, + runtime = LUA_ERRRUN, + memory = LUA_ERRMEM, + handler = LUA_ERRERR, + gc = LUA_ERRGCMM }; enum class type : int {