mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
large integer
This commit is contained in:
parent
5e109c2c37
commit
372db6f6ab
23
.travis.yml
23
.travis.yml
|
@ -74,6 +74,29 @@ matrix:
|
|||
- ninja-build
|
||||
- libluajit-5.1-dev
|
||||
|
||||
# gcc-5:i386
|
||||
- os: linux
|
||||
env: COMPILER=g++-5 LUA_VERSION=luajit51:i386
|
||||
compiler: gcc
|
||||
install:
|
||||
- sudo dpkg --add-architecture i386
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-5
|
||||
- g++-5
|
||||
- ninja-build
|
||||
- libluajit-5.1-dev
|
||||
- libluajit-5.1-dev:i386
|
||||
- libc6:i386
|
||||
- libncurses5:i386
|
||||
- libstdc++6:i386
|
||||
- gcc-5-multilib
|
||||
- g++-5-multilib
|
||||
- linux-libc-dev:i386
|
||||
|
||||
# clang
|
||||
- os: linux
|
||||
env:
|
||||
|
|
|
@ -91,6 +91,12 @@ if 'linux' in sys.platform:
|
|||
# Using normal lua
|
||||
lua_lib = lua_version[:-1] + '.' + lua_version[-1]
|
||||
lua_incl = lua_lib
|
||||
elif re.match(r'luajit5[1-3]:i386', lua_version):
|
||||
# luajit:i386
|
||||
lua_incl = 'luajit-2.0'
|
||||
lua_lib = lua_version[:-7] + '-' + lua_version[-7] + '.' + lua_version[-6]
|
||||
cxxflags.append('-m32')
|
||||
include.extend(['/usr/include/luajit-2.0/', '/usr/local/include/luajit-2.0/'])
|
||||
elif re.match(r'luajit5[1-3]', lua_version):
|
||||
# luajit
|
||||
lua_incl = 'luajit-2.0' # I don't get this..
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// This file was generated with a script.
|
||||
// Generated 2017-08-11 14:35:51.568053 UTC
|
||||
// This header was generated with sol v2.18.0 (revision 4f7f1af)
|
||||
// Generated 2017-08-11 12:59:23.551177 UTC
|
||||
// This header was generated with sol v2.18.0 (revision 5e109c2)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||
|
@ -5798,6 +5798,7 @@ namespace sol {
|
|||
|
||||
// end of sol/inheritance.hpp
|
||||
|
||||
#include <cmath>
|
||||
#ifdef SOL_CXX17_FEATURES
|
||||
#endif // C++17
|
||||
|
||||
|
@ -5854,7 +5855,14 @@ namespace sol {
|
|||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
bool success = lua_isinteger(L, index) == 1;
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
if (lua_isinteger(L, index) != 0) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
int isnum = 0;
|
||||
const lua_Number v = lua_tonumberx(L, index, &isnum);
|
||||
const bool success = isnum != 0 && static_cast<lua_Number>(std::llround(v)) == v;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
|
@ -6347,18 +6355,15 @@ namespace sol {
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_signed<T>>::value>> {
|
||||
struct getter<T, std::enable_if_t<std::is_integral<T>::value>> {
|
||||
static T get(lua_State* L, int index, record& tracking) {
|
||||
tracking.use(1);
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_unsigned<T>>::value>> {
|
||||
static T get(lua_State* L, int index, record& tracking) {
|
||||
tracking.use(1);
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
if (lua_isinteger(L, index) != 0) {
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
}
|
||||
#endif
|
||||
return static_cast<T>(std::llround(lua_tonumber(L, index)));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -7107,16 +7112,25 @@ namespace sol {
|
|||
struct check_getter<T, std::enable_if_t<std::is_integral<T>::value && lua_type_of<T>::value == type::number>> {
|
||||
template <typename Handler>
|
||||
static optional<T> get(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
int isnum = 0;
|
||||
lua_Integer value = lua_tointegerx(L, index, &isnum);
|
||||
if (isnum == 0) {
|
||||
type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t);
|
||||
return nullopt;
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
if (lua_isinteger(L, index) != 0) {
|
||||
tracking.use(1);
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
}
|
||||
tracking.use(1);
|
||||
return static_cast<T>(value);
|
||||
#endif
|
||||
int isnum = 0;
|
||||
const lua_Number value = lua_tonumberx(L, index, &isnum);
|
||||
if (isnum != 0) {
|
||||
const auto integer_value = std::llround(value);
|
||||
if (static_cast<lua_Number>(integer_value) == value) {
|
||||
tracking.use(1);
|
||||
return static_cast<T>(integer_value);
|
||||
}
|
||||
}
|
||||
const type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t);
|
||||
return nullopt;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -7317,6 +7331,8 @@ namespace sol {
|
|||
|
||||
// end of sol/raii.hpp
|
||||
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#ifdef SOL_CODECVT_SUPPORT
|
||||
#endif
|
||||
#ifdef SOL_CXX17_FEATURES
|
||||
|
@ -7477,17 +7493,34 @@ namespace sol {
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_signed<T>>::value>> {
|
||||
struct pusher<T, std::enable_if_t<std::is_integral<T>::value>> {
|
||||
static int push(lua_State* L, const T& value) {
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_unsigned<T>>::value>> {
|
||||
static int push(lua_State* L, const T& value) {
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
static auto integer_value_fits = [](T const& value) {
|
||||
if (sizeof(T) < sizeof(lua_Integer) || std::is_signed<T>::value && sizeof(T) == sizeof(lua_Integer)) {
|
||||
return true;
|
||||
}
|
||||
auto u_min = static_cast<std::intmax_t>(std::numeric_limits<lua_Integer>::min());
|
||||
auto u_max = static_cast<std::uintmax_t>(std::numeric_limits<lua_Integer>::max());
|
||||
auto t_min = static_cast<std::intmax_t>(std::numeric_limits<T>::min());
|
||||
auto t_max = static_cast<std::uintmax_t>(std::numeric_limits<T>::max());
|
||||
return (u_min <= t_min || value >= static_cast<T>(u_min)) && (u_max >= t_max || value <= static_cast<T>(u_max));
|
||||
};
|
||||
if (integer_value_fits(value)) {
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#if defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
if (static_cast<T>(std::llround(static_cast<lua_Number>(value))) != value) {
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
throw sol::error("The integer will be misrepresented in lua.");
|
||||
#else
|
||||
assert(false && "The integer will be misrepresented in lua.");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
lua_pushnumber(L, static_cast<lua_Number>(value));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
@ -11854,8 +11887,6 @@ namespace sol {
|
|||
|
||||
// end of sol/stack_proxy.hpp
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace sol {
|
||||
template <bool is_const>
|
||||
struct va_iterator : std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const stack_proxy, stack_proxy>, std::ptrdiff_t, std::conditional_t<is_const, const stack_proxy*, stack_proxy*>, std::conditional_t<is_const, const stack_proxy, stack_proxy>> {
|
||||
|
@ -13716,7 +13747,6 @@ namespace sol {
|
|||
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
|
||||
namespace sol {
|
||||
namespace usertype_detail {
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <memory>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <cmath>
|
||||
#ifdef SOL_CXX17_FEATURES
|
||||
#include <variant>
|
||||
#endif // C++17
|
||||
|
@ -85,7 +86,14 @@ namespace sol {
|
|||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
bool success = lua_isinteger(L, index) == 1;
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
if (lua_isinteger(L, index) != 0) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
int isnum = 0;
|
||||
const lua_Number v = lua_tonumberx(L, index, &isnum);
|
||||
const bool success = isnum != 0 && static_cast<lua_Number>(std::llround(v)) == v;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "stack_check.hpp"
|
||||
#include "optional.hpp"
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
|
||||
namespace sol {
|
||||
namespace stack {
|
||||
|
@ -56,16 +57,25 @@ namespace sol {
|
|||
struct check_getter<T, std::enable_if_t<std::is_integral<T>::value && lua_type_of<T>::value == type::number>> {
|
||||
template <typename Handler>
|
||||
static optional<T> get(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
int isnum = 0;
|
||||
lua_Integer value = lua_tointegerx(L, index, &isnum);
|
||||
if (isnum == 0) {
|
||||
type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t);
|
||||
return nullopt;
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
if (lua_isinteger(L, index) != 0) {
|
||||
tracking.use(1);
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
}
|
||||
tracking.use(1);
|
||||
return static_cast<T>(value);
|
||||
#endif
|
||||
int isnum = 0;
|
||||
const lua_Number value = lua_tonumberx(L, index, &isnum);
|
||||
if (isnum != 0) {
|
||||
const auto integer_value = std::llround(value);
|
||||
if (static_cast<lua_Number>(integer_value) == value) {
|
||||
tracking.use(1);
|
||||
return static_cast<T>(integer_value);
|
||||
}
|
||||
}
|
||||
const type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t);
|
||||
return nullopt;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <functional>
|
||||
#include <utility>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#ifdef SOL_CODECVT_SUPPORT
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
|
@ -59,18 +60,15 @@ namespace sol {
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_signed<T>>::value>> {
|
||||
struct getter<T, std::enable_if_t<std::is_integral<T>::value>> {
|
||||
static T get(lua_State* L, int index, record& tracking) {
|
||||
tracking.use(1);
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_unsigned<T>>::value>> {
|
||||
static T get(lua_State* L, int index, record& tracking) {
|
||||
tracking.use(1);
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
if (lua_isinteger(L, index) != 0) {
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
}
|
||||
#endif
|
||||
return static_cast<T>(std::llround(lua_tonumber(L, index)));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "usertype_traits.hpp"
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#ifdef SOL_CODECVT_SUPPORT
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
|
@ -192,17 +194,34 @@ namespace sol {
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_signed<T>>::value>> {
|
||||
struct pusher<T, std::enable_if_t<std::is_integral<T>::value>> {
|
||||
static int push(lua_State* L, const T& value) {
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_unsigned<T>>::value>> {
|
||||
static int push(lua_State* L, const T& value) {
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
static auto integer_value_fits = [](T const& value) {
|
||||
if (sizeof(T) < sizeof(lua_Integer) || std::is_signed<T>::value && sizeof(T) == sizeof(lua_Integer)) {
|
||||
return true;
|
||||
}
|
||||
auto u_min = static_cast<std::intmax_t>(std::numeric_limits<lua_Integer>::min());
|
||||
auto u_max = static_cast<std::uintmax_t>(std::numeric_limits<lua_Integer>::max());
|
||||
auto t_min = static_cast<std::intmax_t>(std::numeric_limits<T>::min());
|
||||
auto t_max = static_cast<std::uintmax_t>(std::numeric_limits<T>::max());
|
||||
return (u_min <= t_min || value >= static_cast<T>(u_min)) && (u_max >= t_max || value <= static_cast<T>(u_max));
|
||||
};
|
||||
if (integer_value_fits(value)) {
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#if defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
if (static_cast<T>(std::llround(static_cast<lua_Number>(value))) != value) {
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
throw sol::error("The integer will be misrepresented in lua.");
|
||||
#else
|
||||
assert(false && "The integer will be misrepresented in lua.");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
lua_pushnumber(L, static_cast<lua_Number>(value));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
|
117
test_large_integer.cpp
Normal file
117
test_large_integer.cpp
Normal file
|
@ -0,0 +1,117 @@
|
|||
#define SOL_CHECK_ARGUMENTS
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
TEST_CASE("large_integer/bool", "pass bool integral value to and from lua") {
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
lua.set_function("f", [&](bool num) {
|
||||
REQUIRE(num == true);
|
||||
return num;
|
||||
});
|
||||
lua.script("x = f(true)");
|
||||
lua.script("assert(x == true)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<bool>());
|
||||
REQUIRE(x.as<bool>() == true);
|
||||
REQUIRE_FALSE(x.is<std::int32_t>());
|
||||
REQUIRE_THROWS([&lua]() {
|
||||
lua.script("f(1)");
|
||||
}());
|
||||
}
|
||||
|
||||
TEST_CASE("large_integers/unsigned32", "pass large unsigned 32bit values to and from lua") {
|
||||
using T = std::uint32_t;
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
lua.set_function("f", [&](T num) -> T {
|
||||
REQUIRE(num == 0xFFFFFFFF);
|
||||
return num;
|
||||
});
|
||||
lua.script("x = f(0xFFFFFFFF)");
|
||||
lua.script("assert(x == 0xFFFFFFFF)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<T>());
|
||||
REQUIRE(x.as<T>() == 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
TEST_CASE("large_integer/unsigned53", "pass large unsigned 53bit value to and from lua") {
|
||||
using T = std::uint64_t;
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
lua.set_function("f", [&](T num) -> T {
|
||||
REQUIRE(num == 0x1FFFFFFFFFFFFFull);
|
||||
return num;
|
||||
});
|
||||
lua.script("x = f(0x1FFFFFFFFFFFFF)");
|
||||
lua.script("assert(x == 0x1FFFFFFFFFFFFF)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<T>());
|
||||
REQUIRE(x.as<T>() == 0x1FFFFFFFFFFFFFull);
|
||||
}
|
||||
|
||||
TEST_CASE("large_integer/unsigned64", "pass too large unsigned 64bit value to lua") {
|
||||
using T = std::int64_t;
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
lua.set_function("f", [&](T num) -> T {
|
||||
return num;
|
||||
});
|
||||
REQUIRE_THROWS([&lua]() {
|
||||
lua["f"](0xFFFFFFFFFFFFFFFFull);
|
||||
}());
|
||||
}
|
||||
|
||||
TEST_CASE("large_integer/double", "pass negative and large positive values as signed and unsigned from and to lua") {
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
lua.set_function("s32", [&](std::int32_t num) {
|
||||
return num;
|
||||
});
|
||||
lua.set_function("s64", [&](std::int64_t num) {
|
||||
return num;
|
||||
});
|
||||
lua.set_function("u32", [&](std::uint32_t num) {
|
||||
return num;
|
||||
});
|
||||
lua.set_function("u64", [&](std::uint64_t num) {
|
||||
return num;
|
||||
});
|
||||
//signed 32bit
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("x = s32(-1)");
|
||||
lua.script("assert(x == -1)");
|
||||
lua.script("x = s32(0xFFFFFFFF)");
|
||||
lua.script("assert(x == -1)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<std::int32_t>());
|
||||
REQUIRE(x.as<std::int32_t>() == -1);
|
||||
REQUIRE(x.is<std::uint32_t>());
|
||||
REQUIRE(x.as<std::uint32_t>() == 0xFFFFFFFF);
|
||||
}());
|
||||
//unsigned 32bit
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("x = u32(0xFFFFFFFF)");
|
||||
lua.script("assert(x == 0xFFFFFFFF)");
|
||||
lua.script("x = u32(-1)");
|
||||
lua.script("assert(x == 0xFFFFFFFF)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<std::int32_t>());
|
||||
REQUIRE(x.as<std::int32_t>() == -1);
|
||||
REQUIRE(x.is<std::uint32_t>());
|
||||
REQUIRE(x.as<std::uint32_t>() == 0xFFFFFFFF);
|
||||
}());
|
||||
//signed 64bit
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("x = s64(-1)");
|
||||
lua.script("assert(x == -1)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<std::int64_t>());
|
||||
REQUIRE(x.as<std::int64_t>() == -1);
|
||||
REQUIRE(x.is<std::uint64_t>());
|
||||
REQUIRE(x.as<std::uint64_t>() == 0xFFFFFFFFFFFFFFFFull);
|
||||
}());
|
||||
}
|
Loading…
Reference in New Issue
Block a user