mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
upgrade checkers and handlers to take a semi-optional "reason" type (const char* c-string desired)
add constructor_handler in same vein of handlers add argument_handler in same vein of handlers rewrite env_t checkers
This commit is contained in:
parent
3549bfa8ae
commit
54bcda140c
|
@ -55,7 +55,7 @@ members
|
|||
:caption: function: call_lua
|
||||
:name: stack-call-lua
|
||||
|
||||
template<bool check_args = stack_detail::default_check_arguments, typename Fx, typename... FxArgs>
|
||||
template<bool check_args = stack_detail::default_check_arguments, bool clean_stack = true, typename Fx, typename... FxArgs>
|
||||
inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs);
|
||||
|
||||
This function is helpful for when you bind to a raw C function but need sol's abstractions to save you the agony of setting up arguments and know how `calling C functions works`_. The ``start`` parameter tells the function where to start pulling arguments from. The parameter ``fx`` is what's supposed to be called. Extra arguments are passed to the function directly. There are intermediate versions of this (``sol::stack::call_into_lua`` and similar) for more advanced users, but they are not documented as they are subject to change to improve performance or adjust the API accordingly in later iterations of sol2. Use the more advanced versions at your own peril.
|
||||
|
@ -97,7 +97,7 @@ Checks if the object at ``index`` is of type ``T``. If it is not, it will call t
|
|||
template <typename T, typename Handler>
|
||||
auto check_get( lua_State* L, int index, Handler&& handler, record& tracking )
|
||||
|
||||
Retrieves the value of the object at ``index`` in the stack, but does so safely. It returns an ``optional<U>``, where ``U`` in this case is the return type deduced from ``stack::get<T>``. This allows a person to properly check if the type they're getting is what they actually want, and gracefully handle errors when working with the stack if they so choose to. You can define ``SOL_CHECK_ARGUMENTS`` to turn on additional :doc:`safety<../safety>`, in which ``stack::get`` will default to calling this version of the function with a handler of ``type_panic`` to strongly alert for errors and help you track bugs if you suspect something might be going wrong in your system.
|
||||
Retrieves the value of the object at ``index`` in the stack, but does so safely. It returns an ``optional<U>``, where ``U`` in this case is the return type deduced from ``stack::get<T>``. This allows a person to properly check if the type they're getting is what they actually want, and gracefully handle errors when working with the stack if they so choose to. You can define ``SOL_CHECK_ARGUMENTS`` to turn on additional :doc:`safety<../safety>`, in which ``stack::get`` will default to calling this version of the function with some variant on a handler of ``sol::type_panic_string`` to strongly alert for errors and help you track bugs if you suspect something might be going wrong in your system.
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: function: push
|
||||
|
@ -237,8 +237,9 @@ This is an SFINAE-friendly struct that is meant to expose static function ``push
|
|||
// if the object in the Lua stack at index is a T, return true
|
||||
if ( ... ) return true;
|
||||
// otherwise, call the handler function,
|
||||
// with the required 4 arguments, then return false
|
||||
handler(L, index, expected, indextype);
|
||||
// with the required 5 arguments, then return false
|
||||
//
|
||||
handler(L, index, expected, indextype, "optional message");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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-30 20:09:44.279724 UTC
|
||||
// This header was generated with sol v2.18.1 (revision dea0ec0)
|
||||
// Generated 2017-09-01 00:38:40.996447 UTC
|
||||
// This header was generated with sol v2.18.1 (revision 3549bfa)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||
|
@ -4568,37 +4568,6 @@ namespace sol {
|
|||
return static_cast<type>(lua_type(L, index));
|
||||
}
|
||||
|
||||
inline int type_panic(lua_State* L, int index, type expected, type actual) noexcept(false) {
|
||||
return luaL_error(L, "stack index %d, expected %s, received %s", index,
|
||||
expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected)),
|
||||
actual == type::poly ? "anything" : lua_typename(L, static_cast<int>(actual))
|
||||
);
|
||||
}
|
||||
|
||||
// Specify this function as the handler for lua::check if you know there's nothing wrong
|
||||
inline int no_panic(lua_State*, int, type, type) noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void type_error(lua_State* L, int expected, int actual) noexcept(false) {
|
||||
luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual));
|
||||
}
|
||||
|
||||
inline void type_error(lua_State* L, type expected, type actual) noexcept(false) {
|
||||
type_error(L, static_cast<int>(expected), static_cast<int>(actual));
|
||||
}
|
||||
|
||||
inline void type_assert(lua_State* L, int index, type expected, type actual) noexcept(false) {
|
||||
if (expected != type::poly && expected != actual) {
|
||||
type_panic(L, index, expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
inline void type_assert(lua_State* L, int index, type expected) {
|
||||
type actual = type_of(L, index);
|
||||
type_assert(L, index, expected, actual);
|
||||
}
|
||||
|
||||
inline std::string type_name(lua_State* L, type t) {
|
||||
return lua_typename(L, static_cast<int>(t));
|
||||
}
|
||||
|
@ -5045,6 +5014,82 @@ namespace sol {
|
|||
|
||||
// end of sol/types.hpp
|
||||
|
||||
// beginning of sol/error_handler.hpp
|
||||
|
||||
namespace sol {
|
||||
|
||||
inline int type_panic_string(lua_State* L, int index, type expected, type actual, const std::string& message = "") noexcept(false) {
|
||||
const char* err = message.empty() ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s with message %s";
|
||||
return luaL_error(L, err, index,
|
||||
expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected)),
|
||||
actual == type::poly ? "anything" : lua_typename(L, static_cast<int>(actual)),
|
||||
message.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
inline int type_panic_c_str(lua_State* L, int index, type expected, type actual, const char* message = nullptr) noexcept(false) {
|
||||
const char* err = message == nullptr || (std::char_traits<char>::length(message) == 0) ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s with message %s";
|
||||
return luaL_error(L, err, index,
|
||||
expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected)),
|
||||
actual == type::poly ? "anything" : lua_typename(L, static_cast<int>(actual)),
|
||||
message
|
||||
);
|
||||
}
|
||||
|
||||
struct type_panic_t {
|
||||
int operator()(lua_State* L, int index, type expected, type actual) const noexcept(false) {
|
||||
return type_panic_c_str(L, index, expected, actual, nullptr);
|
||||
}
|
||||
int operator()(lua_State* L, int index, type expected, type actual, const char* message) const noexcept(false) {
|
||||
return type_panic_c_str(L, index, expected, actual, message);
|
||||
}
|
||||
int operator()(lua_State* L, int index, type expected, type actual, const std::string& message) const noexcept(false) {
|
||||
return type_panic_string(L, index, expected, actual, message);
|
||||
}
|
||||
};
|
||||
|
||||
const type_panic_t type_panic = {};
|
||||
|
||||
struct constructor_handler {
|
||||
int operator()(lua_State* L, int index, type expected, type actual, const std::string& message) noexcept(false) {
|
||||
return type_panic_string(L, index, expected, actual, message + " (type check failed in constructor)");
|
||||
}
|
||||
};
|
||||
|
||||
struct argument_handler {
|
||||
int operator()(lua_State* L, int index, type expected, type actual, const std::string& message) noexcept(false) {
|
||||
return type_panic_string(L, index, expected, actual, message + " (bad argument to variable or function call)");
|
||||
}
|
||||
};
|
||||
|
||||
// Specify this function as the handler for lua::check if you know there's nothing wrong
|
||||
inline int no_panic(lua_State*, int, type, type, const char* = nullptr) noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void type_error(lua_State* L, int expected, int actual) noexcept(false) {
|
||||
luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual));
|
||||
}
|
||||
|
||||
inline void type_error(lua_State* L, type expected, type actual) noexcept(false) {
|
||||
type_error(L, static_cast<int>(expected), static_cast<int>(actual));
|
||||
}
|
||||
|
||||
inline void type_assert(lua_State* L, int index, type expected, type actual) noexcept(false) {
|
||||
if (expected != type::poly && expected != actual) {
|
||||
type_panic_c_str(L, index, expected, actual, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
inline void type_assert(lua_State* L, int index, type expected) {
|
||||
type actual = type_of(L, index);
|
||||
type_assert(L, index, expected, actual);
|
||||
}
|
||||
|
||||
} // sol
|
||||
|
||||
// end of sol/error_handler.hpp
|
||||
|
||||
// beginning of sol/reference.hpp
|
||||
|
||||
// beginning of sol/stack_reference.hpp
|
||||
|
@ -5893,7 +5938,7 @@ namespace sol {
|
|||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
template <typename T>
|
||||
inline auto tagged_get(types<T>, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get<T>(L, index, tracking)) {
|
||||
auto op = check_get<T>(L, index, type_panic, tracking);
|
||||
auto op = check_get<T>(L, index, type_panic_c_str, tracking);
|
||||
return *std::move(op);
|
||||
}
|
||||
#else
|
||||
|
@ -6208,7 +6253,7 @@ namespace sol {
|
|||
bool success = check_func(L, index) == 1;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, expected, type_of(L, index));
|
||||
handler(L, index, expected, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -6223,8 +6268,8 @@ namespace sol {
|
|||
const type indextype = type_of(L, index);
|
||||
bool success = expected == indextype;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, expected, indextype);
|
||||
// expected type, actual type, message
|
||||
handler(L, index, expected, indextype, "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -6249,7 +6294,7 @@ namespace sol {
|
|||
#endif // If numbers are enabled, use the imprecise check
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
handler(L, index, type::number, type_of(L, index), "not a numeric type");
|
||||
}
|
||||
return success;
|
||||
#else
|
||||
|
@ -6258,7 +6303,7 @@ namespace sol {
|
|||
type t = type_of(L, index);
|
||||
if (t != type::number) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not a numeric type");
|
||||
return false;
|
||||
}
|
||||
#endif // Do not allow strings to be numbers
|
||||
|
@ -6268,9 +6313,9 @@ namespace sol {
|
|||
if (!success) {
|
||||
// expected type, actual type
|
||||
#ifndef SOL_STRINGS_ARE_NUMBERS
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not a numeric type");
|
||||
#else
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
handler(L, index, type::number, type_of(L, index), "not a numeric type or numeric string");
|
||||
#endif
|
||||
}
|
||||
return success;
|
||||
|
@ -6283,19 +6328,19 @@ namespace sol {
|
|||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
#ifdef SOL_STRINGS_ARE_NUMBERS
|
||||
#ifndef SOL_STRINGS_ARE_NUMBERS
|
||||
type t = type_of(L, index);
|
||||
bool success = t == type::number;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not a numeric type");
|
||||
}
|
||||
return success;
|
||||
#else
|
||||
bool success = lua_isnumber(L, index) == 1;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
handler(L, index, type::number, type_of(L, index), "not a numeric type or numeric string");
|
||||
}
|
||||
return success;
|
||||
#endif
|
||||
|
@ -6315,7 +6360,7 @@ namespace sol {
|
|||
success = lua_isnone(L, index);
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, expected, type_of(L, index));
|
||||
handler(L, index, expected, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -6368,7 +6413,7 @@ namespace sol {
|
|||
bool success = !lua_isnone(L, index);
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::none, type_of(L, index));
|
||||
handler(L, index, type::none, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -6383,7 +6428,7 @@ namespace sol {
|
|||
bool success = t == type::userdata || t == type::lightuserdata;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::lightuserdata, t);
|
||||
handler(L, index, type::lightuserdata, t, "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -6398,7 +6443,7 @@ namespace sol {
|
|||
bool success = t == type::userdata;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::userdata, t);
|
||||
handler(L, index, type::userdata, t, "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -6436,25 +6481,25 @@ namespace sol {
|
|||
return true;
|
||||
}
|
||||
if (t != type::userdata && t != type::table) {
|
||||
handler(L, index, type::function, t);
|
||||
handler(L, index, type::function, t, "must be a function or table or a userdata");
|
||||
return false;
|
||||
}
|
||||
// Do advanced check for call-style userdata?
|
||||
static const auto& callkey = to_string(meta_function::call);
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
// No metatable, no __call key possible
|
||||
handler(L, index, type::function, t);
|
||||
handler(L, index, type::function, t, "value is not a function and does not have overriden metatable");
|
||||
return false;
|
||||
}
|
||||
if (lua_isnoneornil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::function, t);
|
||||
handler(L, index, type::function, t, "value is not a function and does not have valid metatable");
|
||||
return false;
|
||||
}
|
||||
lua_getfield(L, -1, &callkey[0]);
|
||||
if (lua_isnoneornil(L, -1)) {
|
||||
lua_pop(L, 2);
|
||||
handler(L, index, type::function, t);
|
||||
handler(L, index, type::function, t, "value's metatable does not have __call overridden in metatable, cannot call this type");
|
||||
return false;
|
||||
}
|
||||
// has call, is definitely a function
|
||||
|
@ -6473,7 +6518,7 @@ namespace sol {
|
|||
return true;
|
||||
}
|
||||
if (t != type::userdata) {
|
||||
handler(L, index, type::table, t);
|
||||
handler(L, index, type::table, t, "value is not a table or a userdata that can behave like one");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -6495,7 +6540,7 @@ namespace sol {
|
|||
}
|
||||
if (t != type::userdata) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, expected, t);
|
||||
handler(L, index, expected, t, "value does not have a valid metatable");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -6507,19 +6552,11 @@ namespace sol {
|
|||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
type t = type_of(L, index);
|
||||
if (t == type::table || t == type::none || t == type::nil || t == type::userdata) {
|
||||
return true;
|
||||
}
|
||||
type t = type_of(L, -1);
|
||||
if (t == type::table || t == type::none || t == type::nil) {
|
||||
lua_pop(L, 1);
|
||||
return true;
|
||||
}
|
||||
if (t != type::userdata) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::table, t);
|
||||
return false;
|
||||
}
|
||||
handler(L, index, type::table, t, "value cannot not have a valid environment");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -6539,7 +6576,7 @@ namespace sol {
|
|||
}
|
||||
if (t != type::userdata) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::table, t);
|
||||
handler(L, index, type::table, t, "value does not have a valid metatable");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -6552,7 +6589,7 @@ namespace sol {
|
|||
static bool check(types<U>, lua_State* L, type indextype, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
if (indextype != type::userdata) {
|
||||
handler(L, index, type::userdata, indextype);
|
||||
handler(L, index, type::userdata, indextype, "value is not a valid userdata");
|
||||
return false;
|
||||
}
|
||||
if (meta::any<std::is_same<T, lightuserdata_value>, std::is_same<T, userdata_value>, std::is_same<T, userdata>, std::is_same<T, lightuserdata>>::value)
|
||||
|
@ -6582,7 +6619,7 @@ namespace sol {
|
|||
}
|
||||
if (!success) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::userdata, indextype);
|
||||
handler(L, index, type::userdata, indextype, "value is not a valid sol userdata of any kind");
|
||||
return false;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
@ -6621,7 +6658,7 @@ namespace sol {
|
|||
const type indextype = type_of(L, index);
|
||||
tracking.use(1);
|
||||
if (indextype != type::userdata) {
|
||||
handler(L, index, type::userdata, indextype);
|
||||
handler(L, index, type::userdata, indextype, "value is not a userdata");
|
||||
return false;
|
||||
}
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
|
@ -6634,12 +6671,12 @@ namespace sol {
|
|||
detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(static_cast<void*>(pointerpointer + 1));
|
||||
bool success = &detail::usertype_unique_alloc_destroy<T, X> == pdx;
|
||||
if (!success) {
|
||||
handler(L, index, type::userdata, indextype);
|
||||
handler(L, index, type::userdata, indextype, "value is a userdata but is not the correct unique usertype");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::userdata, indextype);
|
||||
handler(L, index, type::userdata, indextype, "unrecognized userdata (not pushed by sol?)");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
@ -6698,7 +6735,7 @@ namespace sol {
|
|||
return true;
|
||||
}
|
||||
tracking.use(1);
|
||||
handler(L, index, type::poly, type_of(L, index));
|
||||
handler(L, index, type::poly, type_of(L, index), "value does not fit any type present in the variant");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -7538,7 +7575,7 @@ namespace sol {
|
|||
int isnum = 0;
|
||||
const lua_Number value = lua_tonumberx(L, index, &isnum);
|
||||
if (isnum != 0) {
|
||||
#if 1 // defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
#if defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
const auto integer_value = llround(value);
|
||||
if (static_cast<lua_Number>(integer_value) == value) {
|
||||
tracking.use(1);
|
||||
|
@ -7551,7 +7588,7 @@ namespace sol {
|
|||
}
|
||||
const type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not an integer");
|
||||
return nullopt;
|
||||
}
|
||||
};
|
||||
|
@ -7565,7 +7602,7 @@ namespace sol {
|
|||
if (isnum == 0) {
|
||||
type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not a valid enumeration value");
|
||||
return nullopt;
|
||||
}
|
||||
tracking.use(1);
|
||||
|
@ -7582,7 +7619,7 @@ namespace sol {
|
|||
if (isnum == 0) {
|
||||
type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not a valid floating point number");
|
||||
return nullopt;
|
||||
}
|
||||
tracking.use(1);
|
||||
|
@ -7614,7 +7651,7 @@ namespace sol {
|
|||
typedef std::variant_alternative_t<0, V> T;
|
||||
// This should never be reached...
|
||||
// please check your code and understand what you did to bring yourself here
|
||||
handler(L, index, type::poly, type_of(L, index));
|
||||
handler(L, index, type::poly, type_of(L, index), "this variant code should never be reached: if it has, you have done something so terribly wrong");
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
|
@ -7837,10 +7874,13 @@ namespace sol {
|
|||
#endif
|
||||
#if defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
if (static_cast<T>(llround(static_cast<lua_Number>(value))) != value) {
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
throw sol::error("The integer will be misrepresented in lua.");
|
||||
#ifdef SOL_NO_EXCEPTIONS
|
||||
// Is this really worth it?
|
||||
assert(false && "integer value will be misrepresented in lua");
|
||||
lua_pushnumber(L, static_cast<lua_Number>(value));
|
||||
return 1;
|
||||
#else
|
||||
assert(false && "The integer will be misrepresented in lua.");
|
||||
throw error(detail::direct_error, "integer value will be misrepresented in lua");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -8910,7 +8950,8 @@ namespace sol {
|
|||
#ifndef _MSC_VER
|
||||
static_assert(meta::all<meta::is_not_move_only<Args>...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention.");
|
||||
#endif // This compiler make me so fucking sad
|
||||
multi_check<checkargs, Args...>(L, start, type_panic);
|
||||
argument_handler handler{};
|
||||
multi_check<checkargs, Args...>(L, start, handler);
|
||||
record tracking{};
|
||||
return evaluator{}.eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
|
@ -8920,7 +8961,8 @@ namespace sol {
|
|||
#ifndef _MSC_VER
|
||||
static_assert(meta::all<meta::is_not_move_only<Args>...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention.");
|
||||
#endif // This compiler make me so fucking sad
|
||||
multi_check<checkargs, Args...>(L, start, type_panic);
|
||||
argument_handler handler{};
|
||||
multi_check<checkargs, Args...>(L, start, handler);
|
||||
record tracking{};
|
||||
evaluator{}.eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
|
@ -11394,7 +11436,8 @@ namespace sol {
|
|||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!is_function<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_function>(lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_function>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
|
@ -11408,13 +11451,15 @@ namespace sol {
|
|||
basic_function(lua_State* L, T&& r) : basic_function(L, sol::ref_index(r.registry_index())) {}
|
||||
basic_function(lua_State* L, int index = -1) : base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_function>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_function>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_function(lua_State* L, ref_index index) : base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_function>(L, -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_function>(L, -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
|
@ -11466,7 +11511,7 @@ namespace sol {
|
|||
decltype(auto) tagged_get(types<T>) const {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!valid()) {
|
||||
type_panic(L, index, type_of(L, index), type::none);
|
||||
type_panic_c_str(L, index, type_of(L, index), type::none);
|
||||
}
|
||||
#endif // Check Argument Safety
|
||||
return stack::get<T>(L, index);
|
||||
|
@ -11482,7 +11527,7 @@ namespace sol {
|
|||
error tagged_get(types<error>) const {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (valid()) {
|
||||
type_panic(L, index, type_of(L, index), type::none);
|
||||
type_panic_c_str(L, index, type_of(L, index), type::none);
|
||||
}
|
||||
#endif // Check Argument Safety
|
||||
return error(detail::direct_error, stack::get<std::string>(L, index));
|
||||
|
@ -11573,29 +11618,29 @@ namespace sol {
|
|||
}
|
||||
|
||||
template <bool b, typename target_t = reference>
|
||||
struct handler {
|
||||
struct protected_handler {
|
||||
typedef std::is_base_of<stack_reference, target_t> is_stack;
|
||||
const target_t& target;
|
||||
int stackindex;
|
||||
|
||||
handler(std::false_type, const target_t& target) : target(target), stackindex(0) {
|
||||
protected_handler(std::false_type, const target_t& target) : target(target), stackindex(0) {
|
||||
if (b) {
|
||||
stackindex = lua_gettop(target.lua_state()) + 1;
|
||||
target.push();
|
||||
}
|
||||
}
|
||||
|
||||
handler(std::true_type, const target_t& target) : target(target), stackindex(0) {
|
||||
protected_handler(std::true_type, const target_t& target) : target(target), stackindex(0) {
|
||||
if (b) {
|
||||
stackindex = target.stack_index();
|
||||
}
|
||||
}
|
||||
|
||||
handler(const target_t& target) : handler(is_stack(), target) {}
|
||||
protected_handler(const target_t& target) : protected_handler(is_stack(), target) {}
|
||||
|
||||
bool valid() const noexcept { return b; }
|
||||
|
||||
~handler() {
|
||||
~protected_handler() {
|
||||
if (!is_stack::value && stackindex != 0) {
|
||||
lua_remove(target.lua_state(), stackindex);
|
||||
}
|
||||
|
@ -11638,29 +11683,29 @@ namespace sol {
|
|||
|
||||
private:
|
||||
template <bool b>
|
||||
call_status luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, detail::handler<b, handler_t>& h) const {
|
||||
call_status luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, detail::protected_handler<b, handler_t>& h) const {
|
||||
return static_cast<call_status>(lua_pcallk(lua_state(), static_cast<int>(argcount), static_cast<int>(resultcount), h.stackindex, 0, nullptr));
|
||||
}
|
||||
|
||||
template<std::size_t... I, bool b, typename... Ret>
|
||||
auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n, detail::handler<b, handler_t>& h) const {
|
||||
auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
luacall(n, sizeof...(Ret), h);
|
||||
return stack::pop<std::tuple<Ret...>>(lua_state());
|
||||
}
|
||||
|
||||
template<std::size_t I, bool b, typename Ret>
|
||||
Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n, detail::handler<b, handler_t>& h) const {
|
||||
Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
luacall(n, 1, h);
|
||||
return stack::pop<Ret>(lua_state());
|
||||
}
|
||||
|
||||
template <std::size_t I, bool b>
|
||||
void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n, detail::handler<b, handler_t>& h) const {
|
||||
void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
luacall(n, 0, h);
|
||||
}
|
||||
|
||||
template <bool b>
|
||||
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n, detail::handler<b, handler_t>& h) const {
|
||||
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
int stacksize = lua_gettop(lua_state());
|
||||
int poststacksize = stacksize;
|
||||
int firstreturn = 1;
|
||||
|
@ -11722,7 +11767,8 @@ namespace sol {
|
|||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!is_function<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_protected_function>(lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
|
@ -11757,26 +11803,30 @@ namespace sol {
|
|||
basic_protected_function(lua_State* L, int index = -1) : basic_protected_function(L, index, get_default_handler(L)) {}
|
||||
basic_protected_function(lua_State* L, int index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_protected_function>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, absolute_index index) : basic_protected_function(L, index, get_default_handler(L)) {}
|
||||
basic_protected_function(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_protected_function>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, raw_index index) : basic_protected_function(L, index, get_default_handler(L)) {}
|
||||
basic_protected_function(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_protected_function>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, ref_index index) : basic_protected_function(L, index, get_default_handler(L)) {}
|
||||
basic_protected_function(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_protected_function>(L, -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
|
@ -11795,13 +11845,13 @@ namespace sol {
|
|||
if (!aligned) {
|
||||
// we do not expect the function to already be on the stack: push it
|
||||
if (error_handler.valid()) {
|
||||
detail::handler<true, handler_t> h(error_handler);
|
||||
detail::protected_handler<true, handler_t> h(error_handler);
|
||||
base_t::push();
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
}
|
||||
else {
|
||||
detail::handler<false, handler_t> h(error_handler);
|
||||
detail::protected_handler<false, handler_t> h(error_handler);
|
||||
base_t::push();
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
|
@ -11817,7 +11867,7 @@ namespace sol {
|
|||
// so, we need to remove the function at the top and then dump the handler out ourselves
|
||||
base_t::push();
|
||||
}
|
||||
detail::handler<true, handler_t> h(error_handler);
|
||||
detail::protected_handler<true, handler_t> h(error_handler);
|
||||
if (!is_stack_handler::value) {
|
||||
lua_replace(lua_state(), -3);
|
||||
h.stackindex = lua_absindex(lua_state(), -2);
|
||||
|
@ -11826,7 +11876,7 @@ namespace sol {
|
|||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
}
|
||||
else {
|
||||
detail::handler<false, handler_t> h(error_handler);
|
||||
detail::protected_handler<false, handler_t> h(error_handler);
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
}
|
||||
|
@ -12215,13 +12265,15 @@ namespace sol {
|
|||
basic_userdata(lua_State* L, T&& r) : basic_userdata(L, sol::ref_index(r.registry_index())) {}
|
||||
basic_userdata(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_userdata>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_userdata>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_userdata(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_userdata>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_userdata>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
};
|
||||
|
@ -12252,13 +12304,15 @@ namespace sol {
|
|||
basic_lightuserdata(lua_State* L, T&& r) : basic_lightuserdata(L, sol::ref_index(r.registry_index())) {}
|
||||
basic_lightuserdata(lua_State* L, int index = -1) : base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_lightuserdata>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_lightuserdata>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_lightuserdata(lua_State* L, ref_index index) : base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_lightuserdata>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_lightuserdata>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
};
|
||||
|
@ -16096,13 +16150,15 @@ namespace sol {
|
|||
}
|
||||
basic_table_core(lua_State* L, int index = -1) : basic_table_core(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_table_core>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_table_core>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_table_core(lua_State* L, ref_index index) : basic_table_core(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_table_core>(L, -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_table_core>(L, -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
template <typename T, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<base_type, stack_reference>>, std::is_base_of<base_type, meta::unqualified_t<T>>> = meta::enabler>
|
||||
|
@ -16110,7 +16166,8 @@ namespace sol {
|
|||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!is_table<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_table_core>(base_t::lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_table_core>(base_t::lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
|
@ -16449,25 +16506,29 @@ namespace sol {
|
|||
|
||||
basic_environment(env_t, const stack_reference& extraction_target) : base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<env_t>(this->lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<env_t>(this->lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
lua_pop(this->lua_state(), 2);
|
||||
}
|
||||
basic_environment(env_t, const reference& extraction_target) : base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<env_t>(this->lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<env_t>(this->lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
lua_pop(this->lua_state(), 2);
|
||||
}
|
||||
basic_environment(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_environment>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_environment>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_environment(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_environment>(L, -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_environment>(L, -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
template <typename T, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_environment>>, meta::neg<std::is_same<base_type, stack_reference>>, std::is_base_of<base_type, meta::unqualified_t<T>>> = meta::enabler>
|
||||
|
@ -16475,7 +16536,8 @@ namespace sol {
|
|||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!is_environment<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_environment>(lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_environment>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
|
@ -16607,7 +16669,7 @@ namespace sol {
|
|||
decltype(auto) tagged_get(types<T>) const {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!valid()) {
|
||||
type_panic(L, index, type_of(L, index), type::none);
|
||||
type_panic_c_str(L, index, type_of(L, index), type::none, "");
|
||||
}
|
||||
#endif // Check Argument Safety
|
||||
return stack::get<T>(L, index);
|
||||
|
@ -16623,7 +16685,7 @@ namespace sol {
|
|||
error tagged_get(types<error>) const {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (valid()) {
|
||||
type_panic(L, index, type_of(L, index), type::none);
|
||||
type_panic_c_str(L, index, type_of(L, index), type::none);
|
||||
}
|
||||
#endif // Check Argument Safety
|
||||
return error(detail::direct_error, stack::get<std::string>(L, index));
|
||||
|
@ -17104,6 +17166,15 @@ namespace sol {
|
|||
return safe_script_file(filename, env, script_default_on_error, mode);
|
||||
}
|
||||
|
||||
#ifdef SOL_SAFE_FUNCTIONS
|
||||
protected_function_result script(const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
return safe_script(code, chunkname, mode);
|
||||
}
|
||||
|
||||
protected_function_result script_file(const std::string& filename, load_mode mode = load_mode::any) {
|
||||
return safe_script_file(filename, mode);
|
||||
}
|
||||
#else
|
||||
function_result script(const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
return unsafe_script(code, chunkname, mode);
|
||||
}
|
||||
|
@ -17111,7 +17182,7 @@ namespace sol {
|
|||
function_result script_file(const std::string& filename, load_mode mode = load_mode::any) {
|
||||
return unsafe_script_file(filename, mode);
|
||||
}
|
||||
|
||||
#endif
|
||||
load_result load(const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
char basechunkname[17] = {};
|
||||
const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
|
||||
|
@ -17475,7 +17546,7 @@ namespace sol {
|
|||
optional<lua_thread_state> get(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
lua_thread_state lts{ lua_tothread(L, index) };
|
||||
if (lts.L == nullptr) {
|
||||
handler(L, index, type::thread, type_of(L, index));
|
||||
handler(L, index, type::thread, type_of(L, index), "value does is not a valid thread type");
|
||||
return nullopt;
|
||||
}
|
||||
tracking.use(1);
|
||||
|
@ -17628,13 +17699,15 @@ namespace sol {
|
|||
coroutine(lua_State* L, T&& r) : coroutine(L, sol::ref_index(r.registry_index())) {}
|
||||
coroutine(lua_State* L, int index = -1) : reference(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<coroutine>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<coroutine>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
coroutine(lua_State* L, ref_index index) : reference(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<coroutine>(L, -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<coroutine>(L, -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
|
|
|
@ -84,13 +84,15 @@ namespace sol {
|
|||
coroutine(lua_State* L, T&& r) : coroutine(L, sol::ref_index(r.registry_index())) {}
|
||||
coroutine(lua_State* L, int index = -1) : reference(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<coroutine>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<coroutine>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
coroutine(lua_State* L, ref_index index) : reference(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<coroutine>(L, -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<coroutine>(L, -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
|
|
|
@ -52,25 +52,29 @@ namespace sol {
|
|||
|
||||
basic_environment(env_t, const stack_reference& extraction_target) : base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<env_t>(this->lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<env_t>(this->lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
lua_pop(this->lua_state(), 2);
|
||||
}
|
||||
basic_environment(env_t, const reference& extraction_target) : base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<env_t>(this->lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<env_t>(this->lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
lua_pop(this->lua_state(), 2);
|
||||
}
|
||||
basic_environment(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_environment>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_environment>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_environment(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_environment>(L, -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_environment>(L, -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
template <typename T, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_environment>>, meta::neg<std::is_same<base_type, stack_reference>>, std::is_base_of<base_type, meta::unqualified_t<T>>> = meta::enabler>
|
||||
|
@ -78,7 +82,8 @@ namespace sol {
|
|||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!is_environment<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_environment>(lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_environment>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
|
|
99
sol/error_handler.hpp
Normal file
99
sol/error_handler.hpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2017 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_ERROR_HANDLER_HPP
|
||||
#define SOL_ERROR_HANDLER_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
||||
inline int type_panic_string(lua_State* L, int index, type expected, type actual, const std::string& message = "") noexcept(false) {
|
||||
const char* err = message.empty() ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s with message %s";
|
||||
return luaL_error(L, err, index,
|
||||
expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected)),
|
||||
actual == type::poly ? "anything" : lua_typename(L, static_cast<int>(actual)),
|
||||
message.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
inline int type_panic_c_str(lua_State* L, int index, type expected, type actual, const char* message = nullptr) noexcept(false) {
|
||||
const char* err = message == nullptr || (std::char_traits<char>::length(message) == 0) ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s with message %s";
|
||||
return luaL_error(L, err, index,
|
||||
expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected)),
|
||||
actual == type::poly ? "anything" : lua_typename(L, static_cast<int>(actual)),
|
||||
message
|
||||
);
|
||||
}
|
||||
|
||||
struct type_panic_t {
|
||||
int operator()(lua_State* L, int index, type expected, type actual) const noexcept(false) {
|
||||
return type_panic_c_str(L, index, expected, actual, nullptr);
|
||||
}
|
||||
int operator()(lua_State* L, int index, type expected, type actual, const char* message) const noexcept(false) {
|
||||
return type_panic_c_str(L, index, expected, actual, message);
|
||||
}
|
||||
int operator()(lua_State* L, int index, type expected, type actual, const std::string& message) const noexcept(false) {
|
||||
return type_panic_string(L, index, expected, actual, message);
|
||||
}
|
||||
};
|
||||
|
||||
const type_panic_t type_panic = {};
|
||||
|
||||
struct constructor_handler {
|
||||
int operator()(lua_State* L, int index, type expected, type actual, const std::string& message) const noexcept(false) {
|
||||
return type_panic_string(L, index, expected, actual, message + " (type check failed in constructor)");
|
||||
}
|
||||
};
|
||||
|
||||
struct argument_handler {
|
||||
int operator()(lua_State* L, int index, type expected, type actual, const std::string& message) const noexcept(false) {
|
||||
return type_panic_string(L, index, expected, actual, message + " (bad argument to variable or function call)");
|
||||
}
|
||||
};
|
||||
|
||||
// Specify this function as the handler for lua::check if you know there's nothing wrong
|
||||
inline int no_panic(lua_State*, int, type, type, const char* = nullptr) noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void type_error(lua_State* L, int expected, int actual) noexcept(false) {
|
||||
luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual));
|
||||
}
|
||||
|
||||
inline void type_error(lua_State* L, type expected, type actual) noexcept(false) {
|
||||
type_error(L, static_cast<int>(expected), static_cast<int>(actual));
|
||||
}
|
||||
|
||||
inline void type_assert(lua_State* L, int index, type expected, type actual) noexcept(false) {
|
||||
if (expected != type::poly && expected != actual) {
|
||||
type_panic_c_str(L, index, expected, actual, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
inline void type_assert(lua_State* L, int index, type expected) {
|
||||
type actual = type_of(L, index);
|
||||
type_assert(L, index, expected, actual);
|
||||
}
|
||||
|
||||
} // sol
|
||||
|
||||
#endif // SOL_ERROR_HANDLER_HPP
|
|
@ -48,7 +48,7 @@ namespace sol {
|
|||
decltype(auto) tagged_get(types<T>) const {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!valid()) {
|
||||
type_panic(L, index, type_of(L, index), type::none);
|
||||
type_panic_c_str(L, index, type_of(L, index), type::none, "");
|
||||
}
|
||||
#endif // Check Argument Safety
|
||||
return stack::get<T>(L, index);
|
||||
|
@ -64,7 +64,7 @@ namespace sol {
|
|||
error tagged_get(types<error>) const {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (valid()) {
|
||||
type_panic(L, index, type_of(L, index), type::none);
|
||||
type_panic_c_str(L, index, type_of(L, index), type::none);
|
||||
}
|
||||
#endif // Check Argument Safety
|
||||
return error(detail::direct_error, stack::get<std::string>(L, index));
|
||||
|
|
|
@ -37,29 +37,29 @@ namespace sol {
|
|||
}
|
||||
|
||||
template <bool b, typename target_t = reference>
|
||||
struct handler {
|
||||
struct protected_handler {
|
||||
typedef std::is_base_of<stack_reference, target_t> is_stack;
|
||||
const target_t& target;
|
||||
int stackindex;
|
||||
|
||||
handler(std::false_type, const target_t& target) : target(target), stackindex(0) {
|
||||
protected_handler(std::false_type, const target_t& target) : target(target), stackindex(0) {
|
||||
if (b) {
|
||||
stackindex = lua_gettop(target.lua_state()) + 1;
|
||||
target.push();
|
||||
}
|
||||
}
|
||||
|
||||
handler(std::true_type, const target_t& target) : target(target), stackindex(0) {
|
||||
protected_handler(std::true_type, const target_t& target) : target(target), stackindex(0) {
|
||||
if (b) {
|
||||
stackindex = target.stack_index();
|
||||
}
|
||||
}
|
||||
|
||||
handler(const target_t& target) : handler(is_stack(), target) {}
|
||||
protected_handler(const target_t& target) : protected_handler(is_stack(), target) {}
|
||||
|
||||
bool valid() const noexcept { return b; }
|
||||
|
||||
~handler() {
|
||||
~protected_handler() {
|
||||
if (!is_stack::value && stackindex != 0) {
|
||||
lua_remove(target.lua_state(), stackindex);
|
||||
}
|
||||
|
@ -102,29 +102,29 @@ namespace sol {
|
|||
|
||||
private:
|
||||
template <bool b>
|
||||
call_status luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, detail::handler<b, handler_t>& h) const {
|
||||
call_status luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, detail::protected_handler<b, handler_t>& h) const {
|
||||
return static_cast<call_status>(lua_pcallk(lua_state(), static_cast<int>(argcount), static_cast<int>(resultcount), h.stackindex, 0, nullptr));
|
||||
}
|
||||
|
||||
template<std::size_t... I, bool b, typename... Ret>
|
||||
auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n, detail::handler<b, handler_t>& h) const {
|
||||
auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
luacall(n, sizeof...(Ret), h);
|
||||
return stack::pop<std::tuple<Ret...>>(lua_state());
|
||||
}
|
||||
|
||||
template<std::size_t I, bool b, typename Ret>
|
||||
Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n, detail::handler<b, handler_t>& h) const {
|
||||
Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
luacall(n, 1, h);
|
||||
return stack::pop<Ret>(lua_state());
|
||||
}
|
||||
|
||||
template <std::size_t I, bool b>
|
||||
void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n, detail::handler<b, handler_t>& h) const {
|
||||
void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
luacall(n, 0, h);
|
||||
}
|
||||
|
||||
template <bool b>
|
||||
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n, detail::handler<b, handler_t>& h) const {
|
||||
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
int stacksize = lua_gettop(lua_state());
|
||||
int poststacksize = stacksize;
|
||||
int firstreturn = 1;
|
||||
|
@ -186,7 +186,8 @@ namespace sol {
|
|||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!is_function<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_protected_function>(lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
|
@ -221,26 +222,30 @@ namespace sol {
|
|||
basic_protected_function(lua_State* L, int index = -1) : basic_protected_function(L, index, get_default_handler(L)) {}
|
||||
basic_protected_function(lua_State* L, int index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_protected_function>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, absolute_index index) : basic_protected_function(L, index, get_default_handler(L)) {}
|
||||
basic_protected_function(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_protected_function>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, raw_index index) : basic_protected_function(L, index, get_default_handler(L)) {}
|
||||
basic_protected_function(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_protected_function>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, ref_index index) : basic_protected_function(L, index, get_default_handler(L)) {}
|
||||
basic_protected_function(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_protected_function>(L, -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
|
@ -259,13 +264,13 @@ namespace sol {
|
|||
if (!aligned) {
|
||||
// we do not expect the function to already be on the stack: push it
|
||||
if (error_handler.valid()) {
|
||||
detail::handler<true, handler_t> h(error_handler);
|
||||
detail::protected_handler<true, handler_t> h(error_handler);
|
||||
base_t::push();
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
}
|
||||
else {
|
||||
detail::handler<false, handler_t> h(error_handler);
|
||||
detail::protected_handler<false, handler_t> h(error_handler);
|
||||
base_t::push();
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
|
@ -281,7 +286,7 @@ namespace sol {
|
|||
// so, we need to remove the function at the top and then dump the handler out ourselves
|
||||
base_t::push();
|
||||
}
|
||||
detail::handler<true, handler_t> h(error_handler);
|
||||
detail::protected_handler<true, handler_t> h(error_handler);
|
||||
if (!is_stack_handler::value) {
|
||||
lua_replace(lua_state(), -3);
|
||||
h.stackindex = lua_absindex(lua_state(), -2);
|
||||
|
@ -290,7 +295,7 @@ namespace sol {
|
|||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
}
|
||||
else {
|
||||
detail::handler<false, handler_t> h(error_handler);
|
||||
detail::protected_handler<false, handler_t> h(error_handler);
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace sol {
|
|||
decltype(auto) tagged_get(types<T>) const {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!valid()) {
|
||||
type_panic(L, index, type_of(L, index), type::none);
|
||||
type_panic_c_str(L, index, type_of(L, index), type::none);
|
||||
}
|
||||
#endif // Check Argument Safety
|
||||
return stack::get<T>(L, index);
|
||||
|
@ -65,7 +65,7 @@ namespace sol {
|
|||
error tagged_get(types<error>) const {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (valid()) {
|
||||
type_panic(L, index, type_of(L, index), type::none);
|
||||
type_panic_c_str(L, index, type_of(L, index), type::none);
|
||||
}
|
||||
#endif // Check Argument Safety
|
||||
return error(detail::direct_error, stack::get<std::string>(L, index));
|
||||
|
|
|
@ -113,7 +113,8 @@ namespace sol {
|
|||
#ifndef _MSC_VER
|
||||
static_assert(meta::all<meta::is_not_move_only<Args>...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention.");
|
||||
#endif // This compiler make me so fucking sad
|
||||
multi_check<checkargs, Args...>(L, start, type_panic);
|
||||
argument_handler handler{};
|
||||
multi_check<checkargs, Args...>(L, start, handler);
|
||||
record tracking{};
|
||||
return evaluator{}.eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
|
@ -123,7 +124,8 @@ namespace sol {
|
|||
#ifndef _MSC_VER
|
||||
static_assert(meta::all<meta::is_not_move_only<Args>...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention.");
|
||||
#endif // This compiler make me so fucking sad
|
||||
multi_check<checkargs, Args...>(L, start, type_panic);
|
||||
argument_handler handler{};
|
||||
multi_check<checkargs, Args...>(L, start, handler);
|
||||
record tracking{};
|
||||
evaluator{}.eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace sol {
|
|||
bool success = check_func(L, index) == 1;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, expected, type_of(L, index));
|
||||
handler(L, index, expected, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -74,8 +74,8 @@ namespace sol {
|
|||
const type indextype = type_of(L, index);
|
||||
bool success = expected == indextype;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, expected, indextype);
|
||||
// expected type, actual type, message
|
||||
handler(L, index, expected, indextype, "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ namespace sol {
|
|||
#endif // If numbers are enabled, use the imprecise check
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
handler(L, index, type::number, type_of(L, index), "not a numeric type");
|
||||
}
|
||||
return success;
|
||||
#else
|
||||
|
@ -109,7 +109,7 @@ namespace sol {
|
|||
type t = type_of(L, index);
|
||||
if (t != type::number) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not a numeric type");
|
||||
return false;
|
||||
}
|
||||
#endif // Do not allow strings to be numbers
|
||||
|
@ -119,9 +119,9 @@ namespace sol {
|
|||
if (!success) {
|
||||
// expected type, actual type
|
||||
#ifndef SOL_STRINGS_ARE_NUMBERS
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not a numeric type");
|
||||
#else
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
handler(L, index, type::number, type_of(L, index), "not a numeric type or numeric string");
|
||||
#endif
|
||||
}
|
||||
return success;
|
||||
|
@ -134,19 +134,19 @@ namespace sol {
|
|||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
#ifdef SOL_STRINGS_ARE_NUMBERS
|
||||
#ifndef SOL_STRINGS_ARE_NUMBERS
|
||||
type t = type_of(L, index);
|
||||
bool success = t == type::number;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not a numeric type");
|
||||
}
|
||||
return success;
|
||||
#else
|
||||
bool success = lua_isnumber(L, index) == 1;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
handler(L, index, type::number, type_of(L, index), "not a numeric type or numeric string");
|
||||
}
|
||||
return success;
|
||||
#endif
|
||||
|
@ -166,7 +166,7 @@ namespace sol {
|
|||
success = lua_isnone(L, index);
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, expected, type_of(L, index));
|
||||
handler(L, index, expected, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ namespace sol {
|
|||
bool success = !lua_isnone(L, index);
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::none, type_of(L, index));
|
||||
handler(L, index, type::none, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ namespace sol {
|
|||
bool success = t == type::userdata || t == type::lightuserdata;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::lightuserdata, t);
|
||||
handler(L, index, type::lightuserdata, t, "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ namespace sol {
|
|||
bool success = t == type::userdata;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::userdata, t);
|
||||
handler(L, index, type::userdata, t, "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -287,25 +287,25 @@ namespace sol {
|
|||
return true;
|
||||
}
|
||||
if (t != type::userdata && t != type::table) {
|
||||
handler(L, index, type::function, t);
|
||||
handler(L, index, type::function, t, "must be a function or table or a userdata");
|
||||
return false;
|
||||
}
|
||||
// Do advanced check for call-style userdata?
|
||||
static const auto& callkey = to_string(meta_function::call);
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
// No metatable, no __call key possible
|
||||
handler(L, index, type::function, t);
|
||||
handler(L, index, type::function, t, "value is not a function and does not have overriden metatable");
|
||||
return false;
|
||||
}
|
||||
if (lua_isnoneornil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::function, t);
|
||||
handler(L, index, type::function, t, "value is not a function and does not have valid metatable");
|
||||
return false;
|
||||
}
|
||||
lua_getfield(L, -1, &callkey[0]);
|
||||
if (lua_isnoneornil(L, -1)) {
|
||||
lua_pop(L, 2);
|
||||
handler(L, index, type::function, t);
|
||||
handler(L, index, type::function, t, "value's metatable does not have __call overridden in metatable, cannot call this type");
|
||||
return false;
|
||||
}
|
||||
// has call, is definitely a function
|
||||
|
@ -324,7 +324,7 @@ namespace sol {
|
|||
return true;
|
||||
}
|
||||
if (t != type::userdata) {
|
||||
handler(L, index, type::table, t);
|
||||
handler(L, index, type::table, t, "value is not a table or a userdata that can behave like one");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -346,7 +346,7 @@ namespace sol {
|
|||
}
|
||||
if (t != type::userdata) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, expected, t);
|
||||
handler(L, index, expected, t, "value does not have a valid metatable");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -358,19 +358,11 @@ namespace sol {
|
|||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
type t = type_of(L, index);
|
||||
if (t == type::table || t == type::none || t == type::nil || t == type::userdata) {
|
||||
return true;
|
||||
}
|
||||
type t = type_of(L, -1);
|
||||
if (t == type::table || t == type::none || t == type::nil) {
|
||||
lua_pop(L, 1);
|
||||
return true;
|
||||
}
|
||||
if (t != type::userdata) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::table, t);
|
||||
return false;
|
||||
}
|
||||
handler(L, index, type::table, t, "value cannot not have a valid environment");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -390,7 +382,7 @@ namespace sol {
|
|||
}
|
||||
if (t != type::userdata) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::table, t);
|
||||
handler(L, index, type::table, t, "value does not have a valid metatable");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -403,7 +395,7 @@ namespace sol {
|
|||
static bool check(types<U>, lua_State* L, type indextype, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
if (indextype != type::userdata) {
|
||||
handler(L, index, type::userdata, indextype);
|
||||
handler(L, index, type::userdata, indextype, "value is not a valid userdata");
|
||||
return false;
|
||||
}
|
||||
if (meta::any<std::is_same<T, lightuserdata_value>, std::is_same<T, userdata_value>, std::is_same<T, userdata>, std::is_same<T, lightuserdata>>::value)
|
||||
|
@ -433,7 +425,7 @@ namespace sol {
|
|||
}
|
||||
if (!success) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::userdata, indextype);
|
||||
handler(L, index, type::userdata, indextype, "value is not a valid sol userdata of any kind");
|
||||
return false;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
@ -472,7 +464,7 @@ namespace sol {
|
|||
const type indextype = type_of(L, index);
|
||||
tracking.use(1);
|
||||
if (indextype != type::userdata) {
|
||||
handler(L, index, type::userdata, indextype);
|
||||
handler(L, index, type::userdata, indextype, "value is not a userdata");
|
||||
return false;
|
||||
}
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
|
@ -485,12 +477,12 @@ namespace sol {
|
|||
detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(static_cast<void*>(pointerpointer + 1));
|
||||
bool success = &detail::usertype_unique_alloc_destroy<T, X> == pdx;
|
||||
if (!success) {
|
||||
handler(L, index, type::userdata, indextype);
|
||||
handler(L, index, type::userdata, indextype, "value is a userdata but is not the correct unique usertype");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::userdata, indextype);
|
||||
handler(L, index, type::userdata, indextype, "unrecognized userdata (not pushed by sol?)");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
@ -549,7 +541,7 @@ namespace sol {
|
|||
return true;
|
||||
}
|
||||
tracking.use(1);
|
||||
handler(L, index, type::poly, type_of(L, index));
|
||||
handler(L, index, type::poly, type_of(L, index), "value does not fit any type present in the variant");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace sol {
|
|||
int isnum = 0;
|
||||
const lua_Number value = lua_tonumberx(L, index, &isnum);
|
||||
if (isnum != 0) {
|
||||
#if 1 // defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
#if defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
const auto integer_value = llround(value);
|
||||
if (static_cast<lua_Number>(integer_value) == value) {
|
||||
tracking.use(1);
|
||||
|
@ -79,7 +79,7 @@ namespace sol {
|
|||
}
|
||||
const type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not an integer");
|
||||
return nullopt;
|
||||
}
|
||||
};
|
||||
|
@ -93,7 +93,7 @@ namespace sol {
|
|||
if (isnum == 0) {
|
||||
type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not a valid enumeration value");
|
||||
return nullopt;
|
||||
}
|
||||
tracking.use(1);
|
||||
|
@ -110,7 +110,7 @@ namespace sol {
|
|||
if (isnum == 0) {
|
||||
type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t);
|
||||
handler(L, index, type::number, t, "not a valid floating point number");
|
||||
return nullopt;
|
||||
}
|
||||
tracking.use(1);
|
||||
|
@ -142,7 +142,7 @@ namespace sol {
|
|||
typedef std::variant_alternative_t<0, V> T;
|
||||
// This should never be reached...
|
||||
// please check your code and understand what you did to bring yourself here
|
||||
handler(L, index, type::poly, type_of(L, index));
|
||||
handler(L, index, type::poly, type_of(L, index), "this variant code should never be reached: if it has, you have done something so terribly wrong");
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define SOL_STACK_CORE_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
#include "error_handler.hpp"
|
||||
#include "reference.hpp"
|
||||
#include "stack_reference.hpp"
|
||||
#include "tuple.hpp"
|
||||
|
@ -299,7 +300,7 @@ namespace sol {
|
|||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
template <typename T>
|
||||
inline auto tagged_get(types<T>, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get<T>(L, index, tracking)) {
|
||||
auto op = check_get<T>(L, index, type_panic, tracking);
|
||||
auto op = check_get<T>(L, index, type_panic_c_str, tracking);
|
||||
return *std::move(op);
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -226,10 +226,13 @@ namespace sol {
|
|||
#endif
|
||||
#if defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
if (static_cast<T>(llround(static_cast<lua_Number>(value))) != value) {
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
throw sol::error("The integer will be misrepresented in lua.");
|
||||
#ifdef SOL_NO_EXCEPTIONS
|
||||
// Is this really worth it?
|
||||
assert(false && "integer value will be misrepresented in lua");
|
||||
lua_pushnumber(L, static_cast<lua_Number>(value));
|
||||
return 1;
|
||||
#else
|
||||
assert(false && "The integer will be misrepresented in lua.");
|
||||
throw error(detail::direct_error, "integer value will be misrepresented in lua");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -435,6 +435,15 @@ namespace sol {
|
|||
return safe_script_file(filename, env, script_default_on_error, mode);
|
||||
}
|
||||
|
||||
#ifdef SOL_SAFE_FUNCTIONS
|
||||
protected_function_result script(const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
return safe_script(code, chunkname, mode);
|
||||
}
|
||||
|
||||
protected_function_result script_file(const std::string& filename, load_mode mode = load_mode::any) {
|
||||
return safe_script_file(filename, mode);
|
||||
}
|
||||
#else
|
||||
function_result script(const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
return unsafe_script(code, chunkname, mode);
|
||||
}
|
||||
|
@ -442,7 +451,7 @@ namespace sol {
|
|||
function_result script_file(const std::string& filename, load_mode mode = load_mode::any) {
|
||||
return unsafe_script_file(filename, mode);
|
||||
}
|
||||
|
||||
#endif
|
||||
load_result load(const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
char basechunkname[17] = {};
|
||||
const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
|
||||
|
|
|
@ -185,13 +185,15 @@ namespace sol {
|
|||
}
|
||||
basic_table_core(lua_State* L, int index = -1) : basic_table_core(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_table_core>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_table_core>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_table_core(lua_State* L, ref_index index) : basic_table_core(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_table_core>(L, -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_table_core>(L, -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
template <typename T, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<base_type, stack_reference>>, std::is_base_of<base_type, meta::unqualified_t<T>>> = meta::enabler>
|
||||
|
@ -199,7 +201,8 @@ namespace sol {
|
|||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!is_table<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_table_core>(base_t::lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_table_core>(base_t::lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace sol {
|
|||
optional<lua_thread_state> get(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
lua_thread_state lts{ lua_tothread(L, index) };
|
||||
if (lts.L == nullptr) {
|
||||
handler(L, index, type::thread, type_of(L, index));
|
||||
handler(L, index, type::thread, type_of(L, index), "value does is not a valid thread type");
|
||||
return nullopt;
|
||||
}
|
||||
tracking.use(1);
|
||||
|
|
|
@ -667,37 +667,6 @@ namespace sol {
|
|||
return static_cast<type>(lua_type(L, index));
|
||||
}
|
||||
|
||||
inline int type_panic(lua_State* L, int index, type expected, type actual) noexcept(false) {
|
||||
return luaL_error(L, "stack index %d, expected %s, received %s", index,
|
||||
expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected)),
|
||||
actual == type::poly ? "anything" : lua_typename(L, static_cast<int>(actual))
|
||||
);
|
||||
}
|
||||
|
||||
// Specify this function as the handler for lua::check if you know there's nothing wrong
|
||||
inline int no_panic(lua_State*, int, type, type) noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void type_error(lua_State* L, int expected, int actual) noexcept(false) {
|
||||
luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual));
|
||||
}
|
||||
|
||||
inline void type_error(lua_State* L, type expected, type actual) noexcept(false) {
|
||||
type_error(L, static_cast<int>(expected), static_cast<int>(actual));
|
||||
}
|
||||
|
||||
inline void type_assert(lua_State* L, int index, type expected, type actual) noexcept(false) {
|
||||
if (expected != type::poly && expected != actual) {
|
||||
type_panic(L, index, expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
inline void type_assert(lua_State* L, int index, type expected) {
|
||||
type actual = type_of(L, index);
|
||||
type_assert(L, index, expected, actual);
|
||||
}
|
||||
|
||||
inline std::string type_name(lua_State* L, type t) {
|
||||
return lua_typename(L, static_cast<int>(t));
|
||||
}
|
||||
|
|
|
@ -71,7 +71,8 @@ namespace sol {
|
|||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
if (!is_function<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_function>(lua_state(), -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_function>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
|
@ -85,13 +86,15 @@ namespace sol {
|
|||
basic_function(lua_State* L, T&& r) : basic_function(L, sol::ref_index(r.registry_index())) {}
|
||||
basic_function(lua_State* L, int index = -1) : base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_function>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_function>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_function(lua_State* L, ref_index index) : base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_function>(L, -1, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_function>(L, -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
|
|
|
@ -52,13 +52,15 @@ namespace sol {
|
|||
basic_userdata(lua_State* L, T&& r) : basic_userdata(L, sol::ref_index(r.registry_index())) {}
|
||||
basic_userdata(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_userdata>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_userdata>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_userdata(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_userdata>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_userdata>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
};
|
||||
|
@ -89,13 +91,15 @@ namespace sol {
|
|||
basic_lightuserdata(lua_State* L, T&& r) : basic_lightuserdata(L, sol::ref_index(r.registry_index())) {}
|
||||
basic_lightuserdata(lua_State* L, int index = -1) : base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
stack::check<basic_lightuserdata>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_lightuserdata>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_lightuserdata(lua_State* L, ref_index index) : base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
auto pp = stack::push_pop(*this);
|
||||
stack::check<basic_lightuserdata>(L, index, type_panic);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_lightuserdata>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1164,82 +1164,94 @@ TEST_CASE("functions/pointer nullptr + nil", "ensure specific semantics for hand
|
|||
REQUIRE_FALSE(result.valid());
|
||||
}
|
||||
SECTION("throw ref") {
|
||||
REQUIRE_THROWS([&]() {
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v1"] = sptr;
|
||||
nil_test& v1 = lua["v1"];
|
||||
(void)(&v1 == sptr.get());
|
||||
}());
|
||||
REQUIRE_THROWS([&]() {
|
||||
sol::object o = lua["v1"];
|
||||
bool isp = o.is<nil_test&>();
|
||||
REQUIRE_FALSE(isp);
|
||||
}
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v2"] = std::unique_ptr<nil_test>();
|
||||
nil_test& v2 = lua["v2"];
|
||||
(void)(&v2 == uptr.get());
|
||||
}());
|
||||
REQUIRE_THROWS([&]() {
|
||||
sol::object o = lua["v2"];
|
||||
bool isp = o.is<nil_test&>();
|
||||
REQUIRE_FALSE(isp);
|
||||
}
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v3"] = rptr;
|
||||
nil_test& v3 = lua["v3"];
|
||||
(void)(&v3 == rptr);
|
||||
}());
|
||||
REQUIRE_THROWS([&]() {
|
||||
sol::object o = lua["v3"];
|
||||
bool isp = o.is<nil_test&>();
|
||||
REQUIRE_FALSE(isp);
|
||||
}
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v4"] = vptr;
|
||||
nil_test& v4 = lua["v4"];
|
||||
(void)(&v4 == vptr);
|
||||
}());
|
||||
sol::object o = lua["v4"];
|
||||
bool isp = o.is<nil_test&>();
|
||||
REQUIRE_FALSE(isp);
|
||||
}
|
||||
}
|
||||
SECTION("throw unique") {
|
||||
REQUIRE_THROWS([&]() {
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v1"] = sptr;
|
||||
std::unique_ptr<nil_test>& v1 = lua["v1"];
|
||||
(void)(v1.get() == sptr.get());
|
||||
}());
|
||||
REQUIRE_THROWS([&]() {
|
||||
sol::object o = lua["v1"];
|
||||
bool isp = o.is<std::unique_ptr<nil_test>>();
|
||||
REQUIRE_FALSE(isp);
|
||||
}
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v2"] = std::unique_ptr<nil_test>();
|
||||
std::unique_ptr<nil_test>& v2 = lua["v2"];
|
||||
(void)(v2.get() == uptr.get());
|
||||
}());
|
||||
REQUIRE_THROWS([&]() {
|
||||
sol::object o = lua["v2"];
|
||||
bool isp = o.is<std::unique_ptr<nil_test>>();
|
||||
REQUIRE_FALSE(isp);
|
||||
}
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v3"] = rptr;
|
||||
std::unique_ptr<nil_test>& v3 = lua["v3"];
|
||||
(void)(v3.get() == rptr);
|
||||
}());
|
||||
REQUIRE_THROWS([&]() {
|
||||
sol::object o = lua["v3"];
|
||||
bool isp = o.is<std::unique_ptr<nil_test>>();
|
||||
REQUIRE_FALSE(isp);
|
||||
};
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v4"] = vptr;
|
||||
std::unique_ptr<nil_test>& v4 = lua["v4"];
|
||||
(void)(v4.get() == vptr);
|
||||
}());
|
||||
sol::object o = lua["v4"];
|
||||
bool isp = o.is<std::unique_ptr<nil_test>>();
|
||||
REQUIRE_FALSE(isp);
|
||||
};
|
||||
}
|
||||
SECTION("throw shared") {
|
||||
REQUIRE_THROWS([&]() {
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v1"] = sptr;
|
||||
std::shared_ptr<nil_test>& v1 = lua["v1"];
|
||||
(void)(v1.get() == sptr.get());
|
||||
}());
|
||||
REQUIRE_THROWS([&]() {
|
||||
sol::object o = lua["v1"];
|
||||
bool isp = o.is<std::shared_ptr<nil_test>>();
|
||||
REQUIRE_FALSE(isp);
|
||||
}
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v2"] = std::unique_ptr<nil_test>();
|
||||
std::shared_ptr<nil_test>& v2 = lua["v2"];
|
||||
(void)(v2.get() == uptr.get());
|
||||
}());
|
||||
REQUIRE_THROWS([&]() {
|
||||
sol::object o = lua["v2"];
|
||||
bool isp = o.is<std::shared_ptr<nil_test>>();
|
||||
REQUIRE_FALSE(isp);
|
||||
}
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v3"] = rptr;
|
||||
std::shared_ptr<nil_test>& v3 = lua["v3"];
|
||||
(void)(v3.get() == rptr);
|
||||
}());
|
||||
REQUIRE_THROWS([&]() {
|
||||
sol::object o = lua["v3"];
|
||||
bool isp = o.is<std::shared_ptr<nil_test>>();
|
||||
REQUIRE_FALSE(isp);
|
||||
}
|
||||
{
|
||||
sol::state lua;
|
||||
lua["v4"] = vptr;
|
||||
std::shared_ptr<nil_test>& v4 = lua["v4"];
|
||||
(void)(v4.get() == vptr);
|
||||
}());
|
||||
sol::object o = lua["v4"];
|
||||
bool isp = o.is<std::shared_ptr<nil_test>>();
|
||||
REQUIRE_FALSE(isp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -427,7 +427,7 @@ TEST_CASE("operators/container-like", "test that generic begin/end and iterator
|
|||
}
|
||||
}
|
||||
#else
|
||||
REQUIRE(true);
|
||||
SUCCEED("");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user