Skip to content

Commit e8649d2

Browse files
committed
NOW it's REALLY fixed, super duperly.
1 parent e60a628 commit e8649d2

File tree

4 files changed

+108
-17
lines changed

4 files changed

+108
-17
lines changed

include/sol/function_types.hpp

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,29 @@ namespace sol {
250250
namespace stack {
251251
template <typename... Sigs>
252252
struct unqualified_pusher<function_sig<Sigs...>> {
253+
template <bool is_yielding, typename Arg0, typename... Args>
254+
static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
255+
if constexpr (meta::is_specialization_of_v<meta::unqualified_t<Arg0>, std::function>) {
256+
if constexpr (is_yielding) {
257+
return stack::push<meta::unqualified_t<Arg0>>(L, detail::yield_tag, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
258+
}
259+
else {
260+
return stack::push(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
261+
}
262+
}
263+
else {
264+
function_detail::select<is_yielding>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
265+
return 1;
266+
}
267+
}
268+
253269
template <typename Arg0, typename... Args>
254270
static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
255271
if constexpr (std::is_same_v<meta::unqualified_t<Arg0>, detail::yield_tag_t>) {
256-
function_detail::select<true>(L, std::forward<Args>(args)...);
272+
push<true>(L, std::forward<Args>(args)...);
257273
}
258274
else {
259-
function_detail::select<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
275+
push<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
260276
}
261277
return 1;
262278
}
@@ -266,14 +282,24 @@ namespace sol {
266282
struct unqualified_pusher<yielding_t<T>> {
267283
template <typename... Args>
268284
static int push(lua_State* L, const yielding_t<T>& f, Args&&... args) {
269-
function_detail::select<true>(L, f.func, std::forward<Args>(args)...);
270-
return 1;
285+
if constexpr (meta::is_specialization_of_v<meta::unqualified_t<T>, std::function>) {
286+
return stack::push<T>(L, detail::yield_tag, f.func, std::forward<Args>(args)...);
287+
}
288+
else {
289+
function_detail::select<true>(L, f.func, std::forward<Args>(args)...);
290+
return 1;
291+
}
271292
}
272293

273294
template <typename... Args>
274295
static int push(lua_State* L, yielding_t<T>&& f, Args&&... args) {
275-
function_detail::select<true>(L, std::move(f.func), std::forward<Args>(args)...);
276-
return 1;
296+
if constexpr (meta::is_specialization_of_v<meta::unqualified_t<T>, std::function>) {
297+
return stack::push<T>(L, detail::yield_tag, std::move(f.func), std::forward<Args>(args)...);
298+
}
299+
else {
300+
function_detail::select<true>(L, std::move(f.func), std::forward<Args>(args)...);
301+
return 1;
302+
}
277303
}
278304
};
279305

@@ -295,6 +321,22 @@ namespace sol {
295321

296322
template <typename Signature>
297323
struct unqualified_pusher<std::function<Signature>> {
324+
static int push(lua_State* L, detail::yield_tag_t, const std::function<Signature>& fx) {
325+
if (fx) {
326+
function_detail::select<true>(L, fx);
327+
return 1;
328+
}
329+
return stack::push(L, lua_nil);
330+
}
331+
332+
static int push(lua_State* L, detail::yield_tag_t, std::function<Signature>&& fx) {
333+
if (fx) {
334+
function_detail::select<true>(L, std::move(fx));
335+
return 1;
336+
}
337+
return stack::push(L, lua_nil);
338+
}
339+
298340
static int push(lua_State* L, const std::function<Signature>& fx) {
299341
if (fx) {
300342
function_detail::select<false>(L, fx);

single/include/sol/forward.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
// This file was generated with a script.
23-
// Generated 2019-08-28 00:04:12.272016 UTC
24-
// This header was generated with sol v3.0.3 (revision a2e01ad)
23+
// Generated 2019-08-28 04:16:59.509251 UTC
24+
// This header was generated with sol (revision )
2525
// https://github.com/ThePhD/sol2
2626

2727
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP

single/include/sol/sol.hpp

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
// This file was generated with a script.
23-
// Generated 2019-08-28 00:04:08.251517 UTC
24-
// This header was generated with sol v3.0.3 (revision a2e01ad)
23+
// Generated 2019-08-28 04:16:58.879902 UTC
24+
// This header was generated with sol (revision )
2525
// https://github.com/ThePhD/sol2
2626

2727
#ifndef SOL_SINGLE_INCLUDE_HPP
@@ -17860,13 +17860,29 @@ namespace sol {
1786017860
namespace stack {
1786117861
template <typename... Sigs>
1786217862
struct unqualified_pusher<function_sig<Sigs...>> {
17863+
template <bool is_yielding, typename Arg0, typename... Args>
17864+
static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
17865+
if constexpr (meta::is_specialization_of_v<meta::unqualified_t<Arg0>, std::function>) {
17866+
if constexpr (is_yielding) {
17867+
return stack::push<meta::unqualified_t<Arg0>>(L, detail::yield_tag, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
17868+
}
17869+
else {
17870+
return stack::push(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
17871+
}
17872+
}
17873+
else {
17874+
function_detail::select<is_yielding>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
17875+
return 1;
17876+
}
17877+
}
17878+
1786317879
template <typename Arg0, typename... Args>
1786417880
static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
1786517881
if constexpr (std::is_same_v<meta::unqualified_t<Arg0>, detail::yield_tag_t>) {
17866-
function_detail::select<true>(L, std::forward<Args>(args)...);
17882+
push<true>(L, std::forward<Args>(args)...);
1786717883
}
1786817884
else {
17869-
function_detail::select<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
17885+
push<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
1787017886
}
1787117887
return 1;
1787217888
}
@@ -17876,14 +17892,24 @@ namespace sol {
1787617892
struct unqualified_pusher<yielding_t<T>> {
1787717893
template <typename... Args>
1787817894
static int push(lua_State* L, const yielding_t<T>& f, Args&&... args) {
17879-
function_detail::select<true>(L, f.func, std::forward<Args>(args)...);
17880-
return 1;
17895+
if constexpr (meta::is_specialization_of_v<meta::unqualified_t<T>, std::function>) {
17896+
return stack::push<T>(L, detail::yield_tag, f.func, std::forward<Args>(args)...);
17897+
}
17898+
else {
17899+
function_detail::select<true>(L, f.func, std::forward<Args>(args)...);
17900+
return 1;
17901+
}
1788117902
}
1788217903

1788317904
template <typename... Args>
1788417905
static int push(lua_State* L, yielding_t<T>&& f, Args&&... args) {
17885-
function_detail::select<true>(L, std::move(f.func), std::forward<Args>(args)...);
17886-
return 1;
17906+
if constexpr (meta::is_specialization_of_v<meta::unqualified_t<T>, std::function>) {
17907+
return stack::push<T>(L, detail::yield_tag, std::move(f.func), std::forward<Args>(args)...);
17908+
}
17909+
else {
17910+
function_detail::select<true>(L, std::move(f.func), std::forward<Args>(args)...);
17911+
return 1;
17912+
}
1788717913
}
1788817914
};
1788917915

@@ -17905,6 +17931,22 @@ namespace sol {
1790517931

1790617932
template <typename Signature>
1790717933
struct unqualified_pusher<std::function<Signature>> {
17934+
static int push(lua_State* L, detail::yield_tag_t, const std::function<Signature>& fx) {
17935+
if (fx) {
17936+
function_detail::select<true>(L, fx);
17937+
return 1;
17938+
}
17939+
return stack::push(L, lua_nil);
17940+
}
17941+
17942+
static int push(lua_State* L, detail::yield_tag_t, std::function<Signature>&& fx) {
17943+
if (fx) {
17944+
function_detail::select<true>(L, std::move(fx));
17945+
return 1;
17946+
}
17947+
return stack::push(L, lua_nil);
17948+
}
17949+
1790817950
static int push(lua_State* L, const std::function<Signature>& fx) {
1790917951
if (fx) {
1791017952
function_detail::select<false>(L, fx);

tests/runtime_tests/source/functions.std.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ void takefn(std::function<int()> purr) {
4848

4949
TEST_CASE("functions/empty std functions", "std::function is allowed to be empty, so it should be serialized to nil") {
5050
sol::state lua;
51+
lua.open_libraries(sol::lib::base);
5152
std::function<void()> foo = nullptr;
5253
sol::function bar;
5354

@@ -64,8 +65,14 @@ TEST_CASE("functions/empty std functions", "std::function is allowed to be empty
6465
then
6566
Foo()
6667
end
67-
)SCR");
68+
)SCR",
69+
sol::script_pass_on_error);
6870
REQUIRE_FALSE(result.has_value());
71+
72+
sol::optional<sol::error> result0 = lua.safe_script(R"SCR(Foo())SCR", sol::script_pass_on_error);
73+
REQUIRE(result0.has_value());
74+
sol::optional<sol::error> result1 = lua.safe_script(R"SCR(Bar())SCR", sol::script_pass_on_error);
75+
REQUIRE(result1.has_value());
6976
}
7077

7178
TEST_CASE("functions/sol::function to std::function", "check if conversion to std::function works properly and calls with correct arguments") {

0 commit comments

Comments
 (0)