Pioneer
Loading...
Searching...
No Matches
LuaPushPull.h
Go to the documentation of this file.
1// Copyright © 2008-2024 Pioneer Developers. See AUTHORS.txt for details
2// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3
4#ifndef _LUAPUSHPULL_H
5#define _LUAPUSHPULL_H
6
7#include "Lua.h"
8#include <lua.hpp>
9
10#include <cstddef>
11#include <string>
12#include <tuple>
13#include <cstdint>
14#include <type_traits>
15
16// Prevent automatic conversion of pointer values to boolean (never what we want when pushing values to lua)
17// sadly requires type_traits so compile times suffer
18template<typename T, typename = std::enable_if_t<std::is_same_v<T, bool>>>
19inline void pi_lua_generic_push(lua_State *l, T value) { lua_pushboolean(l, value); }
20
21inline void pi_lua_generic_push(lua_State *l, int32_t value) { lua_pushinteger(l, value); }
22inline void pi_lua_generic_push(lua_State *l, int64_t value) { lua_pushinteger(l, value); }
23inline void pi_lua_generic_push(lua_State *l, uint32_t value) { lua_pushinteger(l, value); }
24inline void pi_lua_generic_push(lua_State *l, uint64_t value) { lua_pushinteger(l, value); }
25inline void pi_lua_generic_push(lua_State *l, double value) { lua_pushnumber(l, value); }
26inline void pi_lua_generic_push(lua_State *l, const char *value) { lua_pushstring(l, value); }
27inline void pi_lua_generic_push(lua_State *l, const std::string &value)
28{
29 lua_pushlstring(l, value.c_str(), value.size());
30}
31inline void pi_lua_generic_push(lua_State *l, const std::string_view &value)
32{
33 lua_pushlstring(l, value.data(), value.size());
34}
35inline void pi_lua_generic_push(lua_State *l, const std::nullptr_t &value) { lua_pushnil(l); }
36
37inline void pi_lua_generic_pull(lua_State *l, int index, bool &out) { out = lua_toboolean(l, index); }
38inline void pi_lua_generic_pull(lua_State *l, int index, int32_t &out) { out = luaL_checkinteger(l, index); }
39inline void pi_lua_generic_pull(lua_State *l, int index, int64_t &out) { out = luaL_checkinteger(l, index); }
40inline void pi_lua_generic_pull(lua_State *l, int index, uint32_t &out) { out = luaL_checkinteger(l, index); }
41inline void pi_lua_generic_pull(lua_State *l, int index, uint64_t &out) { out = luaL_checkinteger(l, index); }
42inline void pi_lua_generic_pull(lua_State *l, int index, float &out) { out = luaL_checknumber(l, index); }
43inline void pi_lua_generic_pull(lua_State *l, int index, double &out) { out = luaL_checknumber(l, index); }
44inline void pi_lua_generic_pull(lua_State *l, int index, const char *&out) { out = luaL_checkstring(l, index); }
45inline void pi_lua_generic_pull(lua_State *l, int index, std::string &out)
46{
47 size_t len;
48 const char *buf = luaL_checklstring(l, index, &len);
49 std::string(buf, len).swap(out);
50}
51// the returned string view is only valid until the lua object is removed from the stack
52inline void pi_lua_generic_pull(lua_State *l, int index, std::string_view &out)
53{
54 size_t len;
55 const char *buf = luaL_checklstring(l, index, &len);
56 out = { buf, len };
57}
58
59template <typename Type>
60inline void LuaPush(lua_State *l, Type value)
61{
62 pi_lua_generic_push(l, value);
63}
64
65template <typename Type>
66inline std::remove_reference_t<Type> LuaPull(lua_State *l, int index)
67{
68 std::decay_t<Type> value;
69 pi_lua_generic_pull(l, index, value);
70 return value;
71}
72
73// Pull a value with an optional default.
74template <typename Type>
75inline std::remove_reference_t<Type> LuaPull(lua_State *l, int index, Type defaultVal)
76{
77 Type value = defaultVal;
78 if (lua_gettop(l) >= index && !lua_isnil(l, index))
79 pi_lua_generic_pull(l, index, value);
80 return value;
81}
82
83inline bool pi_lua_strict_pull(lua_State *l, int index, bool &out)
84{
85 if (lua_type(l, index) == LUA_TBOOLEAN) {
86 out = lua_toboolean(l, index);
87 return true;
88 }
89 return false;
90}
91inline bool pi_lua_strict_pull(lua_State *l, int index, int &out)
92{
93 if (lua_type(l, index) == LUA_TNUMBER) {
94 out = lua_tointeger(l, index);
95 return true;
96 }
97 return false;
98}
99inline bool pi_lua_strict_pull(lua_State *l, int index, float &out)
100{
101 if (lua_type(l, index) == LUA_TNUMBER) {
102 out = lua_tonumber(l, index);
103 return true;
104 }
105 return false;
106}
107inline bool pi_lua_strict_pull(lua_State *l, int index, double &out)
108{
109 if (lua_type(l, index) == LUA_TNUMBER) {
110 out = lua_tonumber(l, index);
111 return true;
112 }
113 return false;
114}
115inline bool pi_lua_strict_pull(lua_State *l, int index, const char *&out)
116{
117 if (lua_type(l, index) == LUA_TSTRING) {
118 out = lua_tostring(l, index);
119 return true;
120 }
121 return false;
122}
123inline bool pi_lua_strict_pull(lua_State *l, int index, std::string &out)
124{
125 if (lua_type(l, index) == LUA_TSTRING) {
126 size_t len;
127 const char *buf = lua_tolstring(l, index, &len);
128 std::string(buf, len).swap(out);
129 return true;
130 }
131 return false;
132}
133
134// Variadic push/pull support
135
136template<typename... Types>
137inline void pi_lua_multiple_push(lua_State *l, Types... args)
138{
139 (pi_lua_generic_push(l, args), ...);
140}
141
142inline void pi_lua_multiple_push(lua_State *l)
143{
144 return;
145}
146
147template<typename... Types>
148inline std::tuple<std::remove_reference_t<Types>...> pi_lua_multiple_pull(lua_State *l, int beg)
149{
150 // List initialization (braces) has a defined sequence of operations
151 // thus the increment of `beg` over the parameter pack is well-defined
152 return std::tuple<std::remove_reference_t<Types>...>{ LuaPull<Types>(l, beg++)... };
153}
154
155#endif
void LuaPush(lua_State *l, Type value)
Definition: LuaPushPull.h:60
void pi_lua_generic_push(lua_State *l, T value)
Definition: LuaPushPull.h:19
bool pi_lua_strict_pull(lua_State *l, int index, bool &out)
Definition: LuaPushPull.h:83
std::remove_reference_t< Type > LuaPull(lua_State *l, int index)
Definition: LuaPushPull.h:66
void pi_lua_multiple_push(lua_State *l, Types... args)
Definition: LuaPushPull.h:137
void pi_lua_generic_pull(lua_State *l, int index, bool &out)
Definition: LuaPushPull.h:37
std::tuple< std::remove_reference_t< Types >... > pi_lua_multiple_pull(lua_State *l, int beg)
Definition: LuaPushPull.h:148