diff --git a/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h b/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h index fef13d708b7..fb80a345e40 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h +++ b/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h @@ -43,73 +43,120 @@ struct CLuaFunctionParserBase std::string strError = ""; std::string strErrorFoundType = ""; - // Translates a variant type to a list of names separated by slashes - // std::variant => bool/int/float - template - void TypeToNameVariant(SString& accumulator) + template , bool> = true> + std::string TypeToName() { - using param = typename is_variant::param1_t; - if (accumulator.empty()) - accumulator = TypeToName(); - else - accumulator += "/" + TypeToName(); + return "string"; + } - if constexpr (is_variant::count != 1) - return TypeToNameVariant::rest_t>(accumulator); + template , bool> = true> + std::string TypeToName() + { + return "boolean"; } - template - SString TypeToName() + template , bool> = true> + std::string TypeToName() { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v) - return "string"; - else if constexpr (std::is_same_v) - return "boolean"; - else if constexpr (std::is_arithmetic_v) - return "number"; - else if constexpr (std::is_enum_v) - return "enum"; - else if constexpr (is_specialization::value) - { - using param_t = typename is_specialization::param_t; - return TypeToName(); - } - else if constexpr (std::is_same_v) - return "value"; - else if constexpr (std::is_same_v) - return "values"; - else if constexpr (is_2specialization::value) - return "table"; - else if constexpr (is_5specialization::value) - return "table"; - else if constexpr (std::is_same_v) - return "function"; - else if constexpr (std::is_same_v) - return "vector2"; - else if constexpr (std::is_same_v) - return "vector3"; - else if constexpr (std::is_same_v) - return "vector4"; - else if constexpr (std::is_same_v) - return "matrix"; - else if constexpr (std::is_same_v) - return "colour"; - else if constexpr (std::is_same_v) - return ""; // not reachable - else if constexpr (is_variant::value) - { - SString strTypes; - TypeToNameVariant(strTypes); - return strTypes; - } - else if constexpr (std::is_pointer_v && std::is_class_v>) - return GetClassTypeName((T)0); - else if constexpr (std::is_same_v) - return ""; - else if constexpr (std::is_same_v) - return ""; + return "number"; + } + + template , bool> = true> + std::string TypeToName() + { + return "enum"; + } + + template , bool> = true> + std::string TypeToName() + { + return "value"; + } + + template , bool> = true> + std::string TypeToName() + { + return "values"; + } + + template || is_map_v, bool> = true> + std::string TypeToName() + { + return "table"; + } + + template , bool> = true> + std::string TypeToName() + { + return TypeToName::param_t>(); + } + + template , bool> = true> + std::string TypeToName() + { + return "function"; + } + + template , bool> = true> + std::string TypeToName() + { + return "vector2"; + } + + template , bool> = true> + std::string TypeToName() + { + return "vector3"; + } + + template , bool> = true> + std::string TypeToName() + { + return "vector4"; + } + + template , bool> = true> + std::string TypeToName() + { + return "matrix"; + } + + template , bool> = true> + std::string TypeToName() + { + return "colour"; + } + + template && std::is_class_v>, bool> = true> + std::string TypeToName() + { + return "pointer"; + } + + template , bool> = true> + std::string TypeToName() + { + return "lua_State"; + } + + template , bool> = true> + std::string TypeToName() + { + return "monostate"; + } + + template ::value, bool> = true> + std::string TypeToName() + { + using variant_t = is_variant; + using param1_t = typename variant_t::param1_t; + using rest_t = typename variant_t::rest_t; + + std::string out = TypeToName(); + if constexpr (variant_t::count == 1) + return out; else - static_assert(sizeof(T) == 0, "Invalid parameter type provided to CLuaFunctionParser!"); + return out + "/" + TypeToName(); } // Reads the parameter type (& value in some cases) at a given index @@ -187,14 +234,17 @@ struct CLuaFunctionParserBase // If it matches, we've found our index using first_t = typename is_variant::param1_t; using next_t = typename is_variant::rest_t; - if (TypeMatch(L, index)) + if constexpr (TypeMatch(L, index)) return 0; - - // Else try the remaining types of the variant - int iResult = TypeMatchVariant(L, index); - if (iResult == -1) - return -1; - return 1 + iResult; + else + { + // Else try the remaining types of the variant + int iResult = TypeMatchVariant(L, index); + if constexpr (iResult == -1) + return -1; + else + return 1 + iResult; + } } } @@ -207,8 +257,8 @@ struct CLuaFunctionParserBase { int iArgument = lua_type(L, index); // primitive types - if constexpr (std::is_same_v || std::is_same_v) - return (iArgument == LUA_TSTRING || iArgument == LUA_TNUMBER); + if constexpr (is_string_v) + return iArgument == LUA_TSTRING || iArgument == LUA_TNUMBER; else if constexpr (std::is_same_v) return (iArgument == LUA_TBOOLEAN); else if constexpr (std::is_arithmetic_v) @@ -220,10 +270,7 @@ struct CLuaFunctionParserBase return iArgument == LUA_TSTRING; // CLuaArgument can hold any value - else if constexpr (std::is_same_v) - return iArgument != LUA_TNONE; - - else if constexpr (std::is_same_v) + else if constexpr (std::is_same_v || std::is_same_v) return iArgument != LUA_TNONE; // All color classes are read as a single tocolor number @@ -239,12 +286,8 @@ struct CLuaFunctionParserBase else if constexpr (is_specialization::value) return true; - // std::vector is used for arrays built from tables - else if constexpr (is_2specialization::value) - return iArgument == LUA_TTABLE; - - // std::unordered_map is used for maps built from tables - else if constexpr (is_5specialization::value) + // std::vector and std::unordered_map are used for arrays built from tables + else if constexpr (is_vector_v || is_map_v) return iArgument == LUA_TTABLE; // CLuaFunctionRef is used for functions @@ -298,12 +341,8 @@ struct CLuaFunctionParserBase else if constexpr (std::is_pointer_v && std::is_class_v>) return iArgument == LUA_TUSERDATA || iArgument == LUA_TLIGHTUSERDATA; - // dummy type is used as overload extension if one overload has fewer arguments + // monostate type is used as overload extension if one overload has fewer arguments // thus it is only allowed if there are no further args on the Lua side - else if constexpr (std::is_same_v) - return iArgument == LUA_TNONE; - - // no value else if constexpr (std::is_same_v) return iArgument == LUA_TNONE; } @@ -323,12 +362,14 @@ struct CLuaFunctionParserBase else { // If we haven't reached the target index go to the next type - if (vindex != currIndex) + if constexpr (vindex != currIndex) return PopUnsafeVariant(L, index, vindex); - - // Pop the actual type - using type_t = std::remove_reference_t(T{}))>; - return PopUnsafe(L, index); + else + { + // Pop the actual type + using type_t = std::remove_reference_t(T{}))>; + return PopUnsafe(L, index); + } } } @@ -369,8 +410,8 @@ struct CLuaFunctionParserBase // Expect no change in stack size LUA_STACK_EXPECT(0); // the dummy type is not read from Lua - if constexpr (std::is_same_v) - return dummy_type{}; + if constexpr (std::is_same_v) + return std::monostate{}; // primitive types are directly popped else if constexpr (std::is_same_v || std::is_same_v) return lua::PopPrimitive(L, index); diff --git a/Shared/sdk/CVector.h b/Shared/sdk/CVector.h index 5c2ddde7a65..de59a016def 100644 --- a/Shared/sdk/CVector.h +++ b/Shared/sdk/CVector.h @@ -17,6 +17,9 @@ class CVector2D; +class CVector; +using CVector3D = CVector; + /** * CVector Structure used to store a 3D vertex. */ diff --git a/Shared/sdk/SharedUtil.Template.h b/Shared/sdk/SharedUtil.Template.h index 86627eab8f4..f088339e320 100644 --- a/Shared/sdk/SharedUtil.Template.h +++ b/Shared/sdk/SharedUtil.Template.h @@ -3,6 +3,104 @@ #include #include +template +struct is_string : std::false_type +{ +}; +template <> +struct is_string : std::true_type +{ +}; +template <> +struct is_string : std::true_type +{ +}; +template <> +struct is_string : std::true_type +{ +}; +template <> +struct is_string : std::true_type +{ +}; + +template +constexpr bool is_string_v = is_string::value; + +// Get it ready for C++20 +#if __cplusplus >= 202002L +template +concept string_concept_t = is_string_v; +#endif + +template +struct is_vector : std::false_type +{ +}; + +template +struct is_vector> : std::true_type +{ + using param_t = T; +}; + +template +constexpr bool is_vector_v = is_vector::value; + +// Get it ready for C++20 +#if __cplusplus >= 202002L +template +concept vector_concept_t = is_vector_v; +#endif + +template +struct is_map : std::false_type +{ +}; + +template +struct is_map> : std::true_type +{ + using key_t = Key; + using value_t = Value; +}; + +template +struct is_map> : std::true_type +{ + using key_t = Key; + using value_t = Value; +}; + +template +constexpr bool is_map_v = is_map::value; + +// Get it ready for C++20 +#if __cplusplus >= 202002L +template +concept map_concept_t = is_map_v; +#endif + +template +struct is_optional : std::false_type +{ +}; + +template +struct is_optional> : std::true_type +{ + using param_t = T; +}; + +template +constexpr bool is_optional_v = is_optional::value; + +// Get it ready for C++20 +#if __cplusplus >= 202002L +template +concept optional_concept_t = is_optional_v; +#endif + /** is_Nspecialization @@ -87,6 +185,15 @@ struct is_variant> : std::true_type static constexpr auto count = sizeof...(Args) + 1; }; +template +constexpr bool is_variant_v = is_variant::value; + +// Get it ready for C++20 +#if __cplusplus >= 202002L +template +concept variant_concept_t = is_variant_v; +#endif + /** nth_element @@ -187,12 +294,6 @@ struct common_variant, std::variant> using type = typename common_variant, typename common_variant>::type>::type; }; -// dummy_type -// generic dummy type -struct dummy_type -{ -}; - // n_tuple: Constructs a tuple of size N (with dummy_type as parameter types) // n_tuple<2>::type == std::tuple template @@ -210,7 +311,7 @@ struct n_tuple template struct n_tuple { - using type = typename n_tuple= N, Args..., dummy_type>::type; + using type = typename n_tuple= N, Args..., std::monostate>::type; }; // pad_func_with_func