25 #include <string_view>
26 #include <type_traits>
32 template<
typename T,
typename T2 =
void>
37 typename std::decay_t<T>::value_type,
38 typename std::decay_t<T>::iterator,
39 typename std::decay_t<T>::size_type,
40 typename std::decay_t<T>::reference>
41 > : std::true_type {};
43 template<
class T,
template<
class>
class U>
46 template<
template<
class>
class U,
class V>
47 inline constexpr
bool is_instance_of_v<U<V>,U> = std::true_type{};
49 template<
typename T,
typename T2 =
void>
54 typename std::decay_t<T>::key_type,
55 typename std::decay_t<T>::mapped_type>
56 > : std::true_type {};
58 template<
typename T,
typename T2 =
void>
63 typename std::decay_t<T>::first_type,
64 typename std::decay_t<T>::second_type>
65 > : std::true_type {};
68 std::enable_if_t<std::is_same_v<T, lua_index_raw>,
lua_index_raw>
74 std::enable_if_t<std::is_same_v<T, lua_index_raw>,
lua_index_raw>
82 std::enable_if_t<std::is_same_v<T, std::string>, std::string>
85 return luaL_checkstring(L,
n);
88 std::enable_if_t<std::is_same_v<T, std::string>, std::string>
91 return luaL_optstring(L,
n, def.c_str());
94 std::enable_if_t<std::is_same_v<T, std::string>,
void>
97 lua_pushlstring(L, val.c_str(), val.size());
102 std::enable_if_t<std::is_same_v<T, std::string_view>, std::string_view>
108 std::enable_if_t<std::is_same_v<T, std::string_view>, std::string_view>
114 std::enable_if_t<std::is_same_v<T, std::string_view>,
void>
117 lua_pushlstring(L, val.data(), val.size());
122 std::enable_if_t<std::is_same_v<T, config>,
config>
128 std::enable_if_t<std::is_same_v<T, config>,
config>
135 std::enable_if_t<std::is_same_v<T, config>,
void>
143 std::enable_if_t<std::is_same_v<T, map_location>,
map_location>
149 std::enable_if_t<std::is_same_v<T, map_location>,
map_location>
159 std::enable_if_t<std::is_same_v<T, map_location>,
void>
167 std::enable_if_t<std::is_same_v<T, t_string>,
t_string>
173 std::enable_if_t<std::is_same_v<T, t_string>,
void>
182 std::enable_if_t<std::is_same_v<T, gui2::widget>,
void>
190 std::enable_if_t<std::is_same_v<T, bool>,
bool>
196 std::enable_if_t<std::is_same_v<T, bool>,
bool>
202 std::enable_if_t<std::is_same_v<T, bool>,
void>
205 lua_pushboolean(L, val);
210 std::enable_if_t<std::is_floating_point_v<T>, T>
213 return luaL_checknumber(L,
n);
216 std::enable_if_t<std::is_floating_point_v<T>, T>
220 lua_Number
d = lua_tonumberx(L,
n, &isnum);
227 std::enable_if_t<std::is_floating_point_v<T>,
void>
230 lua_pushnumber(L, val);
235 std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>, T>
238 return luaL_checkinteger(L,
n);
241 std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>, T>
245 lua_Integer res = lua_tointegerx(L,
n, &isnum);
253 std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>,
void>
256 lua_pushinteger(L, val);
262 std::enable_if_t<is_pair<T>::value && !std::is_const_v<typename T::first_type>, T>
266 if (lua_istable(L,
n)) {
267 lua_rawgeti(L,
n, 1);
268 result.first = lua_check<const typename T::first_type&>(L, -1);
269 lua_rawgeti(L,
n, 2);
270 result.second = lua_check<const typename T::second_type&>(L, -1);
276 std::enable_if_t<is_pair<T>::value && !std::is_const_v<typename T::first_type>,
void>
280 lua_push<const typename T::first_type&>(L, val.first);
281 lua_rawseti(L, -2, 1);
282 lua_push<const typename T::second_type&>(L, val.second);
283 lua_rawseti(L, -2, 2);
288 std::enable_if_t<is_container<T>::value && !std::is_same_v<T, std::string> && !std::is_same_v<T, std::string_view>, T>
291 if (lua_istable(L,
n))
294 for (
int i = 1, i_end = lua_rawlen(L,
n);
i <= i_end; ++
i)
296 lua_rawgeti(L,
n,
i);
304 luaL_argerror(L,
n,
"Table expected");
305 throw "luaL_argerror returned";
312 is_container<T>::value && !std::is_same_v<T, std::string> && !std::is_same_v<T, std::string_view> && !is_map<T>::value
318 assert(list.size() >= 0);
319 lua_createtable(L, list.size(), 0);
321 for(
typename T::const_iterator iter = list.begin(); iter != list.end(); ++iter) {
322 lua_check_impl::lua_push<std::decay_t<typename T::reference>>(L, *iter);
323 lua_rawseti(L, -2,
i++);
329 std::enable_if_t<is_map<T>::value,
void>
333 for(
const typename T::value_type& pair : map)
335 lua_check_impl::lua_push<std::decay_t<typename T::key_type>>(L, pair.first);
336 lua_check_impl::lua_push<std::decay_t<typename T::mapped_type>>(L, pair.second);
346 std::string str = lua_check_impl::lua_check<std::string>(L,
n);
347 utils::optional<typename T::type> val = T::get_enum(str);
349 luaL_argerror(L,
n, (
"cannot convert " + str +
" to enum.").c_str());
356 std::enable_if_t<is_instance_of_v<T, utils::optional>, T>
359 if(lua_isnoneornil(L,
n)) {
362 return lua_check_impl::lua_check<typename T::value_type>(L,
n);
366 std::enable_if_t<is_instance_of_v<T, utils::optional>,
void>
370 lua_check_impl::lua_push<typename T::value_type>(L, *opt);
380 return lua_check_impl::lua_check<T>(L,
n);
387 return lua_check_impl::lua_check<std::decay_t<T>>(L,
n);
394 return lua_check_impl::lua_to_or_default<std::decay_t<T>>(L,
n, def);
400 return lua_check_impl::lua_push<std::decay_t<T>>(L, val);
410 if(!lua_istable(L,
index)) {
411 luaL_argerror(L,
index,
"table expected");
417 lua_pushlstring(L, k.data(), k.size());
418 lua_gettable(L,
index);
419 if(lua_isnoneornil(L, -1)) {
423 T res = lua_check_impl::lua_to_or_default<std::decay_t<T>>(L, -1, def);
432 if(!lua_istable(L,
index)) {
433 luaL_argerror(L,
index,
"table expected");
437 lua_pushlstring(L, k.data(), k.size());
439 lua_settable(L,
index);
A config object defines a single node in a WML file, with access to child nodes.
void luaW_pushconfig(lua_State *L, const config &cfg)
Converts a config object to a Lua table pushed at the top of the stack.
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
void luaW_pushlocation(lua_State *L, const map_location &ml)
Converts a map location object to a Lua table pushed at the top of the stack.
void luaW_pushtstring(lua_State *L, const t_string &v)
Pushes a t_string on the top of the stack.
bool luaW_toboolean(lua_State *L, int n)
std::string_view luaW_tostring(lua_State *L, int index)
std::string_view luaW_tostring_or_default(lua_State *L, int index, std::string_view def)
bool luaW_toconfig(lua_State *L, int index, config &cfg)
Converts an optional table or vconfig to a config object.
bool luaW_tolocation(lua_State *L, int index, map_location &loc)
Converts an optional table or pair of integers to a map location object.
map_location luaW_checklocation(lua_State *L, int index)
Converts an optional table or pair of integers to a map location object.
t_string luaW_checktstring(lua_State *L, int index)
Converts a scalar to a translatable string.
std::enable_if_t< std::is_same_v< T, lua_index_raw >, lua_index_raw > lua_to_or_default(lua_State *, int n, const T &)
std::enable_if_t< std::is_same_v< T, std::string >, void > lua_push(lua_State *L, const T &val)
constexpr bool is_instance_of_v
std::enable_if_t< std::is_same_v< T, lua_index_raw >, lua_index_raw > lua_check(lua_State *, int n)
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
std::decay_t< T > lua_to_or_default(lua_State *L, int n, const T &def)
std::decay_t< T > lua_check(lua_State *L, int n)
void lua_push(lua_State *L, const T &val)
T::type lua_enum_check(lua_State *L, int n)
std::decay_t< T > luaW_table_get_def(lua_State *L, int index, std::string_view k, const T &def)
returns t[k] where k is the table at index index and k is k or def if it is not convertible to the co...
void luaW_table_set(lua_State *L, int index, std::string_view k, const T &value)
Encapsulates the map of the game.
static map_location::DIRECTION n