Skip to content

Commit d5d8ae7

Browse files
committed
Full support for overloads
1 parent d0ce0c6 commit d5d8ae7

File tree

5 files changed

+85
-15
lines changed

5 files changed

+85
-15
lines changed

Client/mods/deathmatch/logic/luadefs/CLuaDefs.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,14 @@ class CLuaDefs
7474
return CLuaFunctionParser<false, T>()(L, m_pScriptDebugging);
7575
}
7676

77-
template <auto T, auto U>
77+
// Special cases for overloads
78+
template <auto T, auto U, auto... Ts>
7879
static inline int ArgumentParserWarn(lua_State* L)
7980
{
80-
return CLuaFunctionParser<false, CLuaOverloadParser<T, U>::Call>()(L, m_pScriptDebugging);
81+
if constexpr (sizeof...(Ts) == 0)
82+
return ArgumentParserWarn<CLuaOverloadParser<pad_func_with_func<T, U>::Call, pad_func_with_func<U, T>::Call>::Call>(L);
83+
else
84+
return ArgumentParserWarn<CLuaOverloadParser<pad_func_with_func<T, U>::Call, pad_func_with_func<U, T>::Call>::Call, Ts...>(L);
8185
}
8286

8387
// New style: hard error on usage mistakes
@@ -88,9 +92,12 @@ class CLuaDefs
8892
}
8993

9094
// Overload variant
91-
template <auto T, auto U>
95+
template <auto T, auto U, auto... Ts>
9296
static inline int ArgumentParser(lua_State* L)
9397
{
94-
return CLuaFunctionParser<true, CLuaOverloadParser<T, U>::Call>()(L, m_pScriptDebugging);
98+
if constexpr (sizeof...(Ts) == 0)
99+
return ArgumentParser<CLuaOverloadParser<pad_func_with_func<T, U>::Call, pad_func_with_func<U, T>::Call>::Call>(L);
100+
else
101+
return ArgumentParser<CLuaOverloadParser<pad_func_with_func<T, U>::Call, pad_func_with_func<U, T>::Call>::Call, Ts...>(L);
95102
}
96103
};

Server/mods/deathmatch/logic/luadefs/CLuaDefs.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,14 @@ class CLuaDefs
9595
return CLuaFunctionParser<false, T>()(L, m_pScriptDebugging);
9696
}
9797

98-
template <auto T, auto U>
98+
// Special cases for overloads
99+
template <auto T, auto U, auto... Ts>
99100
static inline int ArgumentParserWarn(lua_State* L)
100101
{
101-
return CLuaFunctionParser<false, CLuaOverloadParser<T, U>::Call>()(L, m_pScriptDebugging);
102+
if constexpr (sizeof...(Ts) == 0)
103+
return ArgumentParserWarn<CLuaOverloadParser<pad_func_with_func<T, U>::Call, pad_func_with_func<U, T>::Call>::Call>(L);
104+
else
105+
return ArgumentParserWarn<CLuaOverloadParser<pad_func_with_func<T, U>::Call, pad_func_with_func<U, T>::Call>::Call, Ts...>(L);
102106
}
103107

104108
// New style: hard error on usage mistakes
@@ -109,9 +113,12 @@ class CLuaDefs
109113
}
110114

111115
// Overload variant
112-
template <auto T, auto U>
116+
template <auto T, auto U, auto... Ts>
113117
static inline int ArgumentParser(lua_State* L)
114118
{
115-
return CLuaFunctionParser<true, CLuaOverloadParser<T, U>::Call>()(L, m_pScriptDebugging);
119+
if constexpr (sizeof...(Ts) == 0)
120+
return ArgumentParser<CLuaOverloadParser<pad_func_with_func<T, U>::Call, pad_func_with_func<U, T>::Call>::Call>(L);
121+
else
122+
return ArgumentParser<CLuaOverloadParser<pad_func_with_func<T, U>::Call, pad_func_with_func<U, T>::Call>::Call, Ts...>(L);
116123
}
117124
};

Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct CLuaFunctionParser<ErrorOnFailure, Func>
3434
using param = typename is_variant<T>::param1_t;
3535
if (accumulator.length() == 0)
3636
accumulator = typeToName<param>();
37-
else
37+
else
3838
accumulator += "/" + typeToName<param>();
3939

4040
if constexpr (is_variant<T>::count != 1)
@@ -69,12 +69,13 @@ struct CLuaFunctionParser<ErrorOnFailure, Func>
6969
else if constexpr (is_variant<T>::value)
7070
{
7171
SString strTypes;
72-
typeToNameVariant<T>(strTypes);
72+
typeToNameVariant<T>(strTypes);
7373
return strTypes;
7474
}
75-
7675
else if constexpr (std::is_pointer_v<T> && std::is_class_v<std::remove_pointer_t<T>>)
7776
return GetClassTypeName((T)0);
77+
else if constexpr (std::is_same_v<T, dummy_type>)
78+
return "";
7879
}
7980

8081
static SString ResolveParameter(lua_State* L, std::size_t index)
@@ -215,6 +216,11 @@ struct CLuaFunctionParser<ErrorOnFailure, Func>
215216
// and can be fetched from a userdata
216217
if constexpr (std::is_pointer_v<T> && std::is_class_v<std::remove_pointer_t<T>>)
217218
return iArgument == LUA_TUSERDATA || iArgument == LUA_TLIGHTUSERDATA;
219+
220+
// dummy type is used as overload extension if one overload has fewer arguments
221+
// thus it is only allowed if there are no further args on the Lua side
222+
if constexpr (std::is_same_v<T, dummy_type>)
223+
return iArgument == LUA_TNONE;
218224
}
219225

220226
// Special PopUnsafe for variants
@@ -249,10 +255,13 @@ struct CLuaFunctionParser<ErrorOnFailure, Func>
249255
inline T PopUnsafe(lua_State* L, std::size_t& index)
250256
{
251257
// Expect no change in stack size
252-
LUA_STACK_EXPECT(0);
258+
LUA_STACK_EXPECT(0);
259+
// the dummy type is not read from Lua
260+
if constexpr (std::is_same_v<T, dummy_type>)
261+
return dummy_type{};
253262
// trivial types are directly popped
254-
if constexpr (std::is_same_v<T, std::string> || std::is_same_v<T, int> || std::is_same_v<T, float> || std::is_same_v<T, double> ||
255-
std::is_same_v<T, short> || std::is_same_v<T, unsigned int> || std::is_same_v<T, unsigned short> || std::is_same_v<T, bool>)
263+
else if constexpr (std::is_same_v<T, std::string> || std::is_same_v<T, int> || std::is_same_v<T, float> || std::is_same_v<T, double> ||
264+
std::is_same_v<T, short> || std::is_same_v<T, unsigned int> || std::is_same_v<T, unsigned short> || std::is_same_v<T, bool>)
256265
return lua::PopTrivial<T>(L, index);
257266
else if constexpr (std::is_enum_v<T>)
258267
{

Shared/mods/deathmatch/logic/lua/CLuaOverloadParser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct CLuaOverloadParser<Func, Func2>
3232
template <std::size_t N, typename... Ts, typename... Us>
3333
static ChosenFunction MakeAllChoice(std::variant<Ts...> var, Us... us)
3434
{
35-
ChosenFunction result = MakeChoice<0>(var);
35+
ChosenFunction result = MakeChoice<N>(var);
3636
if constexpr (sizeof...(Us) == 0)
3737
return result;
3838
else

Shared/sdk/SharedUtil.Template.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,50 @@ struct common_variant<std::variant<T, Ts...>, std::variant<Us...>>
144144
{
145145
using type = typename common_variant<std::variant<Ts...>, typename common_variant<T, std::variant<Us...>>::type>::type;
146146
};
147+
148+
// dummy_type
149+
// generic dummy type
150+
struct dummy_type
151+
{
152+
};
153+
154+
155+
// n_tuple: Constructs a tuple of size N
156+
// n_tuple<2>::type == std::tuple<dummy_type, dummy_type>
157+
template <std::size_t, bool B = false, typename... Args>
158+
struct n_tuple;
159+
160+
template <std::size_t N, typename... Args>
161+
struct n_tuple<N, true, Args...>
162+
{
163+
using type = std::tuple<Args...>;
164+
};
165+
166+
template <std::size_t N, typename... Args>
167+
struct n_tuple<N, false, Args...>
168+
{
169+
using type = typename n_tuple<N, sizeof...(Args) + 1 >= N, Args..., dummy_type>::type;
170+
};
171+
172+
// pad_func_with_func
173+
// pads Func with as many dummy_type arguments as needed to
174+
// have the same number of arguments as FuncB has
175+
template <auto* Func, typename T>
176+
struct pad_func_with_func_impl
177+
{
178+
};
179+
template <typename... Ts, typename Ret, typename... Args, auto (*Func)(Args...)->Ret>
180+
struct pad_func_with_func_impl<Func, std::tuple<Ts...>>
181+
{
182+
static inline Ret Call(Args... arg, Ts... args) { return Func(arg...); }
183+
};
184+
185+
template <auto*, auto*>
186+
struct pad_func_with_func
187+
{
188+
};
189+
template <typename Ret, typename... Args, auto (*Func)(Args...)->Ret, typename RetB, typename... ArgsB, auto (*FuncB)(ArgsB...)->RetB>
190+
struct pad_func_with_func<Func, FuncB> : pad_func_with_func_impl<Func, typename n_tuple<std::max(sizeof...(Args), sizeof...(ArgsB)) - sizeof...(Args),
191+
std::max(sizeof...(Args), sizeof...(ArgsB)) - sizeof...(Args) == 0>::type>
192+
{
193+
};

0 commit comments

Comments
 (0)