diff --git a/sol/stack.hpp b/sol/stack.hpp index ff3ceeb9..d7029bc5 100644 --- a/sol/stack.hpp +++ b/sol/stack.hpp @@ -120,28 +120,6 @@ inline auto get_helper(std::false_type, lua_State* L, int index = -1) -> decltyp // T is a class return get(types(), L, index); } - -template -inline void push_unsigned(std::true_type, lua_State* L, T x) { - lua_pushunsigned(L, x); -} - -template -inline void push_unsigned(std::false_type, lua_State* L, T x) { - lua_pushinteger(L, x); -} - -template -inline void push_arithmetic(std::true_type, lua_State* L, T x) { - // T is an integral type - push_unsigned(std::is_unsigned{}, L, x); -} - -template -inline void push_arithmetic(std::false_type, lua_State* L, T x) { - // T is an floating point type - lua_pushnumber(L, x); -} } // detail template> @@ -167,62 +145,100 @@ auto pop(lua_State* L) -> decltype(get(L)) { return r; } -template::value> -inline typename std::enable_if::type push(lua_State* L, T arithmetic) { - detail::push_arithmetic(std::is_integral{}, L, arithmetic); -} +template +struct pusher; -template::value && - !std::is_same, std::string>::value && - has_begin_end::value> -inline typename std::enable_if::type push(lua_State* L, const T& cont) { - lua_createtable(L, cont.size(), 0); - unsigned index = 1; - for(auto&& i : cont) { - // push the index - push(L, index++); - // push the value - push(L, i); - // set the table - lua_settable(L, -3); +template +struct pusher { + template> = 0> + static void push(lua_State* L, const T& value) { + lua_pushnumber(L, value); } -} -inline void push(lua_State*, reference& ref) { - ref.push(); -} + template, std::is_signed> = 0> + static void push(lua_State* L, const T& value) { + lua_pushinteger(L, value); + } -inline void push(lua_State* L, bool boolean) { - lua_pushboolean(L, boolean); -} + template, std::is_unsigned> = 0> + static void push(lua_State* L, const T& value) { + lua_pushunsigned(L, value); + } -inline void push(lua_State* L, const nil_t&) { - lua_pushnil(L); -} + template, Not>> = 0> + static void push(lua_State* L, const T& cont) { + lua_createtable(L, cont.size(), 0); + unsigned index = 1; + for(auto&& i : cont) { + // push the index + pusher::push(L, index++); + // push the value + pusher>::push(L, i); + // set the table + lua_settable(L, -3); + } + } +}; -inline void push(lua_State* L, lua_CFunction func) { - lua_pushcfunction(L, func); -} +template<> +struct pusher { + static void push(lua_State* L, const bool& b) { + lua_pushboolean(L, b); + } +}; -inline void push(lua_State* L, lua_CFunction func, int n) { - lua_pushcclosure(L, func, n); -} +template<> +struct pusher { + static void push(lua_State*, reference& r) { + r.push(); + } +}; -inline void push(lua_State* L, void* userdata) { - lua_pushlightuserdata(L, userdata); -} +template<> +struct pusher { + static void push(lua_State* L, const nil_t&) { + lua_pushnil(L); + } +}; + +template<> +struct pusher { + static void push(lua_State* L, lua_CFunction func) { + lua_pushcfunction(L, func); + } +}; + +template<> +struct pusher { + static void push(lua_State* L, void* userdata) { + lua_pushlightuserdata(L, userdata); + } +}; + +template<> +struct pusher { + static void push(lua_State* L, const char* str) { + lua_pushlstring(L, str, std::char_traits::length(str)); + } +}; template -inline void push(lua_State* L, const char (&str)[N]) { - lua_pushlstring(L, str, N - 1); -} +struct pusher { + static void push(lua_State* L, const char (&str)[N]) { + lua_pushlstring(L, str, N - 1); + } +}; -inline void push(lua_State* L, const char* str) { - lua_pushlstring(L, str, std::char_traits::length(str)); -} +template<> +struct pusher { + static void push(lua_State* L, const std::string& str) { + lua_pushlstring(L, str.c_str(), str.size()); + } +}; -inline void push(lua_State* L, const std::string& str) { - lua_pushlstring(L, str.c_str(), str.size()); +template +inline void push(lua_State* L, T&& t) { + pusher>::push(L, std::forward(t)); } template @@ -237,8 +253,8 @@ inline void push_user(lua_State* L, T& userdata, const char* metatablekey) { } template -inline void push(lua_State* L, const std::array& data) { - for (auto&& i : data) { +inline void push_as_upvalues(lua_State* L, const std::array& data) { + for(auto&& i : data) { push(L, i); } } @@ -254,7 +270,7 @@ inline int push_user(lua_State* L, T& item) { data_t data{{}}; std::memcpy(std::addressof(data[0]), std::addressof(item), itemsize); - push(L, data); + push_as_upvalues(L, data); return data_t_count; } @@ -294,14 +310,15 @@ inline auto rtl_pop(lua_State* L, F&& f, types t, types, } // detail template -inline void push(lua_State* L, const std::tuple& tuplen) { - detail::push_tuple(L, build_indices(), tuplen); -} +struct pusher> { + static void push(lua_State* L, const std::tuple& tuplen) { + detail::push_tuple(L, build_indices(), tuplen); + } -template -inline void push(lua_State* L, std::tuple&& tuplen) { - detail::push_tuple(L, build_indices(), std::move(tuplen)); -} + static void push(lua_State* L, std::tuple&& tuplen) { + detail::push_tuple(L, build_indices(), std::move(tuplen)); + } +}; template inline void push_reverse(lua_State* L, T&& item) { @@ -374,7 +391,6 @@ template struct get_return { typedef decltype(get(nullptr)) type; }; - } // stack } // sol