@@ -124,6 +124,21 @@ true;
false;
#endif

template<bool releasemem = false, typename TCont>
static int push_upvalues(lua_State* L, TCont&& cont) {
int n = 0;
for(auto& c : cont) {
if(releasemem) {
stack::push<upvalue>(L, c.release());
}
else {
stack::push<upvalue>(L, c.get());
}
++n;
}
return n;
}

template <typename T>
struct userdata_pusher {
template <typename Key, typename... Args>
@@ -140,7 +155,7 @@ struct userdata_pusher {
referencereference = allocationtarget;
std::allocator<T> alloc{};
alloc.construct(allocationtarget, std::forward<Args>(args)...);
luaL_getmetatable(L, std::addressof(metatablekey[0]));
luaL_getmetatable(L, &metatablekey[0]);
lua_setmetatable(L, -2);
}
};
@@ -152,7 +167,7 @@ struct userdata_pusher<T*> {
T** pdatum = static_cast<T**>(lua_newuserdata(L, sizeof(T*)));
std::allocator<T*> alloc{};
alloc.construct(pdatum, std::forward<Args>(args)...);
luaL_getmetatable(L, std::addressof(metatablekey[0]));
luaL_getmetatable(L, &metatablekey[0]);
lua_setmetatable(L, -2);
}
};
@@ -361,6 +376,20 @@ struct getter<nil_t> {
}
};

template<>
struct getter<lua_CFunction> {
static lua_CFunction get(lua_State* L, int index = -1) {
return lua_tocfunction(L, index);
}
};

template<>
struct getter<c_closure> {
static c_closure get(lua_State* L, int index = -1) {
return c_closure(lua_tocfunction(L, index), -1);
}
};

template<>
struct getter<userdata> {
static userdata get(lua_State* L, int index = -1) {
@@ -529,6 +558,14 @@ struct pusher<lua_CFunction> {
}
};

template<>
struct pusher<c_closure> {
static int push(lua_State* L, c_closure closure) {
lua_pushcclosure(L, closure.c_function, closure.upvalues);
return 1;
}
};

template<>
struct pusher<void*> {
static int push(lua_State* L, void* userdata) {
@@ -636,6 +673,16 @@ struct field_getter<T, false, std::enable_if_t<is_c_str<T>::value>> {
}
};

#if SOL_LUA_VERSION >= 503
template <typename T>
struct field_getter<T, false, std::enable_if_t<std::is_integral<T>::value>> {
template <typename Key>
void get(lua_State* L, Key&& key, int tableindex = -1) {
lua_geti(L, tableindex, static_cast<lua_Integer>(key));
}
};
#endif // Lua 5.3.x

template <typename T, bool, typename>
struct field_setter {
template <typename Key, typename Value>
@@ -664,6 +711,17 @@ struct field_setter<T, false, std::enable_if_t<is_c_str<T>::value>> {
}
};

#if SOL_LUA_VERSION >= 503
template <typename T>
struct field_setter<T, false, std::enable_if_t<std::is_integral<T>::value>> {
template <typename Key, typename Value>
void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) {
push(L, std::forward<Value>(value));
lua_seti(L, tableindex, static_cast<lua_Integer>(key));
}
};
#endif // Lua 5.3.x

namespace stack_detail {
template<typename T>
inline int push_as_upvalues(lua_State* L, T& item) {
@@ -675,7 +733,7 @@ inline int push_as_upvalues(lua_State* L, T& item) {
typedef std::array<void*, data_t_count> data_t;

data_t data{{}};
std::memcpy(std::addressof(data[0]), std::addressof(item), itemsize);
std::memcpy(&data[0], std::addressof(item), itemsize);
int pushcount = 0;
for(auto&& v : data) {
pushcount += push(L, upvalue(v));
@@ -699,9 +757,9 @@ struct check_arguments {
template <std::size_t I0, std::size_t... I, typename Arg0, typename... Args>
static bool check(types<Arg0, Args...>, std::index_sequence<I0, I...>, lua_State* L, int firstargument) {
bool checks = true;
stack::check<Arg0>(L, firstargument + I0);
(void)detail::swallow{(checks &= stack::check<Args>(L, firstargument + I))...};
return checks;
if (!stack::check<Arg0>(L, firstargument + I0))
return false;
return check(types<Args...>(), std::index_sequence<I...>(), L, firstargument);
}

static bool check(types<>, std::index_sequence<>, lua_State*, int) {
@@ -165,10 +165,6 @@ class table_core : public reference {
return proxy<table_core, T>( *this, std::forward<T>( key ) );
}

void pop( int n = 1 ) const noexcept {
lua_pop( lua_state( ), n );
}

template<typename... Args, typename R, typename Key>
table_core& set_function( Key&& key, R fun_ptr( Args... ) ) {
set_resolved_function( std::forward<Key>( key ), fun_ptr );
@@ -56,6 +56,12 @@ struct userdata {
operator void*() const { return value; }
};

struct c_closure {
lua_CFunction c_function;
int upvalues;
c_closure(lua_CFunction f, int upvalues = 0) : c_function(f), upvalues(upvalues) {}
};

enum class call_syntax {
dot = 0,
colon = 1
@@ -158,6 +164,9 @@ struct lua_type_of<object> : std::integral_constant<type, type::poly> {};
template <>
struct lua_type_of<light_userdata> : std::integral_constant<type, type::lightuserdata> {};

template <>
struct lua_type_of<lua_CFunction> : std::integral_constant<type, type::function> {};

template <>
struct lua_type_of<function> : std::integral_constant<type, type::function> {};

@@ -173,21 +182,8 @@ struct lua_type_of<T*> : std::integral_constant<type, type::userdata> {};
template <typename T>
struct lua_type_of<T, std::enable_if_t<std::is_arithmetic<T>::value>> : std::integral_constant<type, type::number> {};

template<typename T>
inline type type_of() {
return lua_type_of<Unqualified<T>>::value;
}

inline type type_of(lua_State* L, int index) {
return static_cast<type>(lua_type(L, index));
}

// All enumerations are given and taken from lua
// as numbers as well
template <typename T>
struct lua_type_of<T, std::enable_if_t<std::is_enum<T>::value>> : std::integral_constant<type, type::number> {

};
struct lua_type_of<T, std::enable_if_t<std::is_enum<T>::value>> : std::integral_constant<type, type::number> {};

template <typename T>
struct is_lua_primitive : std::integral_constant<bool, type::userdata != lua_type_of<Unqualified<T>>::value> { };
@@ -200,6 +196,15 @@ struct is_proxy_primitive<std::reference_wrapper<T>> : std::true_type { };

template <typename... Args>
struct is_proxy_primitive<std::tuple<Args...>> : std::true_type { };

template<typename T>
inline type type_of() {
return lua_type_of<Unqualified<T>>::value;
}

inline type type_of(lua_State* L, int index) {
return static_cast<type>(lua_type(L, index));
}
} // sol

#endif // SOL_TYPES_HPP

Large diffs are not rendered by default.

@@ -30,7 +30,8 @@ template<typename T>
struct usertype_traits {
static const std::string name;
static const std::string metatable;
static const std::string gctable;
static const std::string variable_metatable;
static const std::string gc_table;
};

template<typename T>
@@ -40,7 +41,10 @@ template<typename T>
const std::string usertype_traits<T>::metatable = std::string("sol.").append(detail::demangle(typeid(T)));

template<typename T>
const std::string usertype_traits<T>::gctable = std::string("sol.").append(detail::demangle(typeid(T))).append(".\xE2\x99\xBB");
const std::string usertype_traits<T>::variable_metatable = std::string("sol.").append(detail::demangle(typeid(T))).append(".variables");

template<typename T>
const std::string usertype_traits<T>::gc_table = std::string("sol.").append(detail::demangle(typeid(T))).append(".\xE2\x99\xBB");

}