Pioneer
LuaPushPull.h
Go to the documentation of this file.
1 // Copyright © 2008-2021 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.hpp>
8 
9 #include "Lua.h"
10 #include <string>
11 #include <tuple>
12 
13 inline void pi_lua_generic_push(lua_State *l, bool value) { lua_pushboolean(l, value); }
14 inline void pi_lua_generic_push(lua_State *l, int value) { lua_pushinteger(l, value); }
15 inline void pi_lua_generic_push(lua_State *l, unsigned int value) { lua_pushinteger(l, value); }
16 inline void pi_lua_generic_push(lua_State *l, double value) { lua_pushnumber(l, value); }
17 inline void pi_lua_generic_push(lua_State *l, const char *value) { lua_pushstring(l, value); }
18 inline void pi_lua_generic_push(lua_State *l, const std::string &value)
19 {
20  lua_pushlstring(l, value.c_str(), value.size());
21 }
22 
23 inline void pi_lua_generic_pull(lua_State *l, int index, bool &out) { out = lua_toboolean(l, index); }
24 inline void pi_lua_generic_pull(lua_State *l, int index, int &out) { out = luaL_checkinteger(l, index); }
25 inline void pi_lua_generic_pull(lua_State *l, int index, unsigned int &out) { out = luaL_checkunsigned(l, index); }
26 inline void pi_lua_generic_pull(lua_State *l, int index, float &out) { out = luaL_checknumber(l, index); }
27 inline void pi_lua_generic_pull(lua_State *l, int index, double &out) { out = luaL_checknumber(l, index); }
28 inline void pi_lua_generic_pull(lua_State *l, int index, const char *&out) { out = luaL_checkstring(l, index); }
29 inline void pi_lua_generic_pull(lua_State *l, int index, std::string &out)
30 {
31  size_t len;
32  const char *buf = luaL_checklstring(l, index, &len);
33  std::string(buf, len).swap(out);
34 }
35 
36 template <typename Type>
37 inline void LuaPush(lua_State *l, Type value)
38 {
39  pi_lua_generic_push(l, value);
40 }
41 
42 template <typename Type>
43 inline typename std::remove_reference<Type>::type LuaPull(lua_State *l, int index)
44 {
45  typename std::decay<Type>::type value;
46  pi_lua_generic_pull(l, index, value);
47  return value;
48 }
49 
50 // Pull a value with an optional default.
51 template <typename Type>
52 inline Type LuaPull(lua_State *l, int index, Type defaultVal)
53 {
54  Type value = defaultVal;
55  if (lua_gettop(l) >= index && !lua_isnil(l, index))
56  pi_lua_generic_pull(l, index, value);
57  return value;
58 }
59 
60 inline bool pi_lua_strict_pull(lua_State *l, int index, bool &out)
61 {
62  if (lua_type(l, index) == LUA_TBOOLEAN) {
63  out = lua_toboolean(l, index);
64  return true;
65  }
66  return false;
67 }
68 inline bool pi_lua_strict_pull(lua_State *l, int index, int &out)
69 {
70  if (lua_type(l, index) == LUA_TNUMBER) {
71  out = lua_tointeger(l, index);
72  return true;
73  }
74  return false;
75 }
76 inline bool pi_lua_strict_pull(lua_State *l, int index, float &out)
77 {
78  if (lua_type(l, index) == LUA_TNUMBER) {
79  out = lua_tonumber(l, index);
80  return true;
81  }
82  return false;
83 }
84 inline bool pi_lua_strict_pull(lua_State *l, int index, double &out)
85 {
86  if (lua_type(l, index) == LUA_TNUMBER) {
87  out = lua_tonumber(l, index);
88  return true;
89  }
90  return false;
91 }
92 inline bool pi_lua_strict_pull(lua_State *l, int index, const char *&out)
93 {
94  if (lua_type(l, index) == LUA_TSTRING) {
95  out = lua_tostring(l, index);
96  return true;
97  }
98  return false;
99 }
100 inline bool pi_lua_strict_pull(lua_State *l, int index, std::string &out)
101 {
102  if (lua_type(l, index) == LUA_TSTRING) {
103  size_t len;
104  const char *buf = lua_tolstring(l, index, &len);
105  std::string(buf, len).swap(out);
106  return true;
107  }
108  return false;
109 }
110 template <typename... Types>
111 inline void pi_lua_multiple_push(lua_State *l, Types... args);
112 
113 #if defined(_MSC_VER) // Non-variadic version for MSVC
114 template <typename Arg1>
115 inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1)
116 {
117  pi_lua_generic_push(l, arg1);
118 }
119 
120 template <typename Arg1, typename Arg2>
121 inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1, Arg2 arg2)
122 {
123  pi_lua_generic_push(l, arg1);
124  pi_lua_generic_push(l, arg2);
125 }
126 
127 template <typename Arg1, typename Arg2, typename Arg3>
128 inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1, Arg2 arg2, Arg3 arg3)
129 {
130  pi_lua_generic_push(l, arg1);
131  pi_lua_generic_push(l, arg2);
132  pi_lua_generic_push(l, arg3);
133 }
134 
135 template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
136 inline void pi_lua_multiple_push(lua_State *l, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
137 {
138  pi_lua_generic_push(l, arg1);
139  pi_lua_generic_push(l, arg2);
140  pi_lua_generic_push(l, arg3);
141  pi_lua_generic_push(l, arg4);
142 }
143 #else // Just use the normal variadic version
144 template <typename Head, typename... Tail>
145 inline void pi_lua_multiple_push(lua_State *l, Head arg1, Tail... rest)
146 {
147  pi_lua_generic_push(l, arg1);
148  pi_lua_multiple_push(l, rest...);
149 }
150 #endif
151 
152 inline void pi_lua_multiple_push(lua_State *l)
153 {
154  return;
155 }
156 
157 #if defined(_MSC_VER)
158 template <typename Arg1, typename Arg2>
159 inline std::tuple<Arg1, Arg2> pi_lua_multiple_pull(lua_State *l, int beg)
160 {
161  beg = lua_absindex(l, beg);
162  Arg1 arg1;
163  Arg2 arg2;
164  pi_lua_generic_pull(l, beg, arg1);
165  pi_lua_generic_pull(l, beg + 1, arg2);
166  return std::make_tuple(arg1, arg2);
167 }
168 template <typename Arg1, typename Arg2, typename Arg3>
169 inline std::tuple<Arg1, Arg2, Arg3> pi_lua_multiple_pull(lua_State *l, int beg)
170 {
171  beg = lua_absindex(l, beg);
172  Arg1 arg1;
173  Arg2 arg2;
174  Arg3 arg3;
175  pi_lua_generic_pull(l, beg, arg1);
176  pi_lua_generic_pull(l, beg + 1, arg2);
177  pi_lua_generic_pull(l, beg + 2, arg3);
178  return std::make_tuple(arg1, arg2, arg3);
179 }
180 template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
181 inline std::tuple<Arg1, Arg2, Arg3, Arg4> pi_lua_multiple_pull(lua_State *l, int beg)
182 {
183  beg = lua_absindex(l, beg);
184  Arg1 arg1;
185  Arg2 arg2;
186  Arg3 arg3;
187  Arg4 arg4;
188  pi_lua_generic_pull(l, beg, arg1);
189  pi_lua_generic_pull(l, beg + 1, arg2);
190  pi_lua_generic_pull(l, beg + 2, arg3);
191  pi_lua_generic_pull(l, beg + 3, arg4);
192  return std::make_tuple(arg1, arg2, arg3, arg4);
193 }
194 #else
195 // The _bogus parameter is used to bring the empty type list case into the template world
196 // to solve name resolution problems.
197 template <int _bogus, typename Head, typename... Tail>
198 inline std::tuple<Head, Tail...> __helper_pi_lua_multiple_pull(lua_State *l, int beg)
199 {
200  beg = lua_absindex(l, beg);
201  std::tuple<Tail...> rest = __helper_pi_lua_multiple_pull<_bogus, Tail...>(l, beg + 1);
202  Head hd;
203  pi_lua_generic_pull(l, beg, hd);
204  std::tuple<Head> first(hd);
205  return std::tuple_cat(first, rest);
206 }
207 
208 template <int _bogus>
209 inline std::tuple<> __helper_pi_lua_multiple_pull(lua_State *l, int beg)
210 {
211  return std::tuple<>();
212 }
213 
214 template <typename... Types>
215 inline std::tuple<Types...> pi_lua_multiple_pull(lua_State *l, int beg)
216 {
217  return __helper_pi_lua_multiple_pull<0, Types...>(l, beg);
218 }
219 #endif
220 
221 #endif
void LuaPush(lua_State *l, Type value)
Definition: LuaPushPull.h:37
std::tuple< Head, Tail... > __helper_pi_lua_multiple_pull(lua_State *l, int beg)
Definition: LuaPushPull.h:198
bool pi_lua_strict_pull(lua_State *l, int index, bool &out)
Definition: LuaPushPull.h:60
std::tuple< Types... > pi_lua_multiple_pull(lua_State *l, int beg)
Definition: LuaPushPull.h:215
std::remove_reference< Type >::type LuaPull(lua_State *l, int index)
Definition: LuaPushPull.h:43
void pi_lua_multiple_push(lua_State *l, Types... args)
void pi_lua_generic_push(lua_State *l, bool value)
Definition: LuaPushPull.h:13
void pi_lua_generic_pull(lua_State *l, int index, bool &out)
Definition: LuaPushPull.h:23