mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Formatting changes.
This commit is contained in:
parent
2a5b800286
commit
da76793c30
|
@ -27,26 +27,25 @@
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
namespace debug {
|
namespace debug {
|
||||||
|
|
||||||
inline std::string dump_types(lua_State* L) {
|
inline std::string dump_types(lua_State* L) {
|
||||||
std::string visual;
|
std::string visual;
|
||||||
std::size_t size = lua_gettop(L) + 1;
|
std::size_t size = lua_gettop(L) + 1;
|
||||||
for (std::size_t i = 1; i < size; ++i) {
|
for(std::size_t i = 1; i < size; ++i) {
|
||||||
if (i != 1)
|
if(i != 1) {
|
||||||
visual += " | ";
|
visual += " | ";
|
||||||
|
}
|
||||||
visual += type_name(L, stack::get<type>(L, i));
|
visual += type_name(L, stack::get<type>(L, i));
|
||||||
}
|
}
|
||||||
return visual;
|
return visual;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void print_stack (lua_State* L) {
|
inline void print_stack(lua_State* L) {
|
||||||
std::cout << dump_types(L) << std::endl;
|
std::cout << dump_types(L) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void print_section (const std::string& message, lua_State* L) {
|
inline void print_section(const std::string& message, lua_State* L) {
|
||||||
std::cout << "-- " << message << " -- [ " << dump_types(L) << " ]" << std::endl;
|
std::cout << "-- " << message << " -- [ " << dump_types(L) << " ]" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // debug
|
} // debug
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "traits.hpp"
|
#include "traits.hpp"
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
|
||||||
struct default_construct {
|
struct default_construct {
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
void operator()(T&& obj, Args&&... args) const {
|
void operator()(T&& obj, Args&&... args) const {
|
||||||
|
@ -34,7 +33,6 @@ struct default_construct {
|
||||||
alloc.construct(obj, std::forward<Args>(args)...);
|
alloc.construct(obj, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
#endif // SOL_DEFAULT_CONSTRUCTOR_HPP
|
#endif // SOL_DEFAULT_CONSTRUCTOR_HPP
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
namespace sol {
|
namespace sol {
|
||||||
class function : public reference {
|
class function : public reference {
|
||||||
private:
|
private:
|
||||||
void luacall (std::size_t argcount, std::size_t resultcount) const {
|
void luacall(std::size_t argcount, std::size_t resultcount) const {
|
||||||
lua_call(state(), static_cast<uint32_t>(argcount), static_cast<uint32_t>(resultcount));
|
lua_call(state(), static_cast<uint32_t>(argcount), static_cast<uint32_t>(resultcount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
function() : reference() {}
|
function() = default;
|
||||||
function(lua_State* L, int index = -1): reference(L, index) {
|
function(lua_State* L, int index = -1): reference(L, index) {
|
||||||
type_assert(L, index, type::function);
|
type_assert(L, index, type::function);
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ struct pusher<function_sig_t<Sigs...>> {
|
||||||
void* userdata = reinterpret_cast<void*>(target);
|
void* userdata = reinterpret_cast<void*>(target);
|
||||||
lua_CFunction freefunc = &base_function::call;
|
lua_CFunction freefunc = &base_function::call;
|
||||||
|
|
||||||
if (luaL_newmetatable(L, metatablename) == 1) {
|
if(luaL_newmetatable(L, metatablename) == 1) {
|
||||||
lua_pushstring(L, "__gc");
|
lua_pushstring(L, "__gc");
|
||||||
stack::push(L, &base_function::gc);
|
stack::push(L, &base_function::gc);
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
|
@ -231,7 +231,7 @@ struct getter<std::function<Signature>> {
|
||||||
static std::function<Signature> get_std_func(types<FxArgs...>, types<Ret...>, lua_State* L, int index = -1) {
|
static std::function<Signature> get_std_func(types<FxArgs...>, types<Ret...>, lua_State* L, int index = -1) {
|
||||||
typedef typename function_traits<Signature>::return_type return_t;
|
typedef typename function_traits<Signature>::return_type return_t;
|
||||||
sol::function f(L, index);
|
sol::function f(L, index);
|
||||||
auto fx = [ f, L, index ] (FxArgs&&... args) -> return_t {
|
auto fx = [f, L, index](FxArgs&&... args) -> return_t {
|
||||||
return f(types<Ret...>(), std::forward<FxArgs>(args)...);
|
return f(types<Ret...>(), std::forward<FxArgs>(args)...);
|
||||||
};
|
};
|
||||||
return std::move(fx);
|
return std::move(fx);
|
||||||
|
@ -240,7 +240,7 @@ struct getter<std::function<Signature>> {
|
||||||
template<typename... FxArgs>
|
template<typename... FxArgs>
|
||||||
static std::function<Signature> get_std_func(types<FxArgs...>, types<void>, lua_State* L, int index = -1) {
|
static std::function<Signature> get_std_func(types<FxArgs...>, types<void>, lua_State* L, int index = -1) {
|
||||||
sol::function f(L, index);
|
sol::function f(L, index);
|
||||||
auto fx = [ f, L, index ] (FxArgs&&... args) -> void {
|
auto fx = [f, L, index](FxArgs&&... args) -> void {
|
||||||
f(std::forward<FxArgs>(args)...);
|
f(std::forward<FxArgs>(args)...);
|
||||||
};
|
};
|
||||||
return std::move(fx);
|
return std::move(fx);
|
||||||
|
|
|
@ -202,7 +202,7 @@ struct static_member_function {
|
||||||
|
|
||||||
struct base_function {
|
struct base_function {
|
||||||
static int base_call(lua_State* L, void* inheritancedata) {
|
static int base_call(lua_State* L, void* inheritancedata) {
|
||||||
if (inheritancedata == nullptr) {
|
if(inheritancedata == nullptr) {
|
||||||
throw error("call from Lua to C++ function has null data");
|
throw error("call from Lua to C++ function has null data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ struct base_function {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ref_base_call(lua_State* L, void* inheritancedata) {
|
static int ref_base_call(lua_State* L, void* inheritancedata) {
|
||||||
if (inheritancedata == nullptr) {
|
if(inheritancedata == nullptr) {
|
||||||
throw error("call from Lua to C++ function has null data");
|
throw error("call from Lua to C++ function has null data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ struct base_function {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int base_gc(lua_State*, void* udata) {
|
static int base_gc(lua_State*, void* udata) {
|
||||||
if (udata == nullptr) {
|
if(udata == nullptr) {
|
||||||
throw error("call from lua to C++ gc function with null data");
|
throw error("call from lua to C++ gc function with null data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ struct base_function {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gc(lua_State* L) {
|
static int gc(lua_State* L) {
|
||||||
for (std::size_t i = 0; i < I; ++i) {
|
for(std::size_t i = 0; i < I; ++i) {
|
||||||
upvalue_t up = stack::get<upvalue_t>(L, i + 1);
|
upvalue_t up = stack::get<upvalue_t>(L, i + 1);
|
||||||
base_function* obj = static_cast<base_function*>(up.value);
|
base_function* obj = static_cast<base_function*>(up.value);
|
||||||
std::allocator<base_function> alloc{};
|
std::allocator<base_function> alloc{};
|
||||||
|
@ -385,7 +385,7 @@ struct userdata_function_core : public base_function {
|
||||||
|
|
||||||
template<typename Return, typename Raw = Unqualified<Return>>
|
template<typename Return, typename Raw = Unqualified<Return>>
|
||||||
typename std::enable_if<std::is_same<T, Raw>::value, void>::type push(lua_State* L, Return&& r) {
|
typename std::enable_if<std::is_same<T, Raw>::value, void>::type push(lua_State* L, Return&& r) {
|
||||||
if (detail::get_ptr(r) == fx.item) {
|
if(detail::get_ptr(r) == fx.item) {
|
||||||
// push nothing
|
// push nothing
|
||||||
// note that pushing nothing with the ':'
|
// note that pushing nothing with the ':'
|
||||||
// syntax means we leave the instance of what
|
// syntax means we leave the instance of what
|
||||||
|
@ -442,8 +442,9 @@ struct userdata_function : public userdata_function_core<Function, Tp> {
|
||||||
template<typename Tx>
|
template<typename Tx>
|
||||||
int fx_call(lua_State* L) {
|
int fx_call(lua_State* L) {
|
||||||
this->fx.item = detail::get_ptr(stack::get<Tx>(L, 1));
|
this->fx.item = detail::get_ptr(stack::get<Tx>(L, 1));
|
||||||
if (this->fx.item == nullptr)
|
if(this->fx.item == nullptr) {
|
||||||
throw error("userdata for function call is null: are you using the wrong syntax? (use item:function/variable(...) syntax)");
|
throw error("userdata for function call is null: are you using the wrong syntax? (use item:function/variable(...) syntax)");
|
||||||
|
}
|
||||||
return static_cast<base_t&>(*this)(tuple_types<return_type>(), args_type(), L);
|
return static_cast<base_t&>(*this)(tuple_types<return_type>(), args_type(), L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,12 +469,14 @@ struct userdata_variable_function : public userdata_function_core<Function, Tp>
|
||||||
userdata_variable_function(FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...) {}
|
userdata_variable_function(FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...) {}
|
||||||
|
|
||||||
template<typename Tx>
|
template<typename Tx>
|
||||||
int fx_call (lua_State* L) {
|
int fx_call(lua_State* L) {
|
||||||
this->fx.item = detail::get_ptr(stack::get<Tx>(L, 1));
|
this->fx.item = detail::get_ptr(stack::get<Tx>(L, 1));
|
||||||
if (this->fx.item == nullptr)
|
if(this->fx.item == nullptr) {
|
||||||
throw error("userdata for member variable is null");
|
throw error("userdata for member variable is null");
|
||||||
|
}
|
||||||
|
|
||||||
int argcount = lua_gettop(L);
|
int argcount = lua_gettop(L);
|
||||||
switch (argcount) {
|
switch(argcount) {
|
||||||
case 2:
|
case 2:
|
||||||
return static_cast<base_t&>(*this)(tuple_types<return_type>(), types<>(), L);
|
return static_cast<base_t&>(*this)(tuple_types<return_type>(), types<>(), L);
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -508,31 +511,29 @@ struct userdata_indexing_function : public userdata_function_core<Function, Tp>
|
||||||
userdata_indexing_function(std::string name, FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...), name(std::move(name)) {}
|
userdata_indexing_function(std::string name, FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...), name(std::move(name)) {}
|
||||||
|
|
||||||
template<typename Tx>
|
template<typename Tx>
|
||||||
int fx_call (lua_State* L) {
|
int fx_call(lua_State* L) {
|
||||||
std::string accessor = stack::get<std::string>(L, 1 - lua_gettop(L));
|
std::string accessor = stack::get<std::string>(L, 1 - lua_gettop(L));
|
||||||
auto function = functions.find(accessor);
|
auto function = functions.find(accessor);
|
||||||
if (function != functions.end()) {
|
if(function != functions.end()) {
|
||||||
if (function->second.second) {
|
if(function->second.second) {
|
||||||
stack::push<upvalue_t>(L, function->second.first.get());
|
stack::push<upvalue_t>(L, function->second.first.get());
|
||||||
if (std::is_same<T*, Tx>::value)
|
if(std::is_same<T*, Tx>::value) {
|
||||||
stack::push(L, &base_function::userdata<0>::ref_call, 1);
|
stack::push(L, &base_function::userdata<0>::ref_call, 1);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
stack::push(L, &base_function::userdata<0>::call, 1);
|
stack::push(L, &base_function::userdata<0>::call, 1);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else if(std::is_same<T*, Tx>::value) {
|
||||||
|
return (*function->second.first)(L, detail::ref_call);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (std::is_same<T*, Tx>::value)
|
return (*function->second.first)(L);
|
||||||
return (*function->second.first)(L, detail::ref_call);
|
|
||||||
else
|
|
||||||
return (*function->second.first)(L);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this->fx.invocation == nullptr) {
|
if(this->fx.invocation == nullptr) {
|
||||||
std::string err = "invalid indexing \"";
|
throw error("invalid indexing \"" + accessor + "\" on type: " + name);
|
||||||
err += accessor;
|
|
||||||
err += "\" on type: ";
|
|
||||||
err += name;
|
|
||||||
throw error(err);
|
|
||||||
}
|
}
|
||||||
this->fx.item = detail::get_ptr(stack::get<Tx>(L, 1));
|
this->fx.item = detail::get_ptr(stack::get<Tx>(L, 1));
|
||||||
return static_cast<base_t&>(*this)(tuple_types<return_type>(), args_type(), L);
|
return static_cast<base_t&>(*this)(tuple_types<return_type>(), args_type(), L);
|
||||||
|
|
|
@ -65,7 +65,7 @@ public:
|
||||||
tbl.set(key, std::forward<U>(other));
|
tbl.set(key, std::forward<U>(other));
|
||||||
}
|
}
|
||||||
|
|
||||||
operator nil_t () const {
|
operator nil_t() const {
|
||||||
return get<nil_t>();
|
return get<nil_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,68 +27,68 @@
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<class R, class... Args, class F, class = typename std::result_of<Unqualified<F>( Args... )>::type>
|
template<typename R, typename... Args, typename F, typename = typename std::result_of<Unqualified<F>(Args...)>::type>
|
||||||
auto resolve_i( types<R( Args... )>, F&& )->R( Unqualified<F>::* )( Args... ) {
|
auto resolve_i(types<R(Args...)>, F&&)->R(Unqualified<F>::*)(Args...) {
|
||||||
typedef R( Sig )( Args... );
|
using Sig = R(Args...);
|
||||||
typedef Unqualified<F> Fu;
|
typedef Unqualified<F> Fu;
|
||||||
return static_cast<Sig Fu::*>( &Fu::operator() );
|
return static_cast<Sig Fu::*>(&Fu::operator());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class F>
|
template<typename F, typename U = Unqualified<F>>
|
||||||
auto resolve_f( std::true_type, F&& f ) -> decltype( resolve_i( types<function_signature_t<decltype( &Unqualified<F>::operator() )>>( ), std::forward<F>( f ) ) ) {
|
auto resolve_f(std::true_type, F&& f) -> decltype(resolve_i(types<function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
|
||||||
typedef Unqualified<F> Fu;
|
return resolve_i(types<function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
|
||||||
return resolve_i( types<function_signature_t<decltype( &Fu::operator() )>>( ), std::forward<F>( f ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class F>
|
template<typename F>
|
||||||
void resolve_f( std::false_type, F&& ) {
|
void resolve_f(std::false_type, F&&) {
|
||||||
static_assert( has_deducible_signature<F>::value, "Cannot use no-template-parameter call with an overloaded functor: specify the signature" );
|
static_assert(has_deducible_signature<F>::value,
|
||||||
|
"Cannot use no-template-parameter call with an overloaded functor: specify the signature");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class F>
|
template<typename F, typename U = Unqualified<F>>
|
||||||
auto resolve_i( types<>, F&& f ) -> decltype( resolve_f( has_deducible_signature<Unqualified<F>> {}, std::forward<F>( f ) ) ) {
|
auto resolve_i(types<>, F&& f) -> decltype(resolve_f(has_deducible_signature<U> {}, std::forward<F>(f))) {
|
||||||
return resolve_f( has_deducible_signature<Unqualified<F>> {}, std::forward<F>( f ) );
|
return resolve_f(has_deducible_signature<U> {}, std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class... Args, class F, class R = typename std::result_of<F&( Args... )>::type>
|
template<typename... Args, typename F, typename R = typename std::result_of<F&(Args...)>::type>
|
||||||
auto resolve_i( types<Args...>, F&& f ) -> decltype( resolve_i( types<R( Args... )>( ), std::forward<F>( f ) ) ) {
|
auto resolve_i(types<Args...>, F&& f) -> decltype( resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
|
||||||
return resolve_i( types<R( Args... )>( ), std::forward<F>( f ) );
|
return resolve_i(types<R(Args...)>(), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Sig, class C>
|
template<typename Sig, typename C>
|
||||||
Sig C::* resolve_v( std::false_type, Sig C::* mem_func_ptr ) {
|
Sig C::* resolve_v(std::false_type, Sig C::* mem_func_ptr) {
|
||||||
return mem_func_ptr;
|
return mem_func_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Sig, class C>
|
template<typename Sig, typename C>
|
||||||
Sig C::* resolve_v( std::true_type, Sig C::* mem_variable_ptr ) {
|
Sig C::* resolve_v(std::true_type, Sig C::* mem_variable_ptr) {
|
||||||
return mem_variable_ptr;
|
return mem_variable_ptr;
|
||||||
}
|
}
|
||||||
} // detail
|
} // detail
|
||||||
|
|
||||||
template<class... Args, class R>
|
template<typename... Args, typename R>
|
||||||
auto resolve( R fun_ptr( Args... ) ) -> R( *)( Args... ) {
|
auto resolve(R fun_ptr(Args...)) -> R(*)(Args...) {
|
||||||
return fun_ptr;
|
return fun_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Sig>
|
template<typename Sig>
|
||||||
Sig* resolve( Sig* fun_ptr ) {
|
Sig* resolve(Sig* fun_ptr) {
|
||||||
return fun_ptr;
|
return fun_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class... Args, class R, class C>
|
template<typename... Args, typename R, typename C>
|
||||||
auto resolve( R( C::*mem_ptr )( Args... ) ) -> R( C::* )( Args... ) {
|
auto resolve(R(C::*mem_ptr)(Args...)) -> R(C::*)(Args...) {
|
||||||
return mem_ptr;
|
return mem_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Sig, class C>
|
template<typename Sig, typename C>
|
||||||
Sig C::* resolve( Sig C::* mem_ptr ) {
|
Sig C::* resolve(Sig C::* mem_ptr) {
|
||||||
return detail::resolve_v( std::is_member_object_pointer<Sig C::*>( ), mem_ptr );
|
return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class... Sig, class F>
|
template<typename... Sig, typename F>
|
||||||
auto resolve( F&& f ) -> decltype( detail::resolve_i( types<Sig...>( ), std::forward<F>( f ) ) ) {
|
auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
||||||
return detail::resolve_i( types<Sig...>( ), std::forward<F>( f ) );
|
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
|
|
|
@ -160,8 +160,9 @@ struct getter<const char*> {
|
||||||
template<>
|
template<>
|
||||||
struct getter<nil_t> {
|
struct getter<nil_t> {
|
||||||
static nil_t get(lua_State* L, int index = -1) {
|
static nil_t get(lua_State* L, int index = -1) {
|
||||||
if (lua_isnil(L, index) == 0)
|
if(lua_isnil(L, index) == 0) {
|
||||||
throw sol::error("not nil");
|
throw sol::error("not nil");
|
||||||
|
}
|
||||||
return nil_t{ };
|
return nil_t{ };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -377,7 +378,7 @@ inline int push_as_upvalues(lua_State* L, T& item) {
|
||||||
|
|
||||||
data_t data{{}};
|
data_t data{{}};
|
||||||
std::memcpy(std::addressof(data[0]), std::addressof(item), itemsize);
|
std::memcpy(std::addressof(data[0]), std::addressof(item), itemsize);
|
||||||
for (auto&& v : data) {
|
for(auto&& v : data) {
|
||||||
push(L, upvalue_t(v));
|
push(L, upvalue_t(v));
|
||||||
}
|
}
|
||||||
return data_t_count;
|
return data_t_count;
|
||||||
|
@ -388,7 +389,7 @@ inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 1) {
|
||||||
const static std::size_t data_t_count = (sizeof(T)+(sizeof(void*)-1)) / sizeof(void*);
|
const static std::size_t data_t_count = (sizeof(T)+(sizeof(void*)-1)) / sizeof(void*);
|
||||||
typedef std::array<void*, data_t_count> data_t;
|
typedef std::array<void*, data_t_count> data_t;
|
||||||
data_t voiddata{ {} };
|
data_t voiddata{ {} };
|
||||||
for (std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) {
|
for(std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) {
|
||||||
voiddata[i] = get<upvalue_t>(L, index++);
|
voiddata[i] = get<upvalue_t>(L, index++);
|
||||||
}
|
}
|
||||||
return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
|
return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
|
||||||
|
@ -475,8 +476,8 @@ inline auto pop_reverse_call(lua_State* L, TFx&& fx, types<Args...> t) -> declty
|
||||||
}
|
}
|
||||||
|
|
||||||
inline call_syntax get_call_syntax(lua_State* L, const std::string& meta) {
|
inline call_syntax get_call_syntax(lua_State* L, const std::string& meta) {
|
||||||
if (get<type>(L, 1) == type::table) {
|
if(get<type>(L, 1) == type::table) {
|
||||||
if (luaL_newmetatable(L, meta.c_str()) == 0) {
|
if(luaL_newmetatable(L, meta.c_str()) == 0) {
|
||||||
lua_settop(L, -2);
|
lua_settop(L, -2);
|
||||||
return call_syntax::colon;
|
return call_syntax::colon;
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void open_file(const std::string& filename) {
|
void open_file(const std::string& filename) {
|
||||||
if (luaL_dofile(L.get(), filename.c_str())) {
|
if(luaL_dofile(L.get(), filename.c_str())) {
|
||||||
lua_error(L.get());
|
lua_error(L.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,11 +147,11 @@ struct is_function_impl<T, true> {
|
||||||
template<class F>
|
template<class F>
|
||||||
struct check_deducible_signature {
|
struct check_deducible_signature {
|
||||||
template<class G>
|
template<class G>
|
||||||
static auto test( int ) -> decltype( &G::operator(), void( ) );
|
static auto test(int) -> decltype(&G::operator(), void());
|
||||||
template<class>
|
template<class>
|
||||||
static auto test( ... ) -> struct nat;
|
static auto test(...) -> struct nat;
|
||||||
|
|
||||||
using type = std::is_void < decltype( test<F>( 0 ) ) > ;
|
using type = std::is_void<decltype(test<F>(0))>;
|
||||||
};
|
};
|
||||||
} // detail
|
} // detail
|
||||||
|
|
||||||
|
|
|
@ -39,19 +39,19 @@ using function_t = function_sig_t<>;
|
||||||
struct upvalue_t {
|
struct upvalue_t {
|
||||||
void* value;
|
void* value;
|
||||||
upvalue_t(void* data) : value(data) {}
|
upvalue_t(void* data) : value(data) {}
|
||||||
operator void* () const { return value; }
|
operator void*() const { return value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lightuserdata_t {
|
struct lightuserdata_t {
|
||||||
void* value;
|
void* value;
|
||||||
lightuserdata_t(void* data) : value(data) {}
|
lightuserdata_t(void* data) : value(data) {}
|
||||||
operator void* () const { return value; }
|
operator void*() const { return value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct userdata_t {
|
struct userdata_t {
|
||||||
void* value;
|
void* value;
|
||||||
userdata_t(void* data) : value(data) {}
|
userdata_t(void* data) : value(data) {}
|
||||||
operator void* () const { return value; }
|
operator void*() const { return value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class call_syntax {
|
enum class call_syntax {
|
||||||
|
|
|
@ -113,7 +113,7 @@ private:
|
||||||
|
|
||||||
template<typename ...CArgs, typename... Args>
|
template<typename ...CArgs, typename... Args>
|
||||||
static void match_constructor(lua_State* L, T* obj, call_syntax syntax, int argcount, types<CArgs...> t, Args&&... args) {
|
static void match_constructor(lua_State* L, T* obj, call_syntax syntax, int argcount, types<CArgs...> t, Args&&... args) {
|
||||||
if (argcount == sizeof...(CArgs)) {
|
if(argcount == sizeof...(CArgs)) {
|
||||||
do_constructor(L, obj, syntax, argcount, t);
|
do_constructor(L, obj, syntax, argcount, t);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ private:
|
||||||
T* obj = static_cast<T*>(udata);
|
T* obj = static_cast<T*>(udata);
|
||||||
match_constructor(L, obj, syntax, argcount - static_cast<int>(syntax), typename identity<TTypes>::type()...);
|
match_constructor(L, obj, syntax, argcount - static_cast<int>(syntax), typename identity<TTypes>::type()...);
|
||||||
|
|
||||||
if (luaL_newmetatable(L, std::addressof(meta[0])) == 1) {
|
if(luaL_newmetatable(L, std::addressof(meta[0])) == 1) {
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
std::string err = "Unable to get userdata metatable for ";
|
std::string err = "Unable to get userdata metatable for ";
|
||||||
err += meta;
|
err += meta;
|
||||||
|
@ -152,52 +152,52 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
void build_cleanup () {
|
void build_cleanup() {
|
||||||
cleanup = &base_function::userdata<N>::gc;
|
cleanup = &base_function::userdata<N>::gc;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
void build_function_tables(function_map_t*& index, function_map_t*& newindex) {
|
void build_function_tables(function_map_t*& index, function_map_t*& newindex) {
|
||||||
int extracount = 0;
|
int extracount = 0;
|
||||||
if (!indexmetafunctions.empty()) {
|
if(!indexmetafunctions.empty()) {
|
||||||
if (index == nullptr) {
|
if(index == nullptr) {
|
||||||
auto idxptr = detail::make_unique<userdata_indexing_function<void (T::*)(), T>>("__index", nullptr);
|
auto idxptr = detail::make_unique<userdata_indexing_function<void (T::*)(), T>>("__index", nullptr);
|
||||||
index = &(idxptr->functions);
|
index = &(idxptr->functions);
|
||||||
functionnames.emplace_back("__index");
|
functionnames.emplace_back("__index");
|
||||||
metafunctions.emplace_back(std::move(idxptr));
|
metafunctions.emplace_back(std::move(idxptr));
|
||||||
std::string& name = functionnames.back();
|
std::string& name = functionnames.back();
|
||||||
metafunctiontable.push_back( { name.c_str(), &base_function::userdata<N>::call } );
|
metafunctiontable.push_back({ name.c_str(), &base_function::userdata<N>::call });
|
||||||
ptrmetafunctiontable.push_back( { name.c_str(), &base_function::userdata<N>::ref_call } );
|
ptrmetafunctiontable.push_back({ name.c_str(), &base_function::userdata<N>::ref_call });
|
||||||
++extracount;
|
++extracount;
|
||||||
}
|
}
|
||||||
auto& idx = *index;
|
auto& idx = *index;
|
||||||
for (auto&& namedfunc : indexmetafunctions ) {
|
for(auto&& namedfunc : indexmetafunctions) {
|
||||||
idx.emplace(std::move(namedfunc.first), std::move(namedfunc.second));
|
idx.emplace(std::move(namedfunc.first), std::move(namedfunc.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!newindexmetafunctions.empty()) {
|
if(!newindexmetafunctions.empty()) {
|
||||||
if (newindex == nullptr) {
|
if(newindex == nullptr) {
|
||||||
auto idxptr = detail::make_unique<userdata_indexing_function<void (T::*)(), T>>("__newindex", nullptr);
|
auto idxptr = detail::make_unique<userdata_indexing_function<void (T::*)(), T>>("__newindex", nullptr);
|
||||||
newindex = &(idxptr->functions);
|
newindex = &(idxptr->functions);
|
||||||
functionnames.emplace_back("__newindex");
|
functionnames.emplace_back("__newindex");
|
||||||
metafunctions.emplace_back(std::move(idxptr));
|
metafunctions.emplace_back(std::move(idxptr));
|
||||||
std::string& name = functionnames.back();
|
std::string& name = functionnames.back();
|
||||||
if (extracount > 0) {
|
if(extracount > 0) {
|
||||||
metafunctiontable.push_back( { name.c_str(), &base_function::userdata<N + 1>::call } );
|
metafunctiontable.push_back({ name.c_str(), &base_function::userdata<N + 1>::call });
|
||||||
ptrmetafunctiontable.push_back( { name.c_str(), &base_function::userdata<N + 1>::ref_call } );
|
ptrmetafunctiontable.push_back({ name.c_str(), &base_function::userdata<N + 1>::ref_call });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
metafunctiontable.push_back( { name.c_str(), &base_function::userdata<N>::call } );
|
metafunctiontable.push_back({ name.c_str(), &base_function::userdata<N>::call });
|
||||||
ptrmetafunctiontable.push_back( { name.c_str(), &base_function::userdata<N>::ref_call } );
|
ptrmetafunctiontable.push_back({ name.c_str(), &base_function::userdata<N>::ref_call });
|
||||||
}
|
}
|
||||||
++extracount;
|
++extracount;
|
||||||
}
|
}
|
||||||
auto& idx = *newindex;
|
auto& idx = *newindex;
|
||||||
for (auto&& namedfunc : newindexmetafunctions ) {
|
for(auto&& namedfunc : newindexmetafunctions) {
|
||||||
idx.emplace(std::move(namedfunc.first), std::move(namedfunc.second));
|
idx.emplace(std::move(namedfunc.first), std::move(namedfunc.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (extracount) {
|
switch(extracount) {
|
||||||
case 2:
|
case 2:
|
||||||
build_cleanup<N + 2>();
|
build_cleanup<N + 2>();
|
||||||
break;
|
break;
|
||||||
|
@ -262,14 +262,14 @@ private:
|
||||||
bool build_function(std::false_type, function_map_t*& index, function_map_t*& newindex, std::string funcname, Fx&& func) {
|
bool build_function(std::false_type, function_map_t*& index, function_map_t*& newindex, std::string funcname, Fx&& func) {
|
||||||
typedef typename std::decay<Fx>::type function_type;
|
typedef typename std::decay<Fx>::type function_type;
|
||||||
auto metamethod = std::find(meta_function_names.begin(), meta_function_names.end(), funcname);
|
auto metamethod = std::find(meta_function_names.begin(), meta_function_names.end(), funcname);
|
||||||
if (metamethod != meta_function_names.end()) {
|
if(metamethod != meta_function_names.end()) {
|
||||||
functionnames.push_back(std::move(funcname));
|
functionnames.push_back(std::move(funcname));
|
||||||
std::string& name = functionnames.back();
|
std::string& name = functionnames.back();
|
||||||
auto indexmetamethod = std::find(meta_variable_names.begin(), meta_variable_names.end(), name);
|
auto indexmetamethod = std::find(meta_variable_names.begin(), meta_variable_names.end(), name);
|
||||||
std::unique_ptr<base_function> ptr(nullptr);
|
std::unique_ptr<base_function> ptr(nullptr);
|
||||||
if (indexmetamethod != meta_variable_names.end()) {
|
if(indexmetamethod != meta_variable_names.end()) {
|
||||||
auto idxptr = detail::make_unique<userdata_indexing_function<function_type, T>>(name, func);
|
auto idxptr = detail::make_unique<userdata_indexing_function<function_type, T>>(name, func);
|
||||||
switch( std::distance(indexmetamethod, meta_variable_names.end()) ) {
|
switch(std::distance(indexmetamethod, meta_variable_names.end())) {
|
||||||
case 0:
|
case 0:
|
||||||
index = &(idxptr->functions);
|
index = &(idxptr->functions);
|
||||||
break;
|
break;
|
||||||
|
@ -296,8 +296,8 @@ private:
|
||||||
template<std::size_t N, typename Fx, typename... Args>
|
template<std::size_t N, typename Fx, typename... Args>
|
||||||
void build_function_tables(function_map_t*& index, function_map_t*& newindex, std::string funcname, Fx&& func, Args&&... args) {
|
void build_function_tables(function_map_t*& index, function_map_t*& newindex, std::string funcname, Fx&& func, Args&&... args) {
|
||||||
typedef typename std::is_member_object_pointer<Unqualified<Fx>>::type is_variable;
|
typedef typename std::is_member_object_pointer<Unqualified<Fx>>::type is_variable;
|
||||||
static const std::size_t V = static_cast<std::size_t>( !is_variable::value );
|
static const std::size_t V = static_cast<std::size_t>(!is_variable::value);
|
||||||
if (build_function<N>(is_variable(), index, newindex, std::move(funcname), std::forward<Fx>(func))) {
|
if(build_function<N>(is_variable(), index, newindex, std::move(funcname), std::forward<Fx>(func))) {
|
||||||
build_function_tables<N + V>(index, newindex, std::forward<Args>(args)...);
|
build_function_tables<N + V>(index, newindex, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -347,11 +347,11 @@ public:
|
||||||
userdata(const char* name, constructors<CArgs...> c, Args&&... args) :
|
userdata(const char* name, constructors<CArgs...> c, Args&&... args) :
|
||||||
userdata(std::string(name), std::move(c), std::forward<Args>(args)...) {}
|
userdata(std::string(name), std::move(c), std::forward<Args>(args)...) {}
|
||||||
|
|
||||||
const std::string& name () const {
|
const std::string& name() const {
|
||||||
return luaname;
|
return luaname;
|
||||||
}
|
}
|
||||||
|
|
||||||
void push (lua_State* L) {
|
void push(lua_State* L) {
|
||||||
// push pointer tables first,
|
// push pointer tables first,
|
||||||
// but leave the regular T table on last
|
// but leave the regular T table on last
|
||||||
// so it can be linked to a type for usage with `.new(...)` or `:new(...)`
|
// so it can be linked to a type for usage with `.new(...)` or `:new(...)`
|
||||||
|
@ -368,7 +368,7 @@ private:
|
||||||
template<typename Meta, typename MetaFuncs, typename MetaFuncTable>
|
template<typename Meta, typename MetaFuncs, typename MetaFuncTable>
|
||||||
static void push_metatable(lua_State* L, Meta&& metakey, MetaFuncs&& metafuncs, MetaFuncTable&& metafunctable) {
|
static void push_metatable(lua_State* L, Meta&& metakey, MetaFuncs&& metafuncs, MetaFuncTable&& metafunctable) {
|
||||||
luaL_newmetatable(L, std::addressof(metakey[0]));
|
luaL_newmetatable(L, std::addressof(metakey[0]));
|
||||||
if (metafunctable.size() > 1) {
|
if(metafunctable.size() > 1) {
|
||||||
// regular functions accessed through __index semantics
|
// regular functions accessed through __index semantics
|
||||||
int up = push_upvalues(L, metafuncs);
|
int up = push_upvalues(L, metafuncs);
|
||||||
luaL_setfuncs(L, metafunctable.data(), up);
|
luaL_setfuncs(L, metafunctable.data(), up);
|
||||||
|
@ -376,7 +376,7 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_global_deleter (lua_State* L) {
|
void set_global_deleter(lua_State* L) {
|
||||||
// Automatic deleter table -- stays alive until lua VM dies
|
// Automatic deleter table -- stays alive until lua VM dies
|
||||||
// even if the user calls collectgarbage()
|
// even if the user calls collectgarbage()
|
||||||
lua_createtable(L, 0, 0);
|
lua_createtable(L, 0, 0);
|
||||||
|
@ -390,13 +390,15 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool release = false, typename TCont>
|
template<bool release = false, typename TCont>
|
||||||
static int push_upvalues (lua_State* L, TCont&& cont) {
|
static int push_upvalues(lua_State* L, TCont&& cont) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (auto& c : cont) {
|
for(auto& c : cont) {
|
||||||
if (release)
|
if(release) {
|
||||||
stack::push<upvalue_t>(L, c.release());
|
stack::push<upvalue_t>(L, c.release());
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
stack::push<upvalue_t>(L, c.get());
|
stack::push<upvalue_t>(L, c.get());
|
||||||
|
}
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
|
@ -406,12 +408,11 @@ private:
|
||||||
namespace stack {
|
namespace stack {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct pusher<userdata<T>> {
|
struct pusher<userdata<T>> {
|
||||||
static void push (lua_State* L, userdata<T>& user) {
|
static void push(lua_State* L, userdata<T>& user) {
|
||||||
user.push(L);
|
user.push(L);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // stack
|
} // stack
|
||||||
|
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
#endif // SOL_USERDATA_HPP
|
#endif // SOL_USERDATA_HPP
|
||||||
|
|
Loading…
Reference in New Issue
Block a user