1 #define SOL_ALL_SAFETIES_ON 1
2 #include <sol/sol.hpp>
3 
4 #include <memory>
5 #include <iostream>
6 
7 struct Shape {
8 	virtual ~Shape() = default;
9 };
10 
11 struct Box : Shape { };
12 
13 SOL_BASE_CLASSES(Box, Shape);
14 SOL_DERIVED_CLASSES(Shape, Box);
15 
main()16 int main() {
17 	sol::state lua;
18 	lua.open_libraries(sol::lib::base);
19 
20 	lua.new_usertype<Shape>("Shape", sol::no_constructor);
21 
22 	lua.new_usertype<Box>("Box", sol::factories([&]() {
23 		auto b = std::make_shared<Box>();
24 		std::cout << "create Box@" << std::hex << b.get() << '\n';
25 		return b;
26 	}));
27 
28 	lua.set_function("inspect_shape_table", [](const sol::table& args) {
29 		std::shared_ptr<Shape> defbox = nullptr;
30 		// check if there's a field with the name "shape"
31 		auto s = args.get<sol::optional<std::shared_ptr<Shape>>>("shape");
32 		std::cout << "has   : " << std::boolalpha << s.has_value() << '\n';
33 
34 		// get the field named "shape" or use the default value
35 		std::cout << "get_or: " << std::hex << args.get_or<std::shared_ptr<Shape>>("shape", defbox).get() << '\n';
36 
37 		// this works but I can't test for existence beforehand...
38 		std::cout << "get   : " << std::hex << args.get<std::shared_ptr<Shape>>("shape").get() << '\n';
39 	});
40 
41 	sol::protected_function_result result = lua.safe_script("inspect_shape_table({shape=Box.new()})");
42 	sol_c_assert(result.valid());
43 
44 	return 0;
45 }
46