From 7e281bd2ef8880668530aa91936f95137f646885 Mon Sep 17 00:00:00 2001 From: Bartek Banachewicz Date: Sat, 20 Jul 2013 01:52:25 +0200 Subject: [PATCH 1/5] backing up my work --- lundi.hpp | 48 +++++++++++++++++++++++++-- test.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 138 insertions(+), 7 deletions(-) diff --git a/lundi.hpp b/lundi.hpp index f402c4a..b2a1a65 100644 --- a/lundi.hpp +++ b/lundi.hpp @@ -40,19 +40,60 @@ class function_wrapper { virtual ~function_wrapper() {}; }; +std::string get_type_name(int lua_type_name) { + switch (lua_type_name) { + case LUA_TNUMBER: return "number"; + case LUA_TBOOLEAN: return "bool"; + case LUA_TSTRING: return "string"; + case LUA_TNIL: return "nil"; + case LUA_TUSERDATA: return "userdata"; + case LUA_TTHREAD: return "thread"; + case LUA_TLIGHTUSERDATA: return "lightuserdata"; + case LUA_TTABLE: return "table"; + case LUA_TFUNCTION: return "function"; + default: return "unknown-type"; + } +} + struct fetch_parameter { lua_State *state; fetch_parameter(lua_State *s) : state(s) {} + // that function is complementary to peek + // the main difference is that it knows what to expect + + // the template version is more flexible, but produces no error message + /*template + void operator()(T&) const { + static_assert(false, "This type can't be used in function signature."); + }*/ + + // TODO : add error reporting to that + // it has to utilize userdata stored in state somehow + void operator()(std::string& t) const { t = lua_tostring(state, -1); lua_pop(state, 1); } void operator()(int& t) const { + t = lua_tointeger(state, -1); + lua_pop(state, 1); + } + + void operator()(double& t) const { t = lua_tonumber(state, -1); lua_pop(state, 1); } + + void operator()(bool& t) const { + t = static_cast(lua_toboolean(state, -1)); + lua_pop(state, 1); + } + + void operator()(lua::nil&) const { + lua_pop(state, 1); + } }; template @@ -129,6 +170,10 @@ char const *stream_name(StreamT &stream) { class state { lua_State *state_; std::function error_func_; + void report_error(std::string const& error_message) { + if (error_func_) + error_func_(error_message); + } variant peek(int index) { switch(lua_type(state_, index)) { @@ -163,8 +208,7 @@ class state { error_msg = std::string(lua_tostring(state_, -1)); lua_pop(state_, -1); // remove error message } - if (error_func_) - error_func_(error_msg); + report_error(error_msg); } } diff --git a/test.cpp b/test.cpp index ffe043b..7abf7c2 100644 --- a/test.cpp +++ b/test.cpp @@ -3,6 +3,11 @@ #include #include +#include +#include +#include +#include + #include "lundi.hpp" #define CATCH_CONFIG_MAIN @@ -10,10 +15,51 @@ namespace { -int plop_xyz(int x, int y, std::string z) { - std::cout << x << " " << y << " " << z << std::endl; - return 11; -} + typedef boost::mpl::vector basic_types; + //typedef boost::mpl::vector basic_types; + + namespace c_funs { + + // left for historical purposes + int plop_xyz(int x, int y, std::string z) { + std::cout << x << " " << y << " " << z << std::endl; + return 11; + } + + // the naming pattern goes: + // {return_type}_{number_of_args} + + // basic empty functions + namespace basic { + template + void void_unary(A a) { } + template + void void_binary_same(A a, A b) { } + template + void void_binary_diff(A a, B b) { } + + // function without parameters + template + Ret nonparam() { return Ret{}; } + + // functions returning nonparameter + template + A same_unary(A a) { return a; } + template + A same_binary_same(A a, A b) { return a; } + template + A first_binary_diff(A a, B b) { return a; } + template + B second_binary_diff(A a, B b) { return b; } + } + + // functions with aggregates + /*namespace aggregate{ + template + void void_unary(Aggr a) { } + // TODO add more + }*/ + } // equivalent of Boost.Variant operator== template @@ -32,6 +78,47 @@ void exceptionErrorReporter(std::string const& s) { } +template +struct calls { + lua::state& state; + F& f; + + calls(lua::state& state, F& f) : state(state), f(f) {} + + template + void operator() (Sig...) { + state.register_function("foo", f); + } +}; + +struct void_calls { + void_calls(lua::state& state) : state(state) {} + lua::state& state; + + template + void operator() (A) { + state.register_function("foo", c_funs::basic::void_unary); + state.register_function("foo", c_funs::basic::void_binary_same); + } +}; + +TEST_CASE( "coverage/void_call", "Check if basic calls in form of void(T) compile.") { + lua::state lua (&exceptionErrorReporter); + namespace mpl = boost::mpl; + + mpl::for_each(void_calls(lua)); + + //lua.register_function("foo", c_funs::basic::void_unary); + + // that will work for functors. + //mpl::for_each(calls(lua, c_funs::basic::void_unary)); +} + +TEST_CASE(" coverage/lambda_call", "Check if basic calls in form of void (T) compile.") { + lua::state lua(&exceptionErrorReporter); + +} + TEST_CASE( "simple/set_global", "Check if the set_global works properly." ) { lua::state lua(&exceptionErrorReporter); @@ -118,7 +205,7 @@ TEST_CASE( "simple/callWithParameters", "Lua function is called with a few param TEST_CASE( "simple/callCppFunction", "Desc" ) { lua::state lua(&exceptionErrorReporter); - lua.register_function("plop_xyz", plop_xyz); + lua.register_function("plop_xyz", c_funs::plop_xyz); lua.eval("x = plop_xyz(2, 6, 'hello')"); std::cout << lua.get_global("x") << std::endl; From 9bb5815e55e8dfdc6ef6f7d4f86bef52519da6dc Mon Sep 17 00:00:00 2001 From: Bartek Banachewicz Date: Sat, 20 Jul 2013 01:57:24 +0200 Subject: [PATCH 2/5] Added a few more tests. --- test.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/test.cpp b/test.cpp index 7abf7c2..b7dd8da 100644 --- a/test.cpp +++ b/test.cpp @@ -102,7 +102,7 @@ struct void_calls { } }; -TEST_CASE( "coverage/void_call", "Check if basic calls in form of void(T) compile.") { +TEST_CASE( "coverage/void_call", "Check if basic calls in form of void(T) compile." ) { lua::state lua (&exceptionErrorReporter); namespace mpl = boost::mpl; @@ -114,9 +114,28 @@ TEST_CASE( "coverage/void_call", "Check if basic calls in form of void(T) compil //mpl::for_each(calls(lua, c_funs::basic::void_unary)); } -TEST_CASE(" coverage/lambda_call", "Check if basic calls in form of void (T) compile.") { +TEST_CASE( "coverage/void_lambda_call", "Check if basic calls in form of void (T) compile." ) { lua::state lua(&exceptionErrorReporter); + lua.register_function("foo", [](int){}); + lua.register_function("foo", [](lua::nil){}); + lua.register_function("foo", [](std::string){}); + lua.register_function("foo", [](double){}); + lua.register_function("foo", [](bool){}); +} + +TEST_CASE("coverage/type_lambda_call", "Check if basic calls in form of void (T) compile.") { + lua::state lua(&exceptionErrorReporter); + + lua.register_function("foo", [](int){ return int {}; }); + lua.register_function("foo", [](lua::nil){ return lua::nil {}; }); + lua.register_function("foo", [](std::string){ return std::string {}; }); + lua.register_function("foo", [](double){ return double {}; }); + lua.register_function("foo", [](bool){ return bool {}; }); +} + +TEST_CASE("coverage/functor_call", "Check if basic calls in form of void (T) compile.") { + } TEST_CASE( "simple/set_global", "Check if the set_global works properly." ) { From 92ecf932294ae7bc05152bcba8abc8a9954509e1 Mon Sep 17 00:00:00 2001 From: Bartek Banachewicz Date: Sat, 20 Jul 2013 16:01:05 +0200 Subject: [PATCH 3/5] Added more tests and changed them from Boost.MPL to Boost.PP --- lundi.hpp | 2 +- test.cpp | 125 +++++++++++++++++++++++------------------------------- 2 files changed, 53 insertions(+), 74 deletions(-) diff --git a/lundi.hpp b/lundi.hpp index d2f1e31..4ae5989 100644 --- a/lundi.hpp +++ b/lundi.hpp @@ -92,7 +92,7 @@ struct fetch_parameter { lua_pop(state, 1); } - void operator()(lua::nil&) const { + void operator()(lua::nil_type&) const { lua_pop(state, 1); } }; diff --git a/test.cpp b/test.cpp index 1ee82d3..67bf88b 100644 --- a/test.cpp +++ b/test.cpp @@ -3,10 +3,8 @@ #include #include -#include -#include -#include -#include +#include +#include #include "lundi.hpp" @@ -14,10 +12,6 @@ #include namespace { - - typedef boost::mpl::vector basic_types; - //typedef boost::mpl::vector basic_types; - namespace c_funs { // left for historical purposes @@ -34,9 +28,9 @@ namespace { template void void_unary(A a) { } template - void void_binary_same(A a, A b) { } - template - void void_binary_diff(A a, B b) { } + void void_binary_first(A a, int) { } + template + void void_binary_second(int, B b) { } // function without parameters template @@ -46,92 +40,77 @@ namespace { template A same_unary(A a) { return a; } template - A same_binary_same(A a, A b) { return a; } - template - A first_binary_diff(A a, B b) { return a; } - template - B second_binary_diff(A a, B b) { return b; } + A first_binary_first(A a, int) { return a; } + template + B second_binary_second(int, B b) { return b; } } // functions with aggregates /*namespace aggregate{ - template - void void_unary(Aggr a) { } - // TODO add more + template + void void_unary(Aggr a) { } + // TODO add more }*/ } -// equivalent of Boost.Variant operator== -template -inline bool equals(V const& variant, T const& value){ - return boost::get(variant) && boost::get(variant) == value; -} - -//[](std::string const& s) { std::cerr << "Lua ERROR : " << s << std::endl; } -void defaultErrorReporter(std::string const& s) { - std::cerr << "Lua ERROR : " << s << std::endl; -} - -void exceptionErrorReporter(std::string const& s) { - throw lua::exception(s); -} - -} - -template -struct calls { - lua::state& state; - F& f; + // equivalent of Boost.Variant operator== + template + inline bool equals(V const& variant, T const& value){ + return boost::get(variant) && boost::get(variant) == value; + } - calls(lua::state& state, F& f) : state(state), f(f) {} + //[](std::string const& s) { std::cerr << "Lua ERROR : " << s << std::endl; } + void defaultErrorReporter(std::string const& s) { + std::cerr << "Lua ERROR : " << s << std::endl; + } - template - void operator() (Sig...) { - state.register_function("foo", f); + void exceptionErrorReporter(std::string const& s) { + throw lua::exception(s); } -}; -struct void_calls { - void_calls(lua::state& state) : state(state) {} - lua::state& state; +} - template - void operator() (A) { - state.register_function("foo", c_funs::basic::void_unary); - state.register_function("foo", c_funs::basic::void_binary_same); - } -}; +#define BASIC_TYPES (int)(double)(bool)(std::string)(lua::nil_type) -TEST_CASE( "coverage/void_call", "Check if basic calls in form of void(T) compile." ) { +TEST_CASE( "coverage/register_void_return", "Check if basic calls in form of void(T) compile." ) { lua::state lua (&exceptionErrorReporter); - namespace mpl = boost::mpl; - mpl::for_each(void_calls(lua)); + #define MACRO(r, data, elem) \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::void_unary)); \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::void_binary_first)); \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::void_binary_second)); + BOOST_PP_SEQ_FOR_EACH(MACRO, _, BASIC_TYPES) + #undef MACRO +} - //lua.register_function("foo", c_funs::basic::void_unary); - - // that will work for functors. - //mpl::for_each(calls(lua, c_funs::basic::void_unary)); +TEST_CASE(" coverage/register_nonvoid_return", "Check if basic calls in form of void(T) compile.") { + lua::state lua(&exceptionErrorReporter); + + #define MACRO(r, data, elem) \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::same_unary)); \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::first_binary_first)); \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::second_binary_second)); + + BOOST_PP_SEQ_FOR_EACH(MACRO, _, BASIC_TYPES) + #undef MACRO } TEST_CASE( "coverage/void_lambda_call", "Check if basic calls in form of void (T) compile." ) { lua::state lua(&exceptionErrorReporter); - lua.register_function("foo", [](int){}); - lua.register_function("foo", [](lua::nil){}); - lua.register_function("foo", [](std::string){}); - lua.register_function("foo", [](double){}); - lua.register_function("foo", [](bool){}); + #define MACRO(r, data, elem) \ + REQUIRE_NOTHROW(lua.register_function("foo", [](elem){})); + BOOST_PP_SEQ_FOR_EACH(MACRO, _, BASIC_TYPES) + #undef MACRO } -TEST_CASE("coverage/type_lambda_call", "Check if basic calls in form of void (T) compile.") { +TEST_CASE("coverage/type_lambda_call", "Check if basic calls in form of T (T) compile.") { lua::state lua(&exceptionErrorReporter); - lua.register_function("foo", [](int){ return int {}; }); - lua.register_function("foo", [](lua::nil){ return lua::nil {}; }); - lua.register_function("foo", [](std::string){ return std::string {}; }); - lua.register_function("foo", [](double){ return double {}; }); - lua.register_function("foo", [](bool){ return bool {}; }); + #define MACRO(r, data, elem) \ + REQUIRE_NOTHROW(lua.register_function("foo", [](elem){ return elem {}; })); + BOOST_PP_SEQ_FOR_EACH(MACRO, _, BASIC_TYPES) + #undef MACRO } TEST_CASE("coverage/functor_call", "Check if basic calls in form of void (T) compile.") { @@ -254,7 +233,7 @@ TEST_CASE( "advanced/callLambdaReturns", "Checks for lambdas returning values") lua.register_function("f", []{ return true; }); lua.register_function("g", []{ return std::string("str"); }); lua.register_function("h", []{}); - lua.register_function("i", []{ return lua::nil(); }); + lua.register_function("i", []{ return lua::nil; }); } TEST_CASE( "advanced/callLambda2", "A C++ lambda is exposed to lua and called") { From 87e798a156ac3520dfb97d5ee5f5fda151fc8e72 Mon Sep 17 00:00:00 2001 From: Bartek Banachewicz Date: Sat, 10 Aug 2013 12:14:44 +0200 Subject: [PATCH 4/5] Elem is a type variable. Also added double param list to lambdas --- test.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/test.cpp b/test.cpp index 67bf88b..397d650 100644 --- a/test.cpp +++ b/test.cpp @@ -75,10 +75,10 @@ namespace { TEST_CASE( "coverage/register_void_return", "Check if basic calls in form of void(T) compile." ) { lua::state lua (&exceptionErrorReporter); - #define MACRO(r, data, elem) \ - REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::void_unary)); \ - REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::void_binary_first)); \ - REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::void_binary_second)); + #define MACRO(r, data, Elem) \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::void_unary)); \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::void_binary_first)); \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::void_binary_second)); BOOST_PP_SEQ_FOR_EACH(MACRO, _, BASIC_TYPES) #undef MACRO } @@ -86,10 +86,10 @@ TEST_CASE( "coverage/register_void_return", "Check if basic calls in form of voi TEST_CASE(" coverage/register_nonvoid_return", "Check if basic calls in form of void(T) compile.") { lua::state lua(&exceptionErrorReporter); - #define MACRO(r, data, elem) \ - REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::same_unary)); \ - REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::first_binary_first)); \ - REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::second_binary_second)); + #define MACRO(r, data, Elem) \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::same_unary)); \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::first_binary_first)); \ + REQUIRE_NOTHROW(lua.register_function("foo", c_funs::basic::second_binary_second)); BOOST_PP_SEQ_FOR_EACH(MACRO, _, BASIC_TYPES) #undef MACRO @@ -98,8 +98,9 @@ TEST_CASE(" coverage/register_nonvoid_return", "Check if basic calls in form of TEST_CASE( "coverage/void_lambda_call", "Check if basic calls in form of void (T) compile." ) { lua::state lua(&exceptionErrorReporter); - #define MACRO(r, data, elem) \ - REQUIRE_NOTHROW(lua.register_function("foo", [](elem){})); + #define MACRO(r, data, Elem) \ + REQUIRE_NOTHROW(lua.register_function("foo", [](Elem){})); \ + REQUIRE_NOTHROW(lua.register_function("foo", [](Elem, Elem){})); BOOST_PP_SEQ_FOR_EACH(MACRO, _, BASIC_TYPES) #undef MACRO } @@ -107,8 +108,9 @@ TEST_CASE( "coverage/void_lambda_call", "Check if basic calls in form of void (T) compile.") { lua::state lua(&exceptionErrorReporter); - #define MACRO(r, data, elem) \ - REQUIRE_NOTHROW(lua.register_function("foo", [](elem){ return elem {}; })); + #define MACRO(r, data, Elem) \ + REQUIRE_NOTHROW(lua.register_function("foo", [](Elem){ return Elem {}; })); \ + REQUIRE_NOTHROW(lua.register_function("foo", [](Elem, Elem){ return Elem {}; })); \ BOOST_PP_SEQ_FOR_EACH(MACRO, _, BASIC_TYPES) #undef MACRO } From 2d8053b2dea83c0c9307ed2a15f7f34fe6fbac44 Mon Sep 17 00:00:00 2001 From: Bartek Banachewicz Date: Sat, 21 Sep 2013 13:12:05 +0200 Subject: [PATCH 5/5] Removed the superfluous (at this moment) test case and fixed something that looked like a nasty bug. --- test.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test.cpp b/test.cpp index 397d650..235a4d4 100644 --- a/test.cpp +++ b/test.cpp @@ -110,15 +110,11 @@ TEST_CASE("coverage/type_lambda_call", "Check if basic calls in form of T (T) compile.") { - -} - TEST_CASE( "simple/set_global", "Check if the set_global works properly." ) { lua::state lua(&exceptionErrorReporter);