Formatting changes.

This commit is contained in:
Rapptz 2014-08-10 20:49:34 -04:00
parent 2a5b800286
commit da76793c30
11 changed files with 118 additions and 118 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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>();
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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());
} }
} }

View File

@ -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

View File

@ -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 {

View File

@ -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