Skip to content

Commit 666eddc

Browse files
committed
Merge branch 'master' into dev/extensible_class_bug
2 parents 903d611 + 3254c8f commit 666eddc

4 files changed

Lines changed: 173 additions & 32 deletions

File tree

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ build/
1414
.DS_store
1515
.idea/
1616
cmake-build-*/
17+
tmpunwind.o

‎Distribution/LuaBridge/LuaBridge.h‎

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <algorithm>
1010
#include <array>
1111
#include <cassert>
12+
#include <cmath>
1213
#include <cstddef>
1314
#include <cstdint>
1415
#include <cstdio>
@@ -656,26 +657,33 @@ constexpr bool is_integral_representable_by(T value)
656657
if constexpr (sizeof(T) == sizeof(U))
657658
{
658659
if constexpr (same_signedness)
660+
{
659661
return true;
660-
661-
if constexpr (std::is_unsigned_v<T>)
662+
}
663+
else if constexpr (std::is_unsigned_v<T>)
664+
{
662665
return value <= static_cast<T>((std::numeric_limits<U>::max)());
663-
664-
return value >= static_cast<T>((std::numeric_limits<U>::min)())
665-
&& static_cast<U>(value) <= (std::numeric_limits<U>::max)();
666+
}
667+
else
668+
{
669+
return value >= static_cast<T>((std::numeric_limits<U>::min)())
670+
&& static_cast<U>(value) <= (std::numeric_limits<U>::max)();
671+
}
666672
}
667-
668-
if constexpr (sizeof(T) < sizeof(U))
673+
else if constexpr (sizeof(T) < sizeof(U))
669674
{
670675
return static_cast<U>(value) >= (std::numeric_limits<U>::min)()
671676
&& static_cast<U>(value) <= (std::numeric_limits<U>::max)();
672677
}
673-
674-
if constexpr (std::is_unsigned_v<T>)
678+
else if constexpr (std::is_unsigned_v<T>)
679+
{
675680
return value <= static_cast<T>((std::numeric_limits<U>::max)());
676-
677-
return value >= static_cast<T>((std::numeric_limits<U>::min)())
678-
&& value <= static_cast<T>((std::numeric_limits<U>::max)());
681+
}
682+
else
683+
{
684+
return value >= static_cast<T>((std::numeric_limits<U>::min)())
685+
&& value <= static_cast<T>((std::numeric_limits<U>::max)());
686+
}
679687
}
680688

681689
template <class U = lua_Integer>
@@ -689,17 +697,28 @@ bool is_integral_representable_by(lua_State* L, int index)
689697
}
690698

691699
template <class U = lua_Number, class T>
692-
constexpr bool is_floating_point_representable_by(T value)
700+
bool is_floating_point_representable_by(T value)
693701
{
694702
if constexpr (sizeof(T) == sizeof(U))
703+
{
695704
return true;
705+
}
706+
else if constexpr (sizeof(T) < sizeof(U))
707+
{
708+
if (std::isnan(value) || std::isinf(value))
709+
return true;
696710

697-
if constexpr (sizeof(T) < sizeof(U))
698711
return static_cast<U>(value) >= -(std::numeric_limits<U>::max)()
699712
&& static_cast<U>(value) <= (std::numeric_limits<U>::max)();
713+
}
714+
else
715+
{
716+
if (std::isnan(value) || std::isinf(value))
717+
return true;
700718

701-
return value >= static_cast<T>(-(std::numeric_limits<U>::max)())
702-
&& value <= static_cast<T>((std::numeric_limits<U>::max)());
719+
return value >= static_cast<T>(-(std::numeric_limits<U>::max)())
720+
&& value <= static_cast<T>((std::numeric_limits<U>::max)());
721+
}
703722
}
704723

705724
template <class U = lua_Number>

‎Source/LuaBridge/detail/LuaHelpers.h‎

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "Config.h"
1010

11+
#include <cmath>
1112
#include <cstdint>
1213
#include <cstdio>
1314
#include <cstdlib>
@@ -626,26 +627,33 @@ constexpr bool is_integral_representable_by(T value)
626627
if constexpr (sizeof(T) == sizeof(U))
627628
{
628629
if constexpr (same_signedness)
630+
{
629631
return true;
630-
631-
if constexpr (std::is_unsigned_v<T>)
632+
}
633+
else if constexpr (std::is_unsigned_v<T>)
634+
{
632635
return value <= static_cast<T>((std::numeric_limits<U>::max)());
633-
634-
return value >= static_cast<T>((std::numeric_limits<U>::min)())
635-
&& static_cast<U>(value) <= (std::numeric_limits<U>::max)();
636+
}
637+
else
638+
{
639+
return value >= static_cast<T>((std::numeric_limits<U>::min)())
640+
&& static_cast<U>(value) <= (std::numeric_limits<U>::max)();
641+
}
636642
}
637-
638-
if constexpr (sizeof(T) < sizeof(U))
643+
else if constexpr (sizeof(T) < sizeof(U))
639644
{
640645
return static_cast<U>(value) >= (std::numeric_limits<U>::min)()
641646
&& static_cast<U>(value) <= (std::numeric_limits<U>::max)();
642647
}
643-
644-
if constexpr (std::is_unsigned_v<T>)
648+
else if constexpr (std::is_unsigned_v<T>)
649+
{
645650
return value <= static_cast<T>((std::numeric_limits<U>::max)());
646-
647-
return value >= static_cast<T>((std::numeric_limits<U>::min)())
648-
&& value <= static_cast<T>((std::numeric_limits<U>::max)());
651+
}
652+
else
653+
{
654+
return value >= static_cast<T>((std::numeric_limits<U>::min)())
655+
&& value <= static_cast<T>((std::numeric_limits<U>::max)());
656+
}
649657
}
650658

651659
template <class U = lua_Integer>
@@ -662,17 +670,28 @@ bool is_integral_representable_by(lua_State* L, int index)
662670
* @brief Checks if the value on the stack is a number type and can fit into the corresponding c++ numerical type..
663671
*/
664672
template <class U = lua_Number, class T>
665-
constexpr bool is_floating_point_representable_by(T value)
673+
bool is_floating_point_representable_by(T value)
666674
{
667675
if constexpr (sizeof(T) == sizeof(U))
676+
{
668677
return true;
678+
}
679+
else if constexpr (sizeof(T) < sizeof(U))
680+
{
681+
if (std::isnan(value) || std::isinf(value))
682+
return true;
669683

670-
if constexpr (sizeof(T) < sizeof(U))
671684
return static_cast<U>(value) >= -(std::numeric_limits<U>::max)()
672685
&& static_cast<U>(value) <= (std::numeric_limits<U>::max)();
686+
}
687+
else
688+
{
689+
if (std::isnan(value) || std::isinf(value))
690+
return true;
673691

674-
return value >= static_cast<T>(-(std::numeric_limits<U>::max)())
675-
&& value <= static_cast<T>((std::numeric_limits<U>::max)());
692+
return value >= static_cast<T>(-(std::numeric_limits<U>::max)())
693+
&& value <= static_cast<T>((std::numeric_limits<U>::max)());
694+
}
676695
}
677696

678697
template <class U = lua_Number>

‎Tests/Source/StackTests.cpp‎

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,6 +1404,108 @@ TEST_F(StackTests, FloatTypeNotFittingIsInstance)
14041404
EXPECT_TRUE(luabridge::isInstance<long double>(L, 1));
14051405
}
14061406

1407+
TEST_F(StackTests, FloatNaNAndInfPush)
1408+
{
1409+
{
1410+
const luabridge::StackRestore sr(L);
1411+
EXPECT_TRUE(luabridge::push(L, std::numeric_limits<float>::quiet_NaN()));
1412+
EXPECT_TRUE(luabridge::isInstance<float>(L, -1));
1413+
EXPECT_TRUE(luabridge::isInstance<double>(L, -1));
1414+
EXPECT_TRUE(luabridge::isInstance<long double>(L, -1));
1415+
auto result = luabridge::get<float>(L, -1);
1416+
ASSERT_TRUE(result);
1417+
EXPECT_TRUE(std::isnan(*result));
1418+
}
1419+
1420+
{
1421+
const luabridge::StackRestore sr(L);
1422+
EXPECT_TRUE(luabridge::push(L, std::numeric_limits<float>::infinity()));
1423+
EXPECT_TRUE(luabridge::isInstance<float>(L, -1));
1424+
EXPECT_TRUE(luabridge::isInstance<double>(L, -1));
1425+
EXPECT_TRUE(luabridge::isInstance<long double>(L, -1));
1426+
auto result = luabridge::get<float>(L, -1);
1427+
ASSERT_TRUE(result);
1428+
EXPECT_TRUE(std::isinf(*result));
1429+
}
1430+
1431+
{
1432+
const luabridge::StackRestore sr(L);
1433+
EXPECT_TRUE(luabridge::push(L, -std::numeric_limits<float>::infinity()));
1434+
auto result = luabridge::get<float>(L, -1);
1435+
ASSERT_TRUE(result);
1436+
EXPECT_TRUE(std::isinf(*result));
1437+
EXPECT_LT(*result, 0.0f);
1438+
}
1439+
}
1440+
1441+
TEST_F(StackTests, DoubleNaNAndInfPush)
1442+
{
1443+
{
1444+
const luabridge::StackRestore sr(L);
1445+
EXPECT_TRUE(luabridge::push(L, std::numeric_limits<double>::quiet_NaN()));
1446+
EXPECT_TRUE(luabridge::isInstance<float>(L, -1));
1447+
EXPECT_TRUE(luabridge::isInstance<double>(L, -1));
1448+
EXPECT_TRUE(luabridge::isInstance<long double>(L, -1));
1449+
auto result = luabridge::get<double>(L, -1);
1450+
ASSERT_TRUE(result);
1451+
EXPECT_TRUE(std::isnan(*result));
1452+
}
1453+
1454+
{
1455+
const luabridge::StackRestore sr(L);
1456+
EXPECT_TRUE(luabridge::push(L, std::numeric_limits<double>::infinity()));
1457+
EXPECT_TRUE(luabridge::isInstance<float>(L, -1));
1458+
EXPECT_TRUE(luabridge::isInstance<double>(L, -1));
1459+
EXPECT_TRUE(luabridge::isInstance<long double>(L, -1));
1460+
auto result = luabridge::get<double>(L, -1);
1461+
ASSERT_TRUE(result);
1462+
EXPECT_TRUE(std::isinf(*result));
1463+
}
1464+
1465+
{
1466+
const luabridge::StackRestore sr(L);
1467+
EXPECT_TRUE(luabridge::push(L, -std::numeric_limits<double>::infinity()));
1468+
auto result = luabridge::get<double>(L, -1);
1469+
ASSERT_TRUE(result);
1470+
EXPECT_TRUE(std::isinf(*result));
1471+
EXPECT_LT(*result, 0.0);
1472+
}
1473+
}
1474+
1475+
TEST_F(StackTests, LongDoubleNaNAndInfPush)
1476+
{
1477+
{
1478+
const luabridge::StackRestore sr(L);
1479+
EXPECT_TRUE(luabridge::push(L, std::numeric_limits<long double>::quiet_NaN()));
1480+
EXPECT_TRUE(luabridge::isInstance<float>(L, -1));
1481+
EXPECT_TRUE(luabridge::isInstance<double>(L, -1));
1482+
EXPECT_TRUE(luabridge::isInstance<long double>(L, -1));
1483+
auto result = luabridge::get<long double>(L, -1);
1484+
ASSERT_TRUE(result);
1485+
EXPECT_TRUE(std::isnan(*result));
1486+
}
1487+
1488+
{
1489+
const luabridge::StackRestore sr(L);
1490+
EXPECT_TRUE(luabridge::push(L, std::numeric_limits<long double>::infinity()));
1491+
EXPECT_TRUE(luabridge::isInstance<float>(L, -1));
1492+
EXPECT_TRUE(luabridge::isInstance<double>(L, -1));
1493+
EXPECT_TRUE(luabridge::isInstance<long double>(L, -1));
1494+
auto result = luabridge::get<long double>(L, -1);
1495+
ASSERT_TRUE(result);
1496+
EXPECT_TRUE(std::isinf(*result));
1497+
}
1498+
1499+
{
1500+
const luabridge::StackRestore sr(L);
1501+
EXPECT_TRUE(luabridge::push(L, -std::numeric_limits<long double>::infinity()));
1502+
auto result = luabridge::get<long double>(L, -1);
1503+
ASSERT_TRUE(result);
1504+
EXPECT_TRUE(std::isinf(*result));
1505+
EXPECT_LT(*result, 0.0l);
1506+
}
1507+
}
1508+
14071509
TEST_F(StackTests, CharArrayType)
14081510
{
14091511
char value[] = "xyz";

0 commit comments

Comments
 (0)