@@ -352,19 +352,41 @@ struct CLuaFunctionParserBase
352352 if constexpr (std::is_same_v<T, dummy_type>)
353353 return dummy_type{};
354354 // primitive types are directly popped
355- else if constexpr (std::is_same_v<T, std::string> || std::is_same_v<T, std::string_view> || std::is_integral_v<T> )
355+ else if constexpr (std::is_same_v<T, std::string> || std::is_same_v<T, std::string_view>)
356356 return lua::PopPrimitive<T>(L, index);
357- // floats/doubles may not be NaN
358- else if constexpr (std::is_same_v<T, float > || std::is_same_v<T, double >)
357+ else if constexpr (std::is_same_v<T, bool >)
358+ return lua::PopPrimitive<T>(L, index);
359+ else if constexpr (std::is_integral_v<T> || std::is_floating_point_v<T>) // bool is an integral type, so must pop it before ^^
359360 {
360- T value = lua::PopPrimitive<T >(L, index);
361- if ( std::isnan (value))
362- {
361+ const auto number = lua::PopPrimitive<lua_Number >(L, index);
362+ 363+ const auto SetError = [&]( const char * expected, const char * got) {
363364 // Subtract one from the index, as the call to lua::PopPrimitive above increments the index, even if the
364365 // underlying element is of a wrong type
365- SetBadArgumentError (L, " number" , index - 1 , " NaN" );
366+ SetBadArgumentError (L, expected, index - 1 , got);
367+ };
368+ 369+ if (std::isnan (number))
370+ {
371+ SetError (" number" , " NaN" );
372+ return static_cast <T>(number);
373+ }
374+ 375+ if (std::isinf (number)) {
376+ SetError (" number" , " inf" );
377+ return static_cast <T>(number);
366378 }
367- return value;
379+ 380+ // NOTE/TODO: Use C++20 `std::in_range` here instead
381+ // For now this doesn't do all the safety checks, but this should be "good enough" [until we switch to C++20]
382+ if constexpr (std::is_integral_v<T> && std::is_unsigned_v<T>)
383+ {
384+ SetError (" positive number" , " negative" );
385+ 386+ return static_cast <T>(static_cast <int64_t >(number));
387+ }
388+ 389+ return static_cast <T>(number);
368390 }
369391 else if constexpr (std::is_enum_v<T>)
370392 {
@@ -488,10 +510,7 @@ struct CLuaFunctionParserBase
488510 {
489511 if (lua_isnumber (L, index))
490512 {
491- CVector2D vec;
492- vec.fX = lua::PopPrimitive<float >(L, index);
493- vec.fY = lua::PopPrimitive<float >(L, index);
494- return vec;
513+ return { PopUnsafe<float >(L, index), PopUnsafe<float >(L, index) };
495514 }
496515 else
497516 {
@@ -520,11 +539,7 @@ struct CLuaFunctionParserBase
520539 {
521540 if (lua_isnumber (L, index))
522541 {
523- CVector vec;
524- vec.fX = lua::PopPrimitive<float >(L, index);
525- vec.fY = lua::PopPrimitive<float >(L, index);
526- vec.fZ = lua::PopPrimitive<float >(L, index);
527- return vec;
542+ return { PopUnsafe<float >(L, index), PopUnsafe<float >(L, index), PopUnsafe<float >(L, index) };
528543 }
529544 else
530545 {
@@ -551,12 +566,8 @@ struct CLuaFunctionParserBase
551566 {
552567 if (lua_isnumber (L, index))
553568 {
554- CVector4D vec;
555- vec.fX = lua::PopPrimitive<float >(L, index);
556- vec.fY = lua::PopPrimitive<float >(L, index);
557- vec.fZ = lua::PopPrimitive<float >(L, index);
558- vec.fW = lua::PopPrimitive<float >(L, index);
559- return vec;
569+ return { PopUnsafe<float >(L, index), PopUnsafe<float >(L, index),
570+ PopUnsafe<float >(L, index), PopUnsafe<float >(L, index) };
560571 }
561572 else
562573 {
@@ -583,19 +594,17 @@ struct CLuaFunctionParserBase
583594 {
584595 if (lua_isnumber (L, index))
585596 {
597+ const auto ReadVector = [&] {
598+ return CVector (PopUnsafe<float >(L, index), PopUnsafe<float >(L, index), PopUnsafe<float >(L, index));
599+ };
600+ 586601 CMatrix matrix;
587- matrix.vRight .fX = lua::PopPrimitive<float >(L, index);
588- matrix.vRight .fY = lua::PopPrimitive<float >(L, index);
589- matrix.vRight .fZ = lua::PopPrimitive<float >(L, index);
590- matrix.vFront .fX = lua::PopPrimitive<float >(L, index);
591- matrix.vFront .fY = lua::PopPrimitive<float >(L, index);
592- matrix.vFront .fZ = lua::PopPrimitive<float >(L, index);
593- matrix.vUp .fX = lua::PopPrimitive<float >(L, index);
594- matrix.vUp .fY = lua::PopPrimitive<float >(L, index);
595- matrix.vUp .fZ = lua::PopPrimitive<float >(L, index);
596- matrix.vPos .fX = lua::PopPrimitive<float >(L, index);
597- matrix.vPos .fY = lua::PopPrimitive<float >(L, index);
598- matrix.vPos .fZ = lua::PopPrimitive<float >(L, index);
602+ 603+ matrix.vRight = ReadVector ();
604+ matrix.vFront = ReadVector ();
605+ matrix.vUp = ReadVector ();
606+ matrix.vPos = ReadVector ();
607+ 599608 return matrix;
600609 }
601610 else
@@ -635,7 +644,7 @@ struct CLuaFunctionParserBase
635644 return static_cast <T>(result);
636645 }
637646 else if constexpr (std::is_same_v<T, SColor>)
638- return static_cast <unsigned long >(lua::PopPrimitive<int64_t >(L, index));
647+ return static_cast <unsigned long >(static_cast < int64_t >( lua::PopPrimitive<lua_Number >(L, index) ));
639648 else if constexpr (std::is_same_v<T, CLuaArgument>)
640649 {
641650 CLuaArgument argument;
0 commit comments