mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Proper semantics for set
/get
`set_function`/`set_usertype` now properly use `set` For the time being, we are going to avoid implementing `traverse`; aside from performance of nested table access (e.g. `int x = lua["a"]["b"]["c"]`), it's a pain. ;~;
This commit is contained in:
parent
b66c7f015a
commit
bb29127785
@ -14,4 +14,4 @@ int main( int argc, char* argv[] ) {
|
|||||||
bench_get( "bench/", configurationname, platformname );
|
bench_get( "bench/", configurationname, platformname );
|
||||||
bench_set( "bench/", configurationname, platformname );
|
bench_set( "bench/", configurationname, platformname );
|
||||||
bench_usertype( "bench/", configurationname, platformname );
|
bench_usertype( "bench/", configurationname, platformname );
|
||||||
}
|
}
|
||||||
|
@ -222,11 +222,11 @@ public:
|
|||||||
|
|
||||||
namespace stack {
|
namespace stack {
|
||||||
template<typename... Sigs>
|
template<typename... Sigs>
|
||||||
struct pusher<function_sig_t<Sigs...>> {
|
struct pusher<function_sig<Sigs...>> {
|
||||||
|
|
||||||
template<typename R, typename... Args, typename Fx, typename = typename std::result_of<Fx(Args...)>::type>
|
template<typename R, typename... Args, typename Fx, typename = typename std::result_of<Fx(Args...)>::type>
|
||||||
static void set_memfx(types<R(Args...)> t, lua_State* L, Fx&& fx) {
|
static void set_memfx(types<R(Args...)> t, lua_State* L, Fx&& fx) {
|
||||||
typedef Decay<Unwrap<Fx>> raw_fx_t;
|
typedef Decay<Unwrap<Unqualified<Fx>>> raw_fx_t;
|
||||||
typedef R(* fx_ptr_t)(Args...);
|
typedef R(* fx_ptr_t)(Args...);
|
||||||
typedef std::is_convertible<raw_fx_t, fx_ptr_t> is_convertible;
|
typedef std::is_convertible<raw_fx_t, fx_ptr_t> is_convertible;
|
||||||
set_isconvertible_fx(is_convertible(), t, L, std::forward<Fx>(fx));
|
set_isconvertible_fx(is_convertible(), t, L, std::forward<Fx>(fx));
|
||||||
@ -234,7 +234,7 @@ struct pusher<function_sig_t<Sigs...>> {
|
|||||||
|
|
||||||
template<typename Fx>
|
template<typename Fx>
|
||||||
static void set_memfx(types<>, lua_State* L, Fx&& fx) {
|
static void set_memfx(types<>, lua_State* L, Fx&& fx) {
|
||||||
typedef Unqualified<Unwrap<Fx>> fx_t;
|
typedef Unwrap<Unqualified<Fx>> fx_t;
|
||||||
typedef decltype(&fx_t::operator()) Sig;
|
typedef decltype(&fx_t::operator()) Sig;
|
||||||
set_memfx(types<function_signature_t<Sig>>(), L, std::forward<Fx>(fx));
|
set_memfx(types<function_signature_t<Sig>>(), L, std::forward<Fx>(fx));
|
||||||
}
|
}
|
||||||
@ -275,7 +275,7 @@ struct pusher<function_sig_t<Sigs...>> {
|
|||||||
|
|
||||||
template<typename Fx, typename R, typename... Args>
|
template<typename Fx, typename R, typename... Args>
|
||||||
static void set_isconvertible_fx(std::false_type, types<R(Args...)>, lua_State* L, Fx&& fx) {
|
static void set_isconvertible_fx(std::false_type, types<R(Args...)>, lua_State* L, Fx&& fx) {
|
||||||
typedef Decay<Unwrap<Fx>> fx_t;
|
typedef Unwrap<Decay<Fx>> fx_t;
|
||||||
std::unique_ptr<base_function> sptr(new functor_function<fx_t>(std::forward<Fx>(fx)));
|
std::unique_ptr<base_function> sptr(new functor_function<fx_t>(std::forward<Fx>(fx)));
|
||||||
set_fx<Fx>(L, std::move(sptr));
|
set_fx<Fx>(L, std::move(sptr));
|
||||||
}
|
}
|
||||||
@ -349,10 +349,23 @@ struct pusher<function_sig_t<Sigs...>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
struct pusher<sol::detail::function_packer<T, Args...>> {
|
||||||
|
template <std::size_t... I, typename FP>
|
||||||
|
static int push_func(indices<I...>, lua_State* L, FP&& fp) {
|
||||||
|
return stack::push<T>(L, std::get<I>(fp)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FP>
|
||||||
|
static int push(lua_State* L, FP&& fp) {
|
||||||
|
return push_func(build_indices<sizeof...(Args)>(), L, std::forward<FP>(fp));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Signature>
|
template<typename Signature>
|
||||||
struct pusher<std::function<Signature>> {
|
struct pusher<std::function<Signature>> {
|
||||||
static int push(lua_State* L, std::function<Signature> fx) {
|
static int push(lua_State* L, std::function<Signature> fx) {
|
||||||
return pusher<function_t>{}.push(L, std::move(fx));
|
return pusher<function_sig<>>{}.push(L, std::move(fx));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,6 +34,14 @@ struct ref_call_t {
|
|||||||
|
|
||||||
const auto ref_call = ref_call_t{};
|
const auto ref_call = ref_call_t{};
|
||||||
|
|
||||||
|
template <typename Sig, typename... Args>
|
||||||
|
struct function_packer : std::tuple<Args...> { using std::tuple<Args...>::tuple; };
|
||||||
|
|
||||||
|
template <typename Sig, typename... Args>
|
||||||
|
function_packer<Sig, Args...> function_pack( Args&&... args ) {
|
||||||
|
return function_packer<Sig, Args...>(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T, typename Func, typename = void>
|
template<typename T, typename Func, typename = void>
|
||||||
struct functor {
|
struct functor {
|
||||||
typedef member_traits<Func> traits_type;
|
typedef member_traits<Func> traits_type;
|
||||||
|
@ -26,15 +26,20 @@
|
|||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
namespace stack {
|
namespace stack {
|
||||||
template <typename T>
|
template <bool top_level, typename T>
|
||||||
struct push_pop {
|
struct push_pop {
|
||||||
T t;
|
T t;
|
||||||
push_pop (T x) : t(x) { t.push(); }
|
push_pop (T x) : t(x) { t.push(); }
|
||||||
~push_pop() { t.pop(); }
|
~push_pop() { t.pop(); }
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
push_pop<T> push_popper(T&& x) {
|
struct push_pop<true, T> {
|
||||||
return push_pop<T>(std::forward<T>(x));
|
push_pop (T x) {}
|
||||||
|
~push_pop() {}
|
||||||
|
};
|
||||||
|
template <bool top_level = false, typename T>
|
||||||
|
push_pop<top_level, T> push_popper(T&& x) {
|
||||||
|
return push_pop<top_level, T>(std::forward<T>(x));
|
||||||
};
|
};
|
||||||
} // stack
|
} // stack
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class table_core : public reference {
|
|||||||
template<typename T, typename Key, EnableIf<Not<Bool<top_level>>, is_c_str<Key>> = 0>
|
template<typename T, typename Key, EnableIf<Not<Bool<top_level>>, is_c_str<Key>> = 0>
|
||||||
decltype(auto) single_get( Key&& key ) const {
|
decltype(auto) single_get( Key&& key ) const {
|
||||||
auto pp = stack::push_popper(*this);
|
auto pp = stack::push_popper(*this);
|
||||||
lua_getfield( lua_state( ), -2, &key[0] );
|
lua_getfield( lua_state( ), -1, &key[0] );
|
||||||
return stack::pop<T>( lua_state( ) );
|
return stack::pop<T>( lua_state( ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,17 +66,19 @@ class table_core : public reference {
|
|||||||
|
|
||||||
template<typename Key, typename Value, EnableIf<Not<Bool<top_level>>, is_c_str<Key>> = 0>
|
template<typename Key, typename Value, EnableIf<Not<Bool<top_level>>, is_c_str<Key>> = 0>
|
||||||
void single_set(Key&& key, Value&& value) {
|
void single_set(Key&& key, Value&& value) {
|
||||||
auto pp = stack::push_popper(*this);
|
push();
|
||||||
stack::push(lua_state(), std::forward<Value>(value));
|
stack::push(lua_state(), std::forward<Value>(value));
|
||||||
lua_setfield(lua_state(), -3, &key[0]);
|
lua_setfield(lua_state(), -2, &key[0]);
|
||||||
|
pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Key, typename Value, EnableIf<Not<is_c_str<Key>>> = 0>
|
template<typename Key, typename Value, EnableIf<Not<is_c_str<Key>>> = 0>
|
||||||
void single_set(Key&& key, Value&& value) {
|
void single_set(Key&& key, Value&& value) {
|
||||||
auto pp = stack::push_popper(*this);
|
push();
|
||||||
stack::push(lua_state(), std::forward<Key>(key));
|
stack::push(lua_state(), std::forward<Key>(key));
|
||||||
stack::push(lua_state(), std::forward<Value>(value));
|
stack::push(lua_state(), std::forward<Value>(value));
|
||||||
lua_settable(lua_state(), -3);
|
lua_settable(lua_state(), -3);
|
||||||
|
pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Keys, typename... Ret, std::size_t... I>
|
template<typename Keys, typename... Ret, std::size_t... I>
|
||||||
@ -125,27 +127,17 @@ public:
|
|||||||
|
|
||||||
template<typename Key, typename T>
|
template<typename Key, typename T>
|
||||||
SOL_DEPRECATED table_core& set_userdata( Key&& key, usertype<T>& user ) {
|
SOL_DEPRECATED table_core& set_userdata( Key&& key, usertype<T>& user ) {
|
||||||
return set_usertype( std::forward<Key>( key ), user );
|
return set_usertype(std::forward<Key>(key), user);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
table_core& set_usertype( usertype<T>& user ) {
|
table_core& set_usertype( usertype<T>& user ) {
|
||||||
return set_usertype( usertype_traits<T>::name, user );
|
return set_usertype(usertype_traits<T>::name, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Key, typename T>
|
template<typename Key, typename T>
|
||||||
table_core& set_usertype( Key&& key, usertype<T>& user ) {
|
table_core& set_usertype( Key&& key, usertype<T>& user ) {
|
||||||
if ( top_level ) {
|
return set(std::forward<Key>(key), user);
|
||||||
stack::push( lua_state( ), user );
|
|
||||||
lua_setglobal( lua_state( ), &key[ 0 ] );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
auto pp = stack::push_popper( *this );
|
|
||||||
stack::push( lua_state( ), std::forward<Key>( key ) );
|
|
||||||
stack::push( lua_state( ), user );
|
|
||||||
lua_settable( lua_state( ), -3 );
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fx>
|
template<typename Fx>
|
||||||
@ -227,27 +219,9 @@ private:
|
|||||||
set_fx( types<function_signature_t<Sig>>( ), std::forward<Key>( key ), std::forward<Fx>( fx ) );
|
set_fx( types<function_signature_t<Sig>>( ), std::forward<Key>( key ), std::forward<Fx>( fx ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Sig, typename... Args, typename Key, EnableIf<Bool<top_level>, is_c_str<Key>> = 0>
|
template<typename... Sig, typename... Args, typename Key>
|
||||||
void set_resolved_function( Key&& key, Args&&... args ) {
|
void set_resolved_function( Key&& key, Args&&... args ) {
|
||||||
stack::push<function_sig_t<Sig...>>( lua_state( ), std::forward<Args>( args )... );
|
set(std::forward<Key>(key), detail::function_pack<function_sig<Sig...>>(std::forward<Args>(args)...));
|
||||||
lua_setglobal( lua_state( ), &key[ 0 ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Sig, typename... Args, typename Key, EnableIf<Not<Bool<top_level>>, is_c_str<Key>> = 0>
|
|
||||||
void set_resolved_function( Key&& key, Args&&... args ) {
|
|
||||||
auto pp = stack::push_popper( *this );
|
|
||||||
int tabletarget = lua_gettop( lua_state( ) );
|
|
||||||
stack::push<function_sig_t<Sig...>>( lua_state( ), std::forward<Args>( args )... );
|
|
||||||
lua_setfield( lua_state( ), tabletarget, &key[ 0 ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Sig, typename... Args, typename Key, EnableIf<Not<is_c_str<Key>>> = 0>
|
|
||||||
void set_resolved_function( Key&& key, Args&&... args ) {
|
|
||||||
auto pp = stack::push_popper( *this );
|
|
||||||
int tabletarget = lua_gettop( lua_state( ) );
|
|
||||||
stack::push(lua_state(), std::forward<Key>(key));
|
|
||||||
stack::push<function_sig_t<Sig...>>( lua_state( ), std::forward<Args>( args )... );
|
|
||||||
lua_settable( lua_state( ), tabletarget );
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // sol
|
} // sol
|
||||||
|
@ -316,7 +316,7 @@ template <typename T>
|
|||||||
using is_string_constructible = Or<std::is_same<Unqualified<T>, const char*>, std::is_same<Unqualified<T>, char>, std::is_same<Unqualified<T>, std::string>, std::is_same<Unqualified<T>, std::initializer_list<char>>>;
|
using is_string_constructible = Or<std::is_same<Unqualified<T>, const char*>, std::is_same<Unqualified<T>, char>, std::is_same<Unqualified<T>, std::string>, std::is_same<Unqualified<T>, std::initializer_list<char>>>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using is_c_str = Or<std::is_same<std::decay_t<Unqualified<T>>, const char*>, std::is_same<Unqualified<T>, std::string>>;
|
using is_c_str = Or<std::is_same<std::decay_t<Unqualified<T>>, char*>, std::is_same<Unqualified<T>, std::string>>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto unwrapper(T&& item) -> decltype(std::forward<T>(item)) {
|
auto unwrapper(T&& item) -> decltype(std::forward<T>(item)) {
|
||||||
|
@ -36,9 +36,8 @@ inline bool operator!=(nil_t, nil_t) { return false; }
|
|||||||
struct void_type : types<void> {}; // This is important because it allows myobject.call( Void, ... ) to work
|
struct void_type : types<void> {}; // This is important because it allows myobject.call( Void, ... ) to work
|
||||||
const void_type Void {};
|
const void_type Void {};
|
||||||
|
|
||||||
template<typename... T>
|
template<typename... Args>
|
||||||
struct function_sig_t {};
|
struct function_sig {};
|
||||||
using function_t = function_sig_t<>;
|
|
||||||
|
|
||||||
struct upvalue {
|
struct upvalue {
|
||||||
void* value;
|
void* value;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user