Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support default parameters #17

Closed
Flamefire opened this issue Mar 18, 2016 · 15 comments
Closed

Support default parameters #17

Flamefire opened this issue Mar 18, 2016 · 15 comments

Comments

@Flamefire
Copy link
Contributor

Is it somehow possible, to support default parameters without writing extra functions?
Like:

class Foo{
  void func(int param = 42){ std::cout << param; }
};

Currently those functions can be registered, but if the param is notpassed by Lua , it will be 0 instead of 42

@satoren
Copy link
Owner

satoren commented Mar 18, 2016

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
);

@ynlh
Copy link

ynlh commented Jul 2, 2016

When can support default parameters?

@satoren
Copy link
Owner

satoren commented Jul 2, 2016

When i hit upon a good idea.

@satoren
Copy link
Owner

satoren commented Jul 18, 2016

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)");

@aster2013
Copy link
Contributor

aster2013 commented Jul 19, 2016

Build error on VS2015 when function return void.

'kaguya::util::push_args': function does not take 2 arguments

@satoren
Copy link
Owner

satoren commented Jul 19, 2016

Add void return version , because can not fix on quick.
I put together they, If it can created.

@aster2013
Copy link
Contributor

aster2013 commented Jul 26, 2016

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 = "");
};

@aster2013
Copy link
Contributor

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)

satoren added a commit that referenced this issue Jul 27, 2016
Unusable in function scope.
@aster2013
Copy link
Contributor

Hi, where you pushed, not on the master?

satoren added a commit that referenced this issue Jul 27, 2016
Unusable in function scope.
@satoren
Copy link
Owner

satoren commented Jul 27, 2016

I'm waited test pass on my CI.

Usage was little changed.

  • KAGUYA_FUNCTION_OVERLOADS and KAGUYA_MEMBER_FUNCTION_OVERLOADS is unusable in function scope.
  • KAGUYA_VOID_FUNCTION_OVERLOADS and KAGUYA_VOID_MEMBER_FUNCTION_OVERLOADS is removed.
  • add KAGUYA_FUNCTION_OVERLOADS_WITH_SIGNATURE and KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE
  • Need round brackets on use

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())
);

@aster2013
Copy link
Contributor

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.
    }
  }

@satoren
Copy link
Owner

satoren commented Jul 28, 2016

Thank you for report.

@aster2013
Copy link
Contributor

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 *'

@aster2013
Copy link
Contributor

template<>  struct lua_type_traits<const char*> {
        // typedef std::string get_type;
        typedef const char* get_type;
        typedef const char* push_type;

@satoren
Copy link
Owner

satoren commented Jul 29, 2016

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants