Lua stream example!

This commit is contained in:
ThePhD 2020-01-25 13:09:16 -05:00
parent 2beb13b9b2
commit 0c38fd1a57
No known key found for this signature in database
GPG Key ID: 1509DB1C0F702BFA
6 changed files with 178 additions and 58 deletions

View File

@ -0,0 +1,23 @@
#define SOL_CHECK_ARGUMENTS 1
#include <sol/sol.hpp>
#include <cstdio>
bool is_file_std_out(sol::table data) {
sol::object maybe_file = data["file"];
if (maybe_file.is<luaL_Stream&>()) {
luaL_Stream& filestream = data["file"];
return filestream.f == stdout;
}
return false;
}
int main() {
sol::state lua;
lua.open_libraries(sol::lib::base, sol::lib::io);
lua["is_std_out"] = &is_file_std_out;
lua.script("assert(is_std_out{ file = io.stdout })");
return 0;
}

View File

@ -223,7 +223,8 @@ namespace sol { namespace stack {
handler(L, index, type::userdata, indextype, "unrecognized userdata (not pushed by sol?)");
return false;
}
else if constexpr (meta::any_same_v<T, lua_nil_t,
else if constexpr (meta::any_same_v<T,
lua_nil_t,
#if defined(SOL_CXX_17_FEATURES) && SOL_CXX_17_FEATURES
std::nullopt_t,
#endif
@ -305,6 +306,33 @@ namespace sol { namespace stack {
}
return true;
}
else if constexpr (std::is_same_v<T, luaL_Stream*> || std::is_same_v<T, luaL_Stream>) {
if (lua_getmetatable(L, index) == 0) {
type t = type_of(L, index);
handler(L, index, expected, t, "value is not a valid luaL_Stream (has no metatable/is not a valid value)");
return false;
}
luaL_getmetatable(L, LUA_FILEHANDLE);
if (type_of(L, index) != type::table) {
type t = type_of(L, index);
lua_pop(L, 1);
handler(L,
index,
expected,
t,
"value is not a valid luaL_Stream (there is no metatable for luaL_Stream -- did you forget to "
"my_lua_state.open_libraries(sol::lib::state) or equivalent?)");
return false;
}
int is_stream_table = lua_compare(L, -1, -2, LUA_OPEQ);
lua_pop(L, 2);
if (is_stream_table == 0) {
type t = type_of(L, index);
handler(L, index, expected, t, "value is not a valid luaL_Stream (incorrect metatable)");
return false;
}
return true;
}
else if constexpr (expected == type::userdata) {
if constexpr (meta::any_same_v<T, userdata_value> || meta::is_specialization_of_v<T, basic_userdata>) {
tracking.use(1);
@ -435,7 +463,9 @@ namespace sol { namespace stack {
template <typename U, typename Handler>
static bool check(types<U>, lua_State* L, int index, type indextype, Handler&& handler, record& tracking) {
if constexpr (std::is_same_v<T, lightuserdata_value> || std::is_same_v<T, userdata_value> || std::is_same_v<T, userdata> || std::is_same_v<T, lightuserdata>) {
if constexpr (
std::is_same_v<T,
lightuserdata_value> || std::is_same_v<T, userdata_value> || std::is_same_v<T, userdata> || std::is_same_v<T, lightuserdata>) {
tracking.use(1);
if (indextype != type::userdata) {
handler(L, index, type::userdata, indextype, "value is not a valid userdata");

View File

@ -153,6 +153,14 @@ namespace sol { namespace stack {
Real* mem = static_cast<Real*>(memory);
return *mem;
}
else if constexpr (std::is_same_v<T, luaL_Stream*>) {
luaL_Stream* pstream = static_cast<luaL_Stream*>(lua_touserdata(L, index));
return pstream;
}
else if constexpr (std::is_same_v<T, luaL_Stream>) {
luaL_Stream* pstream = static_cast<luaL_Stream*>(lua_touserdata(L, index));
return *pstream;
}
else {
return stack_detail::unchecked_unqualified_get<detail::as_value_tag<T>>(L, index, tracking);
}
@ -164,7 +172,8 @@ namespace sol { namespace stack {
static decltype(auto) get(lua_State* L, int index, record& tracking) {
using Tu = meta::unqualified_t<X>;
static constexpr bool is_userdata_of_some_kind
= !std::is_reference_v<X> && is_container_v<Tu> && std::is_default_constructible_v<Tu> && !is_lua_primitive_v<Tu> && !is_transparent_argument_v<Tu>;
= !std::is_reference_v<
X> && is_container_v<Tu> && std::is_default_constructible_v<Tu> && !is_lua_primitive_v<Tu> && !is_transparent_argument_v<Tu>;
if constexpr (is_userdata_of_some_kind) {
if (type_of(L, index) == type::userdata) {
return static_cast<Tu>(stack_detail::unchecked_unqualified_get<Tu>(L, index, tracking));
@ -874,8 +883,7 @@ namespace sol { namespace stack {
lua_getfield(L, -1, &detail::base_class_cast_key()[0]);
if (type_of(L, -1) != type::lua_nil) {
void* basecastdata = lua_touserdata(L, -1);
detail::inheritance_cast_function ic
= reinterpret_cast<detail::inheritance_cast_function>(basecastdata);
detail::inheritance_cast_function ic = reinterpret_cast<detail::inheritance_cast_function>(basecastdata);
// use the casting function to properly adjust the pointer for the desired T
udata = ic(udata, usertype_traits<T>::qualified_name());
}
@ -960,8 +968,7 @@ namespace sol { namespace stack {
static R apply(std::index_sequence<I, Ix...>, lua_State* L, int index, record& tracking, Args&&... args) {
// Fuck you too, VC++
typedef std::tuple_element_t<I, std::tuple<Tn...>> T;
return apply(std::index_sequence<Ix...>(), L, index, tracking, std::forward<Args>(args)...,
stack::get<T>(L, index + tracking.used, tracking));
return apply(std::index_sequence<Ix...>(), L, index, tracking, std::forward<Args>(args)..., stack::get<T>(L, index + tracking.used, tracking));
}
static R get(lua_State* L, int index, record& tracking) {
@ -972,9 +979,8 @@ namespace sol { namespace stack {
template <typename A, typename B>
struct unqualified_getter<std::pair<A, B>> {
static decltype(auto) get(lua_State* L, int index, record& tracking) {
return std::pair<decltype(stack::get<A>(L, index)), decltype(stack::get<B>(L, index))>{
stack::get<A>(L, index, tracking), stack::get<B>(L, index + tracking.used, tracking)
};
return std::pair<decltype(stack::get<A>(L, index)), decltype(stack::get<B>(L, index))> { stack::get<A>(L, index, tracking),
stack::get<B>(L, index + tracking.used, tracking) };
}
};

View File

@ -296,6 +296,20 @@ namespace sol { namespace stack {
lua_pushnumber(L, std::forward<Args>(args)...);
return 1;
}
else if constexpr (std::is_same<Tu, luaL_Stream*>) {
luaL_Stream* source(std::forward<Args>(args)...);
luaL_Stream* stream = static_cast<luaL_Stream*>(lua_newuserdata(L, sizeof(luaL_Stream)));
stream->f = source->f;
stream->closef = source->closef;
return 1;
}
else if constexpr (std::is_same<Tu, luaL_Stream>) {
luaL_Stream& source(std::forward<Args>(args)...);
luaL_Stream* stream = static_cast<luaL_Stream*>(lua_newuserdata(L, sizeof(luaL_Stream)));
stream->f = source.f;
stream->closef = source.closef;
return 1;
}
else if constexpr (std::is_enum_v<Tu>) {
return stack_detail::msvc_is_ass_with_if_constexpr_push_enum(std::true_type(), L, std::forward<Args>(args)...);
}

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script.
// Generated 2020-01-25 04:59:37.808053 UTC
// This header was generated with sol v3.2.0 (revision c5863c8)
// Generated 2020-01-25 17:11:21.688498 UTC
// This header was generated with sol v3.2.0 (revision 2beb13b)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script.
// Generated 2020-01-25 04:59:35.996014 UTC
// This header was generated with sol v3.2.0 (revision c5863c8)
// Generated 2020-01-25 17:11:19.283779 UTC
// This header was generated with sol v3.2.0 (revision 2beb13b)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP
@ -11102,7 +11102,8 @@ namespace sol { namespace stack {
handler(L, index, type::userdata, indextype, "unrecognized userdata (not pushed by sol?)");
return false;
}
else if constexpr (meta::any_same_v<T, lua_nil_t,
else if constexpr (meta::any_same_v<T,
lua_nil_t,
#if defined(SOL_CXX_17_FEATURES) && SOL_CXX_17_FEATURES
std::nullopt_t,
#endif
@ -11184,6 +11185,30 @@ namespace sol { namespace stack {
}
return true;
}
else if constexpr (std::is_same_v<T, luaL_Stream*> || std::is_same_v<T, luaL_Stream>) {
if (lua_getmetatable(L, index) == 0) {
handler(L, index, expected, t, "value is not a valid luaL_Stream (has no metatable/is not a valid value)");
return false;
}
luaL_getmetatable(L, LUA_FILEHANDLE);
if (type_of(L, index) != type::table) {
lua_pop(L, 1);
handler(L,
index,
expected,
t,
"value is not a valid luaL_Stream (there is no metatable for luaL_Stream -- did you forget to "
"my_lua_state.open_libraries(sol::lib::state) or equivalent?)");
return false;
}
int is_stream_table = lua_compare(L, -1, -2, LUA_OPEQ);
lua_pop(L, 2);
if (is_stream_table == 0) {
handler(L, index, expected, t, "value is not a valid luaL_Stream (incorrect metatable)");
return false;
}
return true;
}
else if constexpr (expected == type::userdata) {
if constexpr (meta::any_same_v<T, userdata_value> || meta::is_specialization_of_v<T, basic_userdata>) {
tracking.use(1);
@ -11314,7 +11339,9 @@ namespace sol { namespace stack {
template <typename U, typename Handler>
static bool check(types<U>, lua_State* L, int index, type indextype, Handler&& handler, record& tracking) {
if constexpr (std::is_same_v<T, lightuserdata_value> || std::is_same_v<T, userdata_value> || std::is_same_v<T, userdata> || std::is_same_v<T, lightuserdata>) {
if constexpr (
std::is_same_v<T,
lightuserdata_value> || std::is_same_v<T, userdata_value> || std::is_same_v<T, userdata> || std::is_same_v<T, lightuserdata>) {
tracking.use(1);
if (indextype != type::userdata) {
handler(L, index, type::userdata, indextype, "value is not a valid userdata");
@ -12001,6 +12028,14 @@ namespace sol { namespace stack {
Real* mem = static_cast<Real*>(memory);
return *mem;
}
else if constexpr (std::is_same_v<T, luaL_Stream*>) {
luaL_Stream* pstream = static_cast<luaL_Stream*>(lua_touserdata(L, index));
return pstream;
}
else if constexpr (std::is_same_v<T, luaL_Stream>) {
luaL_Stream* pstream = static_cast<luaL_Stream*>(lua_touserdata(L, index));
return *pstream;
}
else {
return stack_detail::unchecked_unqualified_get<detail::as_value_tag<T>>(L, index, tracking);
}
@ -12012,7 +12047,8 @@ namespace sol { namespace stack {
static decltype(auto) get(lua_State* L, int index, record& tracking) {
using Tu = meta::unqualified_t<X>;
static constexpr bool is_userdata_of_some_kind
= !std::is_reference_v<X> && is_container_v<Tu> && std::is_default_constructible_v<Tu> && !is_lua_primitive_v<Tu> && !is_transparent_argument_v<Tu>;
= !std::is_reference_v<
X> && is_container_v<Tu> && std::is_default_constructible_v<Tu> && !is_lua_primitive_v<Tu> && !is_transparent_argument_v<Tu>;
if constexpr (is_userdata_of_some_kind) {
if (type_of(L, index) == type::userdata) {
return static_cast<Tu>(stack_detail::unchecked_unqualified_get<Tu>(L, index, tracking));
@ -12722,8 +12758,7 @@ namespace sol { namespace stack {
lua_getfield(L, -1, &detail::base_class_cast_key()[0]);
if (type_of(L, -1) != type::lua_nil) {
void* basecastdata = lua_touserdata(L, -1);
detail::inheritance_cast_function ic
= reinterpret_cast<detail::inheritance_cast_function>(basecastdata);
detail::inheritance_cast_function ic = reinterpret_cast<detail::inheritance_cast_function>(basecastdata);
// use the casting function to properly adjust the pointer for the desired T
udata = ic(udata, usertype_traits<T>::qualified_name());
}
@ -12808,8 +12843,7 @@ namespace sol { namespace stack {
static R apply(std::index_sequence<I, Ix...>, lua_State* L, int index, record& tracking, Args&&... args) {
// Fuck you too, VC++
typedef std::tuple_element_t<I, std::tuple<Tn...>> T;
return apply(std::index_sequence<Ix...>(), L, index, tracking, std::forward<Args>(args)...,
stack::get<T>(L, index + tracking.used, tracking));
return apply(std::index_sequence<Ix...>(), L, index, tracking, std::forward<Args>(args)..., stack::get<T>(L, index + tracking.used, tracking));
}
static R get(lua_State* L, int index, record& tracking) {
@ -12820,9 +12854,8 @@ namespace sol { namespace stack {
template <typename A, typename B>
struct unqualified_getter<std::pair<A, B>> {
static decltype(auto) get(lua_State* L, int index, record& tracking) {
return std::pair<decltype(stack::get<A>(L, index)), decltype(stack::get<B>(L, index))>{
stack::get<A>(L, index, tracking), stack::get<B>(L, index + tracking.used, tracking)
};
return std::pair<decltype(stack::get<A>(L, index)), decltype(stack::get<B>(L, index))> { stack::get<A>(L, index, tracking),
stack::get<B>(L, index + tracking.used, tracking) };
}
};
@ -13383,6 +13416,20 @@ namespace sol { namespace stack {
lua_pushnumber(L, std::forward<Args>(args)...);
return 1;
}
else if constexpr (std::is_same<Tu, luaL_Stream*>) {
luaL_Stream* source(std::forward<Args>(Args)...);
luaL_Stream* stream = static_cast<luaL_Stream*>(lua_newuserdata(L, sizeof(luaL_Stream)));
stream->f = source->f;
stream->closef = source->closef;
return 1;
}
else if constexpr (std::is_same<Tu, luaL_Stream>) {
luaL_Stream& source(std::forward<Args>(Args)...);
luaL_Stream* stream = static_cast<luaL_Stream*>(lua_newuserdata(L, sizeof(luaL_Stream)));
stream->f = source.f;
stream->closef = source.closef;
return 1;
}
else if constexpr (std::is_enum_v<Tu>) {
return stack_detail::msvc_is_ass_with_if_constexpr_push_enum(std::true_type(), L, std::forward<Args>(args)...);
}