Closed Flamefire closed 8 years ago
I don't know about detect function have default parameter.
other way is use overload.
struct Foo {
void func(int param = 42) { std::cout << param<<std::endl; }
};
state["Foo"].setClass(kaguya::ClassMetatable<Foo>()
.addMemberFunction("func", &Foo::func)
.addStaticFunction("func", [](Foo& self) {self.func(); })
);
state["foo"] = Foo();
state("foo:func()");//42
state("foo:func(1)");//1
);
When can support default parameters?
When i hit upon a good idea.
Added support for Default parameters
/**
* @name KAGUYA_FUNCTION_OVERLOADS
* @brief Generate wrapper function object for count based overloads. Include default arguments parameter function
* @param GENERATE_NAME generate function object name
* @param FNAME target function name
* @param MINARG minimum arguments count
* @param MAXARG maximum arguments count
*/
#define KAGUYA_FUNCTION_OVERLOADS(GENERATE_NAME,FNAME, MINARG, MAXARG) KAGUYA_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME,FNAME, MINARG, MAXARG)
/**
* @name KAGUYA_FUNCTION_OVERLOADS
* @brief Generate wrapper function object for count based overloads. Include default arguments parameter function
* @param GENERATE_NAME generate function object name
* @param CLASS target class name
* @param FNAME target function name
* @param MINARG minimum arguments count
* @param MAXARG maximum arguments count
*/
#define KAGUYA_MEMBER_FUNCTION_OVERLOADS(GENERATE_NAME,CLASS,FNAME, MINARG, MAXARG) KAGUYA_MEMBER_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME,CLASS,FNAME, MINARG, MAXARG)
example
//free function
int defargfn(int a = 3, int b = 2, int c = 1)
{
return a*b*c;
}
KAGUYA_FUNCTION_OVERLOADS(defargfn_wrapper, defargfn,0,3)
state["defarg"] = kaguya::function(defargfn_wrapper);
state.dostring("assert(defarg() == 6)");
state.dostring("assert(defarg(6) == 12)");
state.dostring("assert(defarg(6,5) == 30)");
state.dostring("assert(defarg(2,2,2) == 8)");
//member function
struct TestClass
{
int defargfn(int a = 3, int b = 2, int c = 1)
{
return a*b*c;
}
}
KAGUYA_MEMBER_FUNCTION_OVERLOADS(defargfn_wrapper, TestClass, default_arg, 0, 3)
state["TestClass"].setClass(kaguya::UserdataMetatable<TestClass>()
.setConstructors<TestClass()>()
.addFunction("defarg", defargfn_wrapper)
);
state.dostring("test = TestClass.new()");
state.dostring("assert(test:defargfn() == 6)");
state.dostring("assert(test:defargfn(6) == 12)");
state.dostring("assert(test:defargfn(6,5) == 30)");
state.dostring("assert(test:defargfn(2,2,2) == 8)");
Build error on VS2015 when function return void.
'kaguya::util::push_args': function does not take 2 arguments
Add void return version , because can not fix on quick. I put together they, If it can created.
When functions with different signatures, these macros can not work. for example.
struct Test
{
void add(int a, int b = 0);
void add(const std::string& a, const std::string& b = "");
};
Here is my current solution:
static void addInt(Test* self, int a, int b = 0)
{
self->add(a, b);
}
static void addString(Test* self, const std::string& a, const std::string& b = "")
{
self->add(a, b);
}
...
KAGUYA_VOID_FUNCTION_OVERLOADS(addInt, addInt, 1, 2);
KAGUYA_VOID_FUNCTION_OVERLOADS(addString, addString, 1, 2);
...
.addOverloadedFunctions("add", addInt, addString)
Hi, where you pushed, not on the master?
I'm waited test pass on my CI.
Usage was little changed.
example
KAGUYA_FUNCTION_OVERLOADS(defargfn_wrapper, defargfn, 0, 3);
KAGUYA_FUNCTION_OVERLOADS_WITH_SIGNATURE(defargfn_wrapper_with_sig, defargfn, 0, 3,int(int,int,int));
KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE(mem_defargfn_wrapper_with_sig, TestClass, default_arg, 0, 3,int(TestClass::*)(int,int,int));
...
state["defargfn"] = kaguya::function(defargfn_wrapper());
state["defargfn2"] = kaguya::function(defargfn_wrapper_with_sig());
state["TestClass"].setClass(kaguya::UserdataMetatable<TestClass>()
.addFunction("defargfn", mem_defargfn_wrapper_with_sig())
);
Bug:
For example, a overloaded function with following arguments:
void Test(const std::string& a = "hello");
We need a const reference as input, but the lua_type_traits<std::string>::get(...)
returns std::string
.
So bug in following code:
namespace nativefunction
{
template<size_t INDEX,typename F>
typename util::ArgumentType<INDEX, F>::type getArgument(lua_State* state)
{
return lua_type_traits<typename util::ArgumentType<INDEX, F>::type>::get(state, INDEX + 1);
}
// explanded:
template<size_t INDEX,typename F>
const std::string& getArgument(lua_State* state)
{
std::string value = lua_type_traits<std::string>::get(state, INDEX + 1);
return value; // <--- Error, return a temporary variable.
}
}
Thank you for report.
And another bug: When some function with const char* argument, kaguya will report error:
cannot convert argument 2 from 'kaguya::lua_type_traits<const char*,void>::get_type' to 'const char *'
template<> struct lua_type_traits<const char*> {
// typedef std::string get_type;
typedef const char* get_type;
typedef const char* push_type;
Thanks!
Is it somehow possible, to support default parameters without writing extra functions? Like:
Currently those functions can be registered, but if the param is notpassed by Lua , it will be
0
instead of42