mirror of https://github.com/swig/swig
feature("cs:defaultargs")
We need a way to specify default arguments for functions. Sometimes we can just take the arguments straight from c++ literals. Sometimes you can't, and need to specify those by hand. So to make this work we: 1. Shutoff handling all "defaultargs" variants of methods and constructors which have cs:defaultargs defined for their node. This gets us a single constructor or method and skips the variants. 2. As we emit arguments in the function declaration, check if there is a definition for it it from cs:defaultargs, if so, use that. If not, and the method has a cs:defaultargs declaration, then fall back to the literal expression from c++.
This commit is contained in:
parent
d2c0105d72
commit
b6409b584f
|
@ -42,6 +42,7 @@
|
|||
<li><a href="#CSharp_director_caveats">Director caveats</a>
|
||||
</ul>
|
||||
<li><a href="#CSharp_multiple_modules">Multiple modules</a>
|
||||
<li><a href="#CSharp_argdef">Named arguments</a>
|
||||
<li><a href="#CSharp_typemap_examples">C# Typemap examples</a>
|
||||
<ul>
|
||||
<li><a href="#CSharp_memory_management_member_variables">Memory management when returning references to member variables</a>
|
||||
|
@ -2150,7 +2151,52 @@ the <tt>[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrows
|
|||
if you don't want users to easily stumble upon these so called 'internal workings' of the wrappers.
|
||||
</p>
|
||||
|
||||
<H2><a name="CSharp_typemap_examples">23.8 C# Typemap examples</a></H2>
|
||||
|
||||
<H2><a name="CSharp_argdef">23.8 C# Named arguments</a></H2>
|
||||
|
||||
<p>
|
||||
In C++ you can specify default arguments for functions, methods, and constructors. C# offers named arguments. This feature, specific to csharp, lets you bind default argument functions with default arguments in C#. You can also add default arguments to functions which don't have default arguments.
|
||||
</p>
|
||||
|
||||
<p>Please note, using this on a function will turn off the default handling of default arguments, which would create an override for each defaulted argument, so that they could be called the same way they could in C++. So you'll want to specify defaults for every argument when you use this.</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("cs:defaultargs") Foo::Foo;
|
||||
%feature("cs:defaultargs", z=4) Foo::bar;
|
||||
%feature("cs:defaultargs", x="\"five\"") Foo::zoo;
|
||||
|
||||
%inline %{
|
||||
class Foo {
|
||||
public:
|
||||
virtual ~Foo() {}
|
||||
Foo(int a, int b=1, int c=2)
|
||||
{
|
||||
}
|
||||
int bar(int x, int y=2, int z=3)
|
||||
{
|
||||
return x+y+z;
|
||||
}
|
||||
int bat(int x=1, int y=2, int z=3)
|
||||
{
|
||||
return x+y+z;
|
||||
}
|
||||
int zoo(std::string x="four")
|
||||
{
|
||||
return (int)x.size();
|
||||
}
|
||||
};
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>For this feature, you first specify the function/constructor you want it to impact. Inside the feature
|
||||
call you specify each argument you want to override. If you specify none, it will take the literal text from c++
|
||||
for each argument and apply that in csharp. That often works fine, but when it doesn't you can supply a string literal
|
||||
with a csharp expression to be used. Or you can supply an int literal, or a float literal. If you want to give a literal
|
||||
string you need to include an escaped quote at the start and end of the literal: "\"a string\"".</p>
|
||||
|
||||
<H2><a name="CSharp_typemap_examples">23.9 C# Typemap examples</a></H2>
|
||||
|
||||
|
||||
This section includes a few examples of typemaps. For more examples, you
|
||||
|
|
|
@ -1829,6 +1829,7 @@ such as C# and Java,
|
|||
which don't have optional arguments in the language,
|
||||
Another restriction of this feature is that it cannot handle default arguments that are not public.
|
||||
The following example illustrates this:
|
||||
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
@ -1850,6 +1851,10 @@ evaluates them in the scope of a wrapper function (meaning that the
|
|||
values have to be public).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For C# there is a feature "cs:defaultargs" which allows you to get a single proxy function and lets you specify the arguments in C#.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The <tt>compactdefaultargs</tt> feature is automatically turned on when wrapping <a href="SWIG.html#SWIG_default_args">C code with default arguments</a>.
|
||||
Some target languages will also automatically turn on this feature
|
||||
|
|
|
@ -121,6 +121,7 @@ CPP_TEST_CASES += \
|
|||
apply_strings \
|
||||
argcargvtest \
|
||||
argout \
|
||||
csharp_argument_defaults_feature \
|
||||
array_member \
|
||||
array_typedef_memberin \
|
||||
arrayref \
|
||||
|
|
|
@ -36,6 +36,8 @@ CPP_TEST_CASES = \
|
|||
nested_scope \
|
||||
li_boost_intrusive_ptr \
|
||||
li_std_list \
|
||||
csharp_argument_defaults_feature \
|
||||
|
||||
|
||||
CPP11_TEST_CASES = \
|
||||
cpp11_shared_ptr_const \
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using csharp_argument_defaults_featureNamespace;
|
||||
|
||||
public class runme {
|
||||
static void Main() {
|
||||
Foo foo = new Foo(1);
|
||||
foo.bar(1); //shutup compiler warning
|
||||
Foo bar = new Foo(1, c:3);
|
||||
|
||||
if(bar.bar(1) != 7)
|
||||
throw new ApplicationException("bar.bar(1) != 7");
|
||||
if(bar.bar(1, 4, 4) != 9)
|
||||
throw new ApplicationException("bar.bar(1, 4, 4) != 9");
|
||||
if(bar.bar(1, y:3) != 8)
|
||||
throw new ApplicationException("bar.bar(1, y:3) != 8");
|
||||
if(bar.bat() != 6)
|
||||
throw new ApplicationException("bar.bat() != 6");
|
||||
if(bar.bat(3,3) != 9)
|
||||
throw new ApplicationException("bar.bat(3,3) != 9");
|
||||
if(bar.zoo() != 5)
|
||||
throw new ApplicationException("bar.zoo() != 5");
|
||||
if(bar.zoo(x:"to") != 2)
|
||||
throw new ApplicationException("bar.zoo(x:\"to\" != 2");
|
||||
if(bar.pi() != System.Math.PI)
|
||||
throw new ApplicationException("bar.pi() != Math.PI");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
%module csharp_argument_defaults_feature
|
||||
%include "std_string.i"
|
||||
|
||||
|
||||
%feature("cs:defaultargs") Foo::Foo;
|
||||
%feature("cs:defaultargs", z=4) Foo::bar;
|
||||
%feature("cs:defaultargs", x="\"fives\"") Foo::zoo;
|
||||
%feature("cs:defaultargs", value="System.Math.PI") Foo::pi;
|
||||
|
||||
//intentionally don't touch bat, leave it to normal handling
|
||||
|
||||
%inline %{
|
||||
#include <string>
|
||||
class Foo {
|
||||
public:
|
||||
virtual ~Foo() {}
|
||||
Foo(int a, int b=1, int c=2)
|
||||
{
|
||||
}
|
||||
int bar(int x, int y=2, int z=3)
|
||||
{
|
||||
return x+y+z;
|
||||
}
|
||||
int bat(int x=1, int y=2, int z=3)
|
||||
{
|
||||
return x+y+z;
|
||||
}
|
||||
int zoo(std::string x="four")
|
||||
{
|
||||
return (int)x.size();
|
||||
}
|
||||
double pi(double value=3.14)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
%}
|
||||
|
||||
|
||||
|
|
@ -15,6 +15,10 @@
|
|||
#include "cparse.h"
|
||||
#include <limits.h> // for INT_MAX
|
||||
#include <ctype.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
|
||||
|
||||
/* Hash type used for upcalls from C/C++ */
|
||||
typedef DOH UpcallData;
|
||||
|
@ -2298,6 +2302,35 @@ public:
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
void printArgumentDeclaration(Node *n,
|
||||
Parm *p, String *param_type, String *arg, String *code)
|
||||
{
|
||||
String *specifiedoverridekey = NewString("feature:cs:defaultargs:");
|
||||
Append(specifiedoverridekey, arg);
|
||||
String *specifiedoverridevalue = Getattr(n, specifiedoverridekey);
|
||||
if(specifiedoverridevalue)
|
||||
{
|
||||
Printf(code, "%s %s=%s", param_type, arg, specifiedoverridevalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
String *cppvalue = NULL;
|
||||
//if they've not specified defaultargs, then fall back to
|
||||
//the normal default handling of specifying one overload per possible
|
||||
//set of arguments. If they have, then use the default argument from
|
||||
//c++ as a literal csharp expression.
|
||||
if(Getattr(n, "feature:cs:defaultargs"))
|
||||
cppvalue = Getattr(p, "value");
|
||||
if(cppvalue)
|
||||
Printf(code, "%s %s=%s", param_type, arg, cppvalue);
|
||||
else
|
||||
Printf(code, "%s %s", param_type, arg);
|
||||
}
|
||||
Delete(specifiedoverridekey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* memberfunctionHandler()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
@ -2376,6 +2409,10 @@ public:
|
|||
if (Getattr(n, "overload:ignore"))
|
||||
return;
|
||||
|
||||
String *csargdef = Getattr(n, "feature:cs:defaultargs");
|
||||
if(csargdef && Getattr(n, "defaultargs"))
|
||||
return;
|
||||
|
||||
// Don't generate proxy method for additional explicitcall method used in directors
|
||||
if (GetFlag(n, "explicitcall"))
|
||||
return;
|
||||
|
@ -2460,7 +2497,6 @@ public:
|
|||
Printf(imcall, "swigCPtr");
|
||||
|
||||
emit_mark_varargs(l);
|
||||
|
||||
int gencomma = !static_flag;
|
||||
|
||||
/* Output each parameter */
|
||||
|
@ -2539,9 +2575,9 @@ public:
|
|||
Printf(interface_class_code, ", ");
|
||||
}
|
||||
gencomma = 2;
|
||||
Printf(function_code, "%s %s", param_type, arg);
|
||||
printArgumentDeclaration(n, p, param_type, arg, function_code);
|
||||
if (is_interface)
|
||||
Printf(interface_class_code, "%s %s", param_type, arg);
|
||||
printArgumentDeclaration(n, p, param_type, arg, interface_class_code);
|
||||
|
||||
Delete(arg);
|
||||
Delete(param_type);
|
||||
|
@ -2723,6 +2759,10 @@ public:
|
|||
if (Getattr(n, "overload:ignore"))
|
||||
return SWIG_OK;
|
||||
|
||||
String *csargdef = Getattr(n, "feature:cs:defaultargs");
|
||||
if(csargdef && Getattr(n, "defaultargs"))
|
||||
return SWIG_OK;
|
||||
|
||||
if (proxy_flag) {
|
||||
String *overloaded_name = getOverloadedName(n);
|
||||
String *mangled_overname = Swig_name_construct(getNSpace(), overloaded_name);
|
||||
|
@ -2831,7 +2871,7 @@ public:
|
|||
Printf(helper_code, ", ");
|
||||
Printf(helper_args, ", ");
|
||||
}
|
||||
Printf(function_code, "%s %s", param_type, arg);
|
||||
printArgumentDeclaration(n, p, param_type, arg, function_code);
|
||||
Printf(helper_code, "%s %s", param_type, arg);
|
||||
Printf(helper_args, "%s", cshin ? cshin : arg);
|
||||
++gencomma;
|
||||
|
|
Loading…
Reference in New Issue