mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Hammer down function behavior and provide an example to show how it works
This commit is contained in:
parent
1e5c256394
commit
cd13f2dc0d
53
examples/functions_empty_arguments.cpp
Normal file
53
examples/functions_empty_arguments.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include "assert.hpp"
|
||||
#include <iostream>
|
||||
|
||||
int main(int, char*[]) {
|
||||
std::cout << "=== functions empty args ===" << std::endl;
|
||||
|
||||
// sol::reference, sol::Stack_reference,
|
||||
// sol::object (and main_* types) can all be
|
||||
// used to capture "nil", or "none" when a function
|
||||
// leaves it off
|
||||
auto my_defaulting_function = [](sol::object maybe_defaulted) -> int {
|
||||
// if it's nil, it's "unused" or "inactive"
|
||||
bool inactive = maybe_defaulted == sol::lua_nil;
|
||||
if (inactive) {
|
||||
return 0;
|
||||
}
|
||||
if (maybe_defaulted.is<int>()) {
|
||||
int value = maybe_defaulted.as<int>();
|
||||
return value;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
// copy function in (use std::ref to change this behavior)
|
||||
lua.set_function("defaulting_function", my_defaulting_function);
|
||||
|
||||
sol::string_view code = R"(
|
||||
result = defaulting_function(24)
|
||||
result_nothing = defaulting_function()
|
||||
result_nil = defaulting_function(nil)
|
||||
result_string = defaulting_function('meow')
|
||||
print('defaulting_function(24), returned:', result)
|
||||
print('defaulting_function(), returned:', result_nothing)
|
||||
print('defaulting_function(nil), returned:', result_nil)
|
||||
print('defaulting_function(\'meow\'), returned:', result_string)
|
||||
assert(result == 24)
|
||||
assert(result_nothing == 0)
|
||||
assert(result_nil == 0)
|
||||
assert(result_string == 1)
|
||||
)";
|
||||
|
||||
lua.safe_script(code);
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -7899,12 +7899,7 @@ namespace stack {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
bool success = !lua_isnone(L, index);
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::poly, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -239,7 +239,7 @@ namespace stack {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
bool success = !lua_isnone(L, index);
|
||||
bool success = is_lua_reference<T>::value || !lua_isnone(L, index);
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::poly, type_of(L, index), "");
|
||||
|
@ -135,15 +135,16 @@ namespace stack {
|
||||
typedef std::integral_constant<bool, V_size::value == 0> V_is_empty;
|
||||
|
||||
template <typename Handler>
|
||||
static optional<V> get_empty(std::true_type, lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
static optional<V> get_empty(std::true_type, lua_State*, int, Handler&&, record&) {
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
static optional<V> get_empty(std::false_type, lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
static optional<V> get_empty(std::false_type, lua_State* L, int index, Handler&& handler, record&) {
|
||||
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
|
||||
// maybe file a bug report, or 5
|
||||
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;
|
||||
}
|
||||
|
@ -1490,6 +1490,54 @@ TEST_CASE("functions/unique_usertype overloading", "make sure overloading can wo
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("functions/lua style default arguments", "allow default arguments using sol::reference and sol::object") {
|
||||
auto def_f1 = [](sol::object defaulted) -> int {
|
||||
bool inactive = defaulted == sol::lua_nil; // inactive by default
|
||||
if (inactive) {
|
||||
return 20;
|
||||
}
|
||||
return 10;
|
||||
};
|
||||
auto def_f2 = [](sol::reference defaulted) -> int {
|
||||
bool inactive = defaulted == sol::lua_nil; // inactive by default
|
||||
if (inactive) {
|
||||
return 20;
|
||||
}
|
||||
return 10;
|
||||
};
|
||||
auto def_f3 = [](sol::stack_reference defaulted) -> int {
|
||||
bool inactive = defaulted == sol::lua_nil; // inactive by default
|
||||
if (inactive) {
|
||||
return 20;
|
||||
}
|
||||
return 10;
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.set_function("f1", def_f1);
|
||||
lua.set_function("f2", def_f2);
|
||||
lua.set_function("f3", def_f3);
|
||||
|
||||
auto result = lua.safe_script(R"(
|
||||
v1d, v1nd = f1(), f1(1)
|
||||
v2d, v2nd = f2(), f2(1)
|
||||
v3d, v3nd = f3(), f3(1)
|
||||
)", sol::script_pass_on_error);
|
||||
REQUIRE(result.valid());
|
||||
int v1d = lua["v1d"];
|
||||
int v1nd = lua["v1nd"];
|
||||
int v2d = lua["v2d"];
|
||||
int v2nd = lua["v2nd"];
|
||||
int v3d = lua["v3d"];
|
||||
int v3nd = lua["v3nd"];
|
||||
REQUIRE(20 == v1d);
|
||||
REQUIRE(20 == v2d);
|
||||
REQUIRE(20 == v3d);
|
||||
REQUIRE(10 == v1nd);
|
||||
REQUIRE(10 == v2nd);
|
||||
REQUIRE(10 == v3nd);
|
||||
}
|
||||
|
||||
#if !defined(_MSC_VER) || !(defined(_WIN32) && !defined(_WIN64))
|
||||
|
||||
TEST_CASE("functions/noexcept", "allow noexcept functions to be serialized properly into Lua using sol2") {
|
||||
|
Loading…
x
Reference in New Issue
Block a user