1 #define SOL_CHECK_ARGUMENTS
2 
3 #include <catch.hpp>
4 #include <sol.hpp>
5 #include <iostream>
6 #include "test_stack_guard.hpp"
7 
makefn()8 std::function<int()> makefn() {
9 	auto fx = []() -> int {
10 		return 0x1456789;
11 	};
12 	return fx;
13 }
14 
15 template <typename T>
va_func(sol::variadic_args va,T first)16 T va_func(sol::variadic_args va, T first) {
17 	T s = 0;
18 	for (auto arg : va) {
19 		T v = arg;
20 		s += v;
21 	}
22 	std::cout << first << std::endl;
23 	std::cout << s << std::endl;
24 
25 	return s;
26 }
27 
takefn(std::function<int ()> purr)28 void takefn(std::function<int()> purr) {
29 	if (purr() != 0x1456789)
30 		throw 0;
31 }
32 
33 struct A {
barkA34 	int a = 0xA; int bark() { return 1; }
35 };
36 
bark(int num_value,A * a)37 std::tuple<int, int> bark(int num_value, A* a) {
38 	return std::tuple<int, int>(num_value * 2, a->bark());
39 }
40 
test_free_func(std::function<void ()> f)41 void test_free_func(std::function<void()> f) {
42 	f();
43 }
44 
test_free_func2(std::function<int (int)> f,int arg1)45 void test_free_func2(std::function<int(int)> f, int arg1) {
46 	int val = f(arg1);
47 	if (val != arg1)
48 		throw sol::error("failed function call!");
49 }
50 
overloaded(int x)51 int overloaded(int x) {
52 	INFO(x);
53 	return 3;
54 }
55 
overloaded(int x,int y)56 int overloaded(int x, int y) {
57 	INFO(x << " " << y);
58 	return 7;
59 }
60 
overloaded(int x,int y,int z)61 int overloaded(int x, int y, int z) {
62 	INFO(x << " " << y << " " << z);
63 	return 11;
64 }
65 
non_overloaded(int x,int y,int z)66 int non_overloaded(int x, int y, int z) {
67 	INFO(x << " " << y << " " << z);
68 	return 13;
69 }
70 
71 namespace sep {
plop_xyz(int x,int y,std::string z)72 	int plop_xyz(int x, int y, std::string z) {
73 		INFO(x << " " << y << " " << z);
74 		return 11;
75 	}
76 }
77 
func_1(int)78 int func_1(int) {
79 	return 1;
80 }
81 
func_1s(std::string a)82 std::string func_1s(std::string a) {
83 	return "string: " + a;
84 }
85 
func_2(int,int)86 int func_2(int, int) {
87 	return 2;
88 }
89 
func_3(int,int,int)90 void func_3(int, int, int) {
91 
92 }
93 
f1(int)94 int f1(int) { return 32; }
f2(int,int)95 int f2(int, int) { return 1; }
96 struct fer {
f3fer97 	double f3(int, int) {
98 		return 2.5;
99 	}
100 };
101 
102 TEST_CASE("functions/tuple-returns", "Make sure tuple returns are ordered properly") {
103 	sol::state lua;
104 	lua.script("function f() return '3', 4 end");
105 
106 	std::tuple<std::string, int> result = lua["f"]();
107 	auto s = std::get<0>(result);
108 	auto v = std::get<1>(result);
109 	REQUIRE(s == "3");
110 	REQUIRE(v == 4);
111 }
112 
113 TEST_CASE("functions/overload-resolution", "Check if overloaded function resolution templates compile/work") {
114 	sol::state lua;
115 	lua.open_libraries(sol::lib::base);
116 
117 	lua.set_function("non_overloaded", non_overloaded);
118 	REQUIRE_NOTHROW(lua.script("x = non_overloaded(1, 2, 3)\nprint(x)"));
119 
120 	/*
121 	// Cannot reasonably support: clang++ refuses to try enough
122 	// deductions to make this work
123 	lua.set_function<int>("overloaded", overloaded);
124 	REQUIRE_NOTHROW(lua.script("print(overloaded(1))"));
125 
126 	lua.set_function<int, int>("overloaded", overloaded);
127 	REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2))"));
128 
129 	lua.set_function<int, int, int>("overloaded", overloaded);
130 	REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2, 3))"));
131 	*/
132 	lua.set_function("overloaded", sol::resolve<int(int)>(overloaded));
133 	REQUIRE_NOTHROW(lua.script("print(overloaded(1))"));
134 
135 	lua.set_function("overloaded", sol::resolve<int(int, int)>(overloaded));
136 	REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2))"));
137 
138 	lua.set_function("overloaded", sol::resolve<int(int, int, int)>(overloaded));
139 	REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2, 3))"));
140 }
141 
142 TEST_CASE("functions/return-order-and-multi-get", "Check if return order is in the same reading order specified in Lua") {
143 	const static std::tuple<int, int, int> triple = std::make_tuple(10, 11, 12);
144 	const static std::tuple<int, float> paired = std::make_tuple(10, 10.f);
145 	sol::state lua;
__anonc3e92e0a0202null146 	lua.set_function("f", [] {
147 		return std::make_tuple(10, 11, 12);
148 	});
149 	int a = 0;
__anonc3e92e0a0302() 150 	lua.set_function("h", []() {
151 		return std::make_tuple(10, 10.0f);
152 	});
153 	lua.script("function g() return 10, 11, 12 end\nx,y,z = g()");
154 	auto tcpp = lua.get<sol::function>("f").call<int, int, int>();
155 	auto tlua = lua.get<sol::function>("g").call<int, int, int>();
156 	auto tcpp2 = lua.get<sol::function>("h").call<int, float>();
157 	auto tluaget = lua.get<int, int, int>("x", "y", "z");
158 	REQUIRE(tcpp == triple);
159 	REQUIRE(tlua == triple);
160 	REQUIRE(tluaget == triple);
161 	REQUIRE(tcpp2 == paired);
162 }
163 
164 TEST_CASE("functions/deducing-return-order-and-multi-get", "Check if return order is in the same reading order specified in Lua, with regular deducing calls") {
165 	const static std::tuple<int, int, int> triple = std::make_tuple(10, 11, 12);
166 	sol::state lua;
__anonc3e92e0a0402() 167 	lua.set_function("f_string", []() { return "this is a string!"; });
168 	sol::function f_string = lua["f_string"];
169 
170 	// Make sure there are no overload collisions / compiler errors for automatic string conversions
171 	std::string f_string_result = f_string();
172 	REQUIRE(f_string_result == "this is a string!");
173 	f_string_result = f_string();
174 	REQUIRE(f_string_result == "this is a string!");
175 
__anonc3e92e0a0502null176 	lua.set_function("f", [] {
177 		return std::make_tuple(10, 11, 12);
178 	});
179 	lua.script("function g() return 10, 11, 12 end\nx,y,z = g()");
180 	std::tuple<int, int, int> tcpp = lua.get<sol::function>("f")();
181 	std::tuple<int, int, int> tlua = lua.get<sol::function>("g")();
182 	std::tuple<int, int, int> tluaget = lua.get<int, int, int>("x", "y", "z");
183 	INFO("cpp: " << std::get<0>(tcpp) << ',' << std::get<1>(tcpp) << ',' << std::get<2>(tcpp));
184 	INFO("lua: " << std::get<0>(tlua) << ',' << std::get<1>(tlua) << ',' << std::get<2>(tlua));
185 	INFO("lua xyz: " << lua.get<int>("x") << ',' << lua.get<int>("y") << ',' << lua.get<int>("z"));
186 	REQUIRE(tcpp == triple);
187 	REQUIRE(tlua == triple);
188 	REQUIRE(tluaget == triple);
189 }
190 
191 TEST_CASE("functions/optional-values", "check if optionals can be passed in to be nil or otherwise") {
192 	struct thing {
193 		int v;
194 	};
195 	sol::state lua;
196 	lua.script(R"( function f (a)
197     return a
198 end )");
199 
200 	sol::function lua_bark = lua["f"];
201 
202 	sol::optional<int> testv = lua_bark(sol::optional<int>(29));
203 	sol::optional<int> testn = lua_bark(sol::nullopt);
204 	REQUIRE((bool)testv);
205 	REQUIRE_FALSE((bool)testn);
206 	REQUIRE(testv.value() == 29);
207 	sol::optional<thing> v = lua_bark(sol::optional<thing>(thing{ 29 }));
208 	REQUIRE_NOTHROW(sol::nil_t n = lua_bark(sol::nullopt));
209 	REQUIRE(v->v == 29);
210 }
211 
212 TEST_CASE("functions/pair-and-tuple-and-proxy-tests", "Check if sol::reference and sol::proxy can be passed to functions as arguments") {
213 	sol::state lua;
214 	lua.new_usertype<A>("A",
215 		"bark", &A::bark);
216 	lua.script(R"( function f (num_value, a)
217     return num_value * 2, a:bark()
218 end
219 function h (num_value, a, b)
220     return num_value * 2, a:bark(), b * 3
221 end
222 nested = { variables = { no = { problem = 10 } } } )");
223 	lua.set_function("g", bark);
224 
225 	sol::function cpp_bark = lua["g"];
226 	sol::function lua_bark = lua["f"];
227 	sol::function lua_bark2 = lua["h"];
228 
229 	sol::reference lua_variable_x = lua["nested"]["variables"]["no"]["problem"];
230 	A cpp_variable_y;
231 
232 	static const std::tuple<int, int> abdesired(20, 1);
233 	static const std::pair<int, int> cddesired = { 20, 1 };
234 	static const std::tuple<int, int, int> abcdesired(20, 1, 3);
235 
236 	std::tuple<int, int> ab = cpp_bark(lua_variable_x, cpp_variable_y);
237 	std::pair<int, int> cd = lua_bark(lua["nested"]["variables"]["no"]["problem"], cpp_variable_y);
238 
239 	REQUIRE(ab == abdesired);
240 	REQUIRE(cd == cddesired);
241 
242 	ab = cpp_bark(std::make_pair(lua_variable_x, cpp_variable_y));
243 	cd = lua_bark(std::make_pair(lua["nested"]["variables"]["no"]["problem"], cpp_variable_y));
244 
245 	REQUIRE(ab == abdesired);
246 	REQUIRE(cd == cddesired);
247 
248 	std::tuple<int, int, int> abc = lua_bark2(std::make_tuple(10, cpp_variable_y), sol::optional<int>(1));
249 	REQUIRE(abc == abcdesired);
250 }
251 
252 TEST_CASE("functions/sol::function-to-std::function", "check if conversion to std::function works properly and calls with correct arguments") {
253 	sol::state lua;
254 	lua.open_libraries(sol::lib::base);
255 
256 	lua.set_function("testFunc", test_free_func);
257 	lua.set_function("testFunc2", test_free_func2);
258 	lua.script(
259 		"testFunc(function() print(\"hello std::function\") end)"
260 	);
261 	REQUIRE_NOTHROW(lua.script(
262 		"function m(a)\n"
263 		"     print(\"hello std::function with arg \", a)\n"
264 		"     return a\n"
265 		"end\n"
266 		"\n"
267 		"testFunc2(m, 1)"
268 	));
269 }
270 
271 TEST_CASE("functions/returning-functions-from-C++-and-gettin-in-lua", "check to see if returning a functor and getting a functor from lua is possible") {
272 	sol::state lua;
273 	lua.open_libraries(sol::lib::base);
274 
275 	lua.set_function("makefn", makefn);
276 	lua.set_function("takefn", takefn);
277 	lua.script("afx = makefn()\n"
278 		"print(afx())\n"
279 		"takefn(afx)\n");
280 }
281 
282 TEST_CASE("functions/function_result-protected_function_result", "Function result should be the beefy return type for sol::function that allows for error checking and error handlers") {
283 	sol::state lua;
284 	lua.open_libraries(sol::lib::base, sol::lib::debug);
285 	static const char unhandlederrormessage[] = "true error message";
286 	static const char handlederrormessage[] = "doodle";
287 	static const std::string handlederrormessage_s = handlederrormessage;
288 
289 	// Some function; just using a lambda to be cheap
__anonc3e92e0a0602() 290 	auto doomfx = []() {
291 		INFO("doomfx called");
292 		throw std::runtime_error(unhandlederrormessage);
293 	};
__anonc3e92e0a0702() 294 	auto luadoomfx = [&lua]() {
295 		INFO("luadoomfx called");
296 		// Does not bypass error function, will call it
297 		luaL_error(lua.lua_state(), unhandlederrormessage);
298 	};
299 	lua.set_function("doom", doomfx);
300 	lua.set_function("luadoom", luadoomfx);
301 
__anonc3e92e0a0802(std::string x) 302 	auto cpphandlerfx = [](std::string x) {
303 		INFO("c++ handler called with: " << x);
304 		return handlederrormessage;
305 	};
306 	lua.set_function("cpphandler", cpphandlerfx);
307 	lua.script(
308 		std::string("function luahandler ( message )")
309 		+ "    print('lua handler called with: ' .. message)"
310 		+ "    return '" + handlederrormessage + "'"
311 		+ "end"
312 	);
__anonc3e92e0a0902(lua_State*) 313 	auto nontrampolinefx = [](lua_State*) -> int { throw "x"; };
314 	lua_CFunction c_nontrampolinefx = nontrampolinefx;
315 	lua.set("nontrampoline", c_nontrampolinefx);
__anonc3e92e0a0a02() 316 	lua.set_function("bark", []() -> int {return 100; });
317 
318 	sol::function luahandler = lua["luahandler"];
319 	sol::function cpphandler = lua["cpphandler"];
320 	sol::protected_function doom(lua["doom"], luahandler);
321 	sol::protected_function luadoom(lua["luadoom"]);
322 	sol::protected_function nontrampoline = lua["nontrampoline"];
323 	sol::protected_function justfine = lua["bark"];
324 	sol::protected_function justfinewithhandler = lua["bark"];
325 	luadoom.error_handler = cpphandler;
326 	nontrampoline.error_handler = cpphandler;
327 	justfinewithhandler.error_handler = luahandler;
328 	bool present = true;
329 	{
330 		sol::protected_function_result result = doom();
331 		REQUIRE_FALSE(result.valid());
332 		sol::optional<sol::error> operr = result;
333 		sol::optional<int> opvalue = result;
334 		present = (bool)operr;
335 		REQUIRE(present);
336 		present = (bool)opvalue;
337 		REQUIRE_FALSE(present);
338 		sol::error err = result;
339 		REQUIRE(err.what() == handlederrormessage_s);
340 	}
341 	{
342 		sol::protected_function_result result = luadoom();
343 		REQUIRE_FALSE(result.valid());
344 		sol::optional<sol::error> operr = result;
345 		sol::optional<int> opvalue = result;
346 		present = (bool)operr;
347 		REQUIRE(present);
348 		present = (bool)opvalue;
349 		REQUIRE_FALSE(present);
350 		sol::error err = result;
351 		REQUIRE(err.what() == handlederrormessage_s);
352 	}
353 	{
354 		sol::protected_function_result result = nontrampoline();
355 		REQUIRE_FALSE(result.valid());
356 		sol::optional<sol::error> operr = result;
357 		sol::optional<int> opvalue = result;
358 		present = (bool)operr;
359 		REQUIRE(present);
360 		present = (bool)opvalue;
361 		REQUIRE_FALSE(present);
362 		sol::error err = result;
363 		REQUIRE(err.what() == handlederrormessage_s);
364 	}
365 	{
366 		sol::protected_function_result result = justfine();
367 		REQUIRE(result.valid());
368 		sol::optional<sol::error> operr = result;
369 		sol::optional<int> opvalue = result;
370 		present = (bool)operr;
371 		REQUIRE_FALSE(present);
372 		present = (bool)opvalue;
373 		REQUIRE(present);
374 		int value = result;
375 		REQUIRE(value == 100);
376 	}
377 	{
378 		sol::protected_function_result result = justfinewithhandler();
379 		REQUIRE(result.valid());
380 		sol::optional<sol::error> operr = result;
381 		sol::optional<int> opvalue = result;
382 		present = (bool)operr;
383 		REQUIRE_FALSE(present);
384 		present = (bool)opvalue;
385 		REQUIRE(present);
386 		int value = result;
387 		REQUIRE(value == 100);
388 	}
389 }
390 
391 TEST_CASE("functions/destructor-tests", "Show that proper copies / destruction happens") {
392 	static int created = 0;
393 	static int destroyed = 0;
394 	static void* last_call = nullptr;
395 	static void* static_call = reinterpret_cast<void*>(0x01);
396 	typedef void(*fptr)();
397 	struct x {
xx398 		x() { ++created; }
xx399 		x(const x&) { ++created; }
xx400 		x(x&&) { ++created; }
operator =x401 		x& operator=(const x&) { return *this; }
operator =x402 		x& operator=(x&&) { return *this; }
funcx403 		void func() { last_call = static_cast<void*>(this); };
~xx404 		~x() { ++destroyed; }
405 	};
406 	struct y {
yy407 		y() { ++created; }
yy408 		y(const x&) { ++created; }
yy409 		y(x&&) { ++created; }
operator =y410 		y& operator=(const x&) { return *this; }
operator =y411 		y& operator=(x&&) { return *this; }
funcy412 		static void func() { last_call = static_call; };
operator ()y413 		void operator()() { func(); }
operator fptry414 		operator fptr () { return func; }
~yy415 		~y() { ++destroyed; }
416 	};
417 
418 	// stateful functors/member functions should always copy unless specified
419 	{
420 		created = 0;
421 		destroyed = 0;
422 		last_call = nullptr;
423 		{
424 			sol::state lua;
425 			x x1;
426 			lua.set_function("x1copy", &x::func, x1);
427 			lua.script("x1copy()");
428 			REQUIRE(created == 2);
429 			REQUIRE(destroyed == 0);
430 			REQUIRE_FALSE(last_call == &x1);
431 
432 			lua.set_function("x1ref", &x::func, std::ref(x1));
433 			lua.script("x1ref()");
434 			REQUIRE(created == 2);
435 			REQUIRE(destroyed == 0);
436 			REQUIRE(last_call == &x1);
437 		}
438 		REQUIRE(created == 2);
439 		REQUIRE(destroyed == 2);
440 	}
441 
442 	// things convertible to a static function should _never_ be forced to make copies
443 	// therefore, pass through untouched
444 	{
445 		created = 0;
446 		destroyed = 0;
447 		last_call = nullptr;
448 		{
449 			sol::state lua;
450 			y y1;
451 			lua.set_function("y1copy", y1);
452 			lua.script("y1copy()");
453 			REQUIRE(created == 1);
454 			REQUIRE(destroyed == 0);
455 			REQUIRE(last_call == static_call);
456 
457 			last_call = nullptr;
458 			lua.set_function("y1ref", std::ref(y1));
459 			lua.script("y1ref()");
460 			REQUIRE(created == 1);
461 			REQUIRE(destroyed == 0);
462 			REQUIRE(last_call == static_call);
463 		}
464 		REQUIRE(created == 1);
465 		REQUIRE(destroyed == 1);
466 	}
467 }
468 
469 
470 TEST_CASE("functions/all-kinds", "Register all kinds of functions, make sure they all compile and work") {
471 	sol::state lua;
472 
473 	struct test_1 {
474 		int a = 0xA;
barktest_1475 		virtual int bark() {
476 			return a;
477 		}
478 
bark_memtest_1479 		int bark_mem() {
480 			return a;
481 		}
482 
x_barktest_1483 		static std::tuple<int, int> x_bark(int num_value, test_1* a) {
484 			return std::tuple<int, int>(num_value * 2, a->a);
485 		}
486 	};
487 
488 	struct test_2 {
489 		int a = 0xC;
barktest_2490 		int bark() {
491 			return 20;
492 		}
493 	};
494 
495 	struct inner {
496 		const int z = 5653;
497 	};
498 
499 	struct nested {
500 		inner i;
501 	};
502 
__anonc3e92e0a0b02() 503 	auto a = []() { return 500; };
__anonc3e92e0a0c02() 504 	auto b = [&]() { return 501; };
__anonc3e92e0a0d02() 505 	auto c = [&]() { return 502; };
__anonc3e92e0a0e02() 506 	auto d = []() { return 503; };
507 
508 	lua.new_usertype<test_1>("test_1",
509 		"bark", sol::c_call<decltype(&test_1::bark_mem), &test_1::bark_mem>
510 		);
511 	lua.new_usertype<test_2>("test_2",
512 		"bark", sol::c_call<decltype(&test_2::bark), &test_2::bark>
513 		);
514 	test_2 t2;
515 
516 	lua.set_function("a", a);
517 	lua.set_function("b", b);
518 	lua.set_function("c", std::ref(c));
519 	lua.set_function("d", std::ref(d));
520 	lua.set_function("f", &test_1::bark);
521 	lua.set_function("g", test_1::x_bark);
522 	lua.set_function("h", sol::c_call<decltype(&test_1::bark_mem), &test_1::bark_mem>);
523 	lua.set_function("i", &test_2::bark, test_2());
524 	lua.set_function("j", &test_2::a, test_2());
525 	lua.set_function("k", &test_2::a);
526 	lua.set_function("l", sol::c_call<decltype(&test_1::a), &test_1::a>);
527 	lua.set_function("m", &test_2::a, &t2);
528 	lua.set_function("n", sol::c_call<decltype(&non_overloaded), &non_overloaded>);
529 
530 	lua.script(R"(
531 o1 = test_1.new()
532 o2 = test_2.new()
533 )");
534 
535 	lua.script(R"(
536 ob = o1:bark()
537 
538 A = a()
539 B = b()
540 C = c()
541 D = d()
542 F = f(o1)
543 G0, G1 = g(2, o1)
544 H = h(o1)
545 I = i(o1)
546 I = i(o1)
547 )");
548 
549 
550 	lua.script(R"(
551 J0 = j()
552 j(24)
553 J1 = j()
554     )");
555 
556 	lua.script(R"(
557 K0 = k(o2)
558 k(o2, 1024)
559 K1 = k(o2)
560     )");
561 
562 	lua.script(R"(
563 L0 = l(o1)
564 l(o1, 678)
565 L1 = l(o1)
566     )");
567 
568 
569 	lua.script(R"(
570 M0 = m()
571 m(256)
572 M1 = m()
573     )");
574 
575 	lua.script(R"(
576 N = n(1, 2, 3)
577     )");
578 	int ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N;
579 	std::tie(ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N)
580 		= lua.get<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>(
581 			"ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N"
582 			);
583 
584 	REQUIRE(ob == 0xA);
585 
586 	REQUIRE(A == 500);
587 	REQUIRE(B == 501);
588 	REQUIRE(C == 502);
589 	REQUIRE(D == 503);
590 
591 	REQUIRE(F == 0xA);
592 	REQUIRE(G0 == 4);
593 	REQUIRE(G1 == 0xA);
594 	REQUIRE(H == 0xA);
595 	REQUIRE(I == 20);
596 
597 	REQUIRE(J0 == 0xC);
598 	REQUIRE(J1 == 24);
599 
600 	REQUIRE(K0 == 0xC);
601 	REQUIRE(K1 == 1024);
602 
603 	REQUIRE(L0 == 0xA);
604 	REQUIRE(L1 == 678);
605 
606 	REQUIRE(M0 == 0xC);
607 	REQUIRE(M1 == 256);
608 
609 	REQUIRE(N == 13);
610 
611 	sol::tie(ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N)
612 		= lua.get<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>(
613 			"ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N"
614 			);
615 
616 	REQUIRE(ob == 0xA);
617 
618 	REQUIRE(A == 500);
619 	REQUIRE(B == 501);
620 	REQUIRE(C == 502);
621 	REQUIRE(D == 503);
622 
623 	REQUIRE(F == 0xA);
624 	REQUIRE(G0 == 4);
625 	REQUIRE(G1 == 0xA);
626 	REQUIRE(H == 0xA);
627 	REQUIRE(I == 20);
628 
629 	REQUIRE(J0 == 0xC);
630 	REQUIRE(J1 == 24);
631 
632 	REQUIRE(K0 == 0xC);
633 	REQUIRE(K1 == 1024);
634 
635 	REQUIRE(L0 == 0xA);
636 	REQUIRE(L1 == 678);
637 
638 	REQUIRE(M0 == 0xC);
639 	REQUIRE(M1 == 256);
640 
641 	REQUIRE(N == 13);
642 
643 	// Work that compiler, WORK IT!
644 	lua.set("o", &test_1::bark);
645 	lua.set("p", test_1::x_bark);
646 	lua.set("q", sol::c_call<decltype(&test_1::bark_mem), &test_1::bark_mem>);
647 	lua.set("r", &test_2::a);
648 	lua.set("s", sol::readonly(&test_2::a));
649 	lua.set_function("t", sol::readonly(&test_2::a), test_2());
650 	lua.set_function("u", &nested::i, nested());
651 	lua.set("v", &nested::i);
652 	lua.set("nested", nested());
653 	lua.set("inner", inner());
654 	REQUIRE_THROWS(lua.script("s(o2, 2)"));
655 	REQUIRE_THROWS(lua.script("t(2)"));
656 	REQUIRE_THROWS(lua.script("u(inner)"));
657 	REQUIRE_THROWS(lua.script("v(nested, inner)"));
658 }
659 
660 TEST_CASE("simple/call-with-parameters", "Lua function is called with a few parameters from C++") {
661 	sol::state lua;
662 
663 	REQUIRE_NOTHROW(lua.script("function my_add(i, j, k) return i + j + k end"));
664 	auto f = lua.get<sol::function>("my_add");
665 	REQUIRE_NOTHROW(lua.script("function my_nothing(i, j, k) end"));
666 	auto fvoid = lua.get<sol::function>("my_nothing");
667 	int a;
668 	REQUIRE_NOTHROW(fvoid(1, 2, 3));
669 	REQUIRE_NOTHROW(a = f.call<int>(1, 2, 3));
670 	REQUIRE(a == 6);
671 	REQUIRE_THROWS(a = f(1, 2, "arf"));
672 }
673 
674 TEST_CASE("simple/call-c++-function", "C++ function is called from lua") {
675 	sol::state lua;
676 
677 	lua.set_function("plop_xyz", sep::plop_xyz);
678 	lua.script("x = plop_xyz(2, 6, 'hello')");
679 
680 	REQUIRE(lua.get<int>("x") == 11);
681 }
682 
683 TEST_CASE("simple/call-lambda", "A C++ lambda is exposed to lua and called") {
684 	sol::state lua;
685 
686 	int a = 0;
687 
__anonc3e92e0a0f02null688 	lua.set_function("foo", [&a] { a = 1; });
689 
690 	lua.script("foo()");
691 
692 	REQUIRE(a == 1);
693 }
694 
695 TEST_CASE("advanced/get-and-call", "Checks for lambdas returning values after a get operation") {
696 	const static std::string lol = "lol", str = "str";
697 	const static std::tuple<int, float, double, std::string> heh_tuple = std::make_tuple(1, 6.28f, 3.14, std::string("heh"));
698 	sol::state lua;
699 
__anonc3e92e0a1002null700 	REQUIRE_NOTHROW(lua.set_function("a", [] { return 42; }));
701 	REQUIRE(lua.get<sol::function>("a").call<int>() == 42);
702 
__anonc3e92e0a1102null703 	REQUIRE_NOTHROW(lua.set_function("b", [] { return 42u; }));
704 	REQUIRE(lua.get<sol::function>("b").call<unsigned int>() == 42u);
705 
__anonc3e92e0a1202null706 	REQUIRE_NOTHROW(lua.set_function("c", [] { return 3.14; }));
707 	REQUIRE(lua.get<sol::function>("c").call<double>() == 3.14);
708 
__anonc3e92e0a1302null709 	REQUIRE_NOTHROW(lua.set_function("d", [] { return 6.28f; }));
710 	REQUIRE(lua.get<sol::function>("d").call<float>() == 6.28f);
711 
__anonc3e92e0a1402null712 	REQUIRE_NOTHROW(lua.set_function("e", [] { return "lol"; }));
713 	REQUIRE(lua.get<sol::function>("e").call<std::string>() == lol);
714 
__anonc3e92e0a1502null715 	REQUIRE_NOTHROW(lua.set_function("f", [] { return true; }));
716 	REQUIRE(lua.get<sol::function>("f").call<bool>());
717 
__anonc3e92e0a1602null718 	REQUIRE_NOTHROW(lua.set_function("g", [] { return std::string("str"); }));
719 	REQUIRE(lua.get<sol::function>("g").call<std::string>() == str);
720 
__anonc3e92e0a1702null721 	REQUIRE_NOTHROW(lua.set_function("h", [] {}));
722 	REQUIRE_NOTHROW(lua.get<sol::function>("h").call());
723 
__anonc3e92e0a1802null724 	REQUIRE_NOTHROW(lua.set_function("i", [] { return sol::nil; }));
725 	REQUIRE(lua.get<sol::function>("i").call<sol::nil_t>() == sol::nil);
__anonc3e92e0a1902null726 	REQUIRE_NOTHROW(lua.set_function("j", [] { return std::make_tuple(1, 6.28f, 3.14, std::string("heh")); }));
727 	REQUIRE((lua.get<sol::function>("j").call<int, float, double, std::string>() == heh_tuple));
728 }
729 
730 TEST_CASE("advanced/operator[]-call", "Checks for lambdas returning values using operator[]") {
731 	const static std::string lol = "lol", str = "str";
732 	const static std::tuple<int, float, double, std::string> heh_tuple = std::make_tuple(1, 6.28f, 3.14, std::string("heh"));
733 	sol::state lua;
734 
__anonc3e92e0a1a02null735 	REQUIRE_NOTHROW(lua.set_function("a", [] { return 42; }));
736 	REQUIRE(lua["a"].call<int>() == 42);
737 
__anonc3e92e0a1b02null738 	REQUIRE_NOTHROW(lua.set_function("b", [] { return 42u; }));
739 	REQUIRE(lua["b"].call<unsigned int>() == 42u);
740 
__anonc3e92e0a1c02null741 	REQUIRE_NOTHROW(lua.set_function("c", [] { return 3.14; }));
742 	REQUIRE(lua["c"].call<double>() == 3.14);
743 
__anonc3e92e0a1d02null744 	REQUIRE_NOTHROW(lua.set_function("d", [] { return 6.28f; }));
745 	REQUIRE(lua["d"].call<float>() == 6.28f);
746 
__anonc3e92e0a1e02null747 	REQUIRE_NOTHROW(lua.set_function("e", [] { return "lol"; }));
748 	REQUIRE(lua["e"].call<std::string>() == lol);
749 
__anonc3e92e0a1f02null750 	REQUIRE_NOTHROW(lua.set_function("f", [] { return true; }));
751 	REQUIRE(lua["f"].call<bool>());
752 
__anonc3e92e0a2002null753 	REQUIRE_NOTHROW(lua.set_function("g", [] { return std::string("str"); }));
754 	REQUIRE(lua["g"].call<std::string>() == str);
755 
__anonc3e92e0a2102null756 	REQUIRE_NOTHROW(lua.set_function("h", [] {}));
757 	REQUIRE_NOTHROW(lua["h"].call());
758 
__anonc3e92e0a2202null759 	REQUIRE_NOTHROW(lua.set_function("i", [] { return sol::nil; }));
760 	REQUIRE(lua["i"].call<sol::nil_t>() == sol::nil);
__anonc3e92e0a2302null761 	REQUIRE_NOTHROW(lua.set_function("j", [] { return std::make_tuple(1, 6.28f, 3.14, std::string("heh")); }));
762 	REQUIRE((lua["j"].call<int, float, double, std::string>() == heh_tuple));
763 }
764 
765 TEST_CASE("advanced/call-lambdas", "A C++ lambda is exposed to lua and called") {
766 	sol::state lua;
767 
768 	int x = 0;
__anonc3e92e0a2402(int new_x) 769 	lua.set_function("set_x", [&](int new_x) {
770 		x = new_x;
771 		return 0;
772 	});
773 
774 	lua.script("set_x(9)");
775 	REQUIRE(x == 9);
776 }
777 
778 TEST_CASE("advanced/call-referenced_obj", "A C++ object is passed by pointer/reference_wrapper to lua and invoked") {
779 	sol::state lua;
780 
781 	int x = 0;
__anonc3e92e0a2502(int new_x) 782 	auto objx = [&](int new_x) {
783 		x = new_x;
784 		return 0;
785 	};
786 	lua.set_function("set_x", std::ref(objx));
787 
788 	int y = 0;
__anonc3e92e0a2602(int new_y) 789 	auto objy = [&](int new_y) {
790 		y = new_y;
791 		return std::tuple<int, int>(0, 0);
792 	};
793 	lua.set_function("set_y", &decltype(objy)::operator(), std::ref(objy));
794 
795 	lua.script("set_x(9)");
796 	lua.script("set_y(9)");
797 	REQUIRE(x == 9);
798 	REQUIRE(y == 9);
799 }
800 
801 TEST_CASE("functions/tie", "make sure advanced syntax with 'tie' works") {
802 	sol::state lua;
803 
804 	lua.script(R"(function f ()
805     return 1, 2, 3
806 end)");
807 	sol::function f = lua["f"];
808 
809 	int a, b, c;
810 	sol::tie(a, b, c) = f();
811 	REQUIRE(a == 1);
812 	REQUIRE(b == 2);
813 	REQUIRE(c == 3);
814 }
815 
816 TEST_CASE("functions/variadic_args", "Check to see we can receive multiple arguments through a variadic") {
817 	struct structure {
818 		int x;
819 		bool b;
820 	};
821 
822 	sol::state lua;
823 	lua.open_libraries(sol::lib::base);
__anonc3e92e0a2702(sol::this_state, sol::variadic_args va) 824 	lua.set_function("v", [](sol::this_state, sol::variadic_args va) -> structure {
825 		int r = 0;
826 		for (auto v : va) {
827 			int value = v;
828 			r += value;
829 		}
830 		return{ r, r > 200 };
831 	});
832 
833 	lua.script("x = v(25, 25)");
834 	lua.script("x2 = v(25, 25, 100, 50, 250, 150)");
835 	lua.script("x3 = v(1, 2, 3, 4, 5, 6)");
836 
837 	structure& lx = lua["x"];
838 	structure& lx2 = lua["x2"];
839 	structure& lx3 = lua["x3"];
840 	REQUIRE(lx.x == 50);
841 	REQUIRE(lx2.x == 600);
842 	REQUIRE(lx3.x == 21);
843 	REQUIRE_FALSE(lx.b);
844 	REQUIRE(lx2.b);
845 	REQUIRE_FALSE(lx3.b);
846 }
847 
848 TEST_CASE("functions/required_and_variadic_args", "Check if a certain number of arguments can still be required even when using variadic_args") {
849 	sol::state lua;
850 	lua.set_function("v",
__anonc3e92e0a2802(sol::this_state, sol::variadic_args, int, int) 851 		[](sol::this_state, sol::variadic_args, int, int) {
852 		}
853 	);
854 	REQUIRE_NOTHROW(lua.script("v(20, 25, 30)"));
855 	REQUIRE_NOTHROW(lua.script("v(20, 25)"));
856 #ifndef SOL_LUAJIT
857 	REQUIRE_THROWS(lua.script("v(20)"));
858 #endif // LuaJIT has problems with exceptions, as fucking usual
859 }
860 
861 TEST_CASE("functions/overloading", "Check if overloading works properly for regular set function syntax") {
862 	sol::state lua;
863 	lua.open_libraries(sol::lib::base);
864 
865 	lua.set_function("func_1", func_1);
866 	lua.set_function("func", sol::overload(func_2, func_3, func_1, func_1s));
867 
868 	const std::string string_bark = "string: bark";
869 
870 	REQUIRE_NOTHROW(lua.script(
871 		"a = func(1)\n"
872 		"b = func('bark')\n"
873 		"c = func(1,2)\n"
874 		"func(1,2,3)\n"
875 	));
876 
877 	REQUIRE((lua["a"] == 1));
878 	REQUIRE((lua["b"] == string_bark));
879 	REQUIRE((lua["c"] == 2));
880 
881 	REQUIRE_THROWS(lua.script("func(1,2,'meow')"));
882 }
883 
884 TEST_CASE("overloading/c_call", "Make sure that overloading works with c_call functionality") {
885 	sol::state lua;
886 	lua.set("f", sol::c_call<sol::wrap<decltype(&f1), &f1>, sol::wrap<decltype(&f2), &f2>, sol::wrap<decltype(&fer::f3), &fer::f3>>);
887 	lua.set("g", sol::c_call<sol::wrap<decltype(&f1), &f1>>);
888 	lua.set("h", sol::c_call<decltype(&f2), &f2>);
889 	lua.set("obj", fer());
890 
891 	lua.script("r1 = f(1)");
892 	lua.script("r2 = f(1, 2)");
893 	lua.script("r3 = f(obj, 1, 2)");
894 	lua.script("r4 = g(1)");
895 	lua.script("r5 = h(1, 2)");
896 
897 	int r1 = lua["r1"];
898 	int r2 = lua["r2"];
899 	double r3 = lua["r3"];
900 	int r4 = lua["r4"];
901 	int r5 = lua["r5"];
902 
903 	REQUIRE(r1 == 32);
904 	REQUIRE(r2 == 1);
905 	REQUIRE(r3 == 2.5);
906 	REQUIRE(r4 == 32);
907 	REQUIRE(r5 == 1);
908 }
909 
910 TEST_CASE("functions/stack-protect", "make sure functions don't impede on the stack") {
911 	//setup sol/lua
912 	sol::state lua;
913 	lua.open_libraries(sol::lib::base, sol::lib::string);
914 
915 	lua.script("function ErrorHandler(msg) print('Lua created error msg : ' ..  msg) return msg end");
916 	lua.script("function stringtest(a) if a == nil then error('fuck') end print('Lua recieved content : ' .. a) return a end");
917 
918 	// test normal function
919 	{
920 		sol::stack_guard normalsg(lua);
921 		std::string str = lua["stringtest"]("normal test");
922 		INFO("Back in C++, direct call result is : " << str);
923 	}
924 
925 	//test protected_function
926 	sol::protected_function Stringtest(lua["stringtest"]);
927 	Stringtest.error_handler = lua["ErrorHandler"];
928 	sol::stack_guard sg(lua);
929 	{
930 		sol::protected_function_result stringresult = Stringtest("protected test");
931 		REQUIRE(stringresult.valid());
932 		std::string s = stringresult;
933 		INFO("Back in C++, protected result is : " << s);
934 	}
935 	REQUIRE(sg.check_stack());
936 
937 	//test optional
938 	{
939 		sol::stack_guard opsg(lua);
940 		sol::optional<std::string> opt_result = Stringtest("optional test");
941 		REQUIRE(opsg.check_stack());
942 		if (opt_result)
943 		{
944 			std::string s = opt_result.value();
945 			INFO("Back in C++, opt_result is : " << s);
946 		}
947 		else
948 		{
949 			INFO("opt_result failed");
950 		}
951 	}
952 	REQUIRE(sg.check_stack());
953 
954 	{
955 		sol::protected_function_result errresult = Stringtest(sol::nil);
956 		REQUIRE_FALSE(errresult.valid());
957 		sol::error err = errresult;
958 		std::string msg = err.what();
959 		INFO("error :" << msg);
960 	}
961 	REQUIRE(sg.check_stack());
962 }
963 
964 TEST_CASE("functions/same-type-closures", "make sure destructions are per-object, not per-type, by destroying one type multiple times") {
965 	static std::set<void*> last_my_closures;
966 	static bool checking_closures = false;
967 	static bool check_failed = false;
968 
969 	struct my_closure {
970 		int& n;
971 
my_closuremy_closure972 		my_closure(int& n) : n(n) {}
~my_closuremy_closure973 		~my_closure() noexcept(false) {
974 			if (!checking_closures)
975 				return;
976 			void* addr = static_cast<void*>(this);
977 			auto f = last_my_closures.find(addr);
978 			if (f != last_my_closures.cend()) {
979 				check_failed = true;
980 			}
981 			last_my_closures.insert(f, addr);
982 		}
983 
operator ()my_closure984 		int operator() () {
985 			++n; return n;
986 		}
987 	};
988 
989 	int n = 250;
990 	my_closure a(n);
991 	my_closure b(n);
992 	{
993 		sol::state lua;
994 
995 		lua.set_function("f", a);
996 		lua.set_function("g", b);
997 		checking_closures = true;
998 	}
999 	REQUIRE_FALSE(check_failed);
1000 	REQUIRE(last_my_closures.size() == 2);
1001 }
1002 
1003 TEST_CASE("functions/stack-multi-return", "Make sure the stack is protected after multi-returns") {
1004 	sol::state lua;
1005 	lua.script("function f () return 1, 2, 3, 4, 5 end");
1006 
1007 	{
1008 		sol::stack_guard sg(lua);
1009 		sol::stack::push(lua, double(256.78));
1010 		{
1011 			int a, b, c, d, e;
1012 			sol::stack_guard sg2(lua);
1013 			sol::function f = lua["f"];
1014 			sol::tie(a, b, c, d, e) = f();
1015 			REQUIRE(a == 1);
1016 			REQUIRE(b == 2);
1017 			REQUIRE(c == 3);
1018 			REQUIRE(d == 4);
1019 			REQUIRE(e == 5);
1020 		}
1021 		double f = sol::stack::pop<double>(lua);
1022 		REQUIRE(f == 256.78);
1023 	}
1024 }
1025 
1026 TEST_CASE("functions/protected-stack-multi-return", "Make sure the stack is protected after multi-returns") {
1027 	sol::state lua;
1028 	lua.script("function f () return 1, 2, 3, 4, 5 end");
1029 
1030 	{
1031 		sol::stack_guard sg(lua);
1032 		sol::stack::push(lua, double(256.78));
1033 		{
1034 			int a, b, c, d, e;
1035 			sol::stack_guard sg2(lua);
1036 			sol::protected_function pf = lua["f"];
1037 			sol::tie(a, b, c, d, e) = pf();
1038 			REQUIRE(a == 1);
1039 			REQUIRE(b == 2);
1040 			REQUIRE(c == 3);
1041 			REQUIRE(d == 4);
1042 			REQUIRE(e == 5);
1043 		}
1044 		double f = sol::stack::pop<double>(lua);
1045 		REQUIRE(f == 256.78);
1046 	}
1047 }
1048 
1049 TEST_CASE("functions/overloaded-variadic", "make sure variadics work to some degree with overloading") {
1050 	sol::state lua;
1051 	lua.open_libraries();
1052 
1053 	sol::table ssl = lua.create_named_table("ssl");
1054 	ssl.set_function("test", sol::overload(&va_func<int>, &va_func<double>));
1055 
1056 	lua.script("a = ssl.test(1, 2, 3)");
1057 	lua.script("b = ssl.test(1, 2)");
1058 	lua.script("c = ssl.test(2.2)");
1059 
1060 	int a = lua["a"];
1061 	int b = lua["b"];
1062 	double c = lua["c"];
1063 	REQUIRE(a == 6);
1064 	REQUIRE(b == 3);
1065 	REQUIRE(c == 2.2);
1066 }
1067