You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is an issue I recently discovered when working on Java bindings for 2 different optimization solvers in C++. One of them is proprietary, but the other one is the FOSS NLopt project, see pull request stevengj/nlopt#578.
The std_vector.i file that SWIG ships for Java contains this constructor in a %proxycode block:
public$javaclassname($typemap(jstype, CTYPE)[] initialElements) {
this();
reserve(initialElements.length);
for ($typemap(jstype, CTYPE) element : initialElements) {
add(element);
}
}
As you can see, the Java type $typemap(jstype, CTYPE)[] initialElements is hardcoded except for the $typemap(jstype, CTYPE) part, in particular, the [] is hardcoded and not customizable via a typemap.
As a result, to construct such a vector in Java, you have to write a nested new call, e.g., new FooVector(new Foo[]{foo1, foo2, foo3}).
Starting from Java 1.5 (released more than 20 years ago, 2004-09-30 – all earlier versions have reached their end of life no later than October 2008), it has been possible to instead use varargs syntax, i.e., $typemap(jstype, CTYPE)... initialElements. That allows constructing the vector using the natural syntax new FooVector(foo1, foo2, foo3). An explicit array will still be accepted though, so the code is still compatible with application code calling new FooVector(new Foo[]{foo1, foo2, foo3}) (so it is not even a backwards compatibility issue for the libraries using SWIG), though that feature is most useful if you already have an array and want to pass it to the constructor, as in new FooVector(fooArr).
Unfortunately, the fact that varargs syntax also accepts an array, and in fact is internally a method taking an array with an extra annotation, means that you cannot have both an array overload and a varargs overload. So something like:
on top of the current std_vector.i is not going to compile. The Java compiler will complain about the conflicting overloads (FooVector(Foo[]) vs. FooVector(Foo...)).
So the only way I see to get SWIG to output a varargs constructor would be to replace the entire std_vector.i file. Alternatively, one can do what I did and postprocess the SWIG output with a simple s/\[\] initialElements/... initialElements/g text replacement, but this is a pretty ugly hack in my view.
Hence, it would be nice to have some kind of flag to get std_vectors.i to use the varargs form. Maybe even make it the default or only option, if you decide that supporting Java ≤ 1.4 is not worth it anymore 16 years past its official EOL. (Note that, e.g., enum was also added in Java 1.5, so any SWIG binding using proper Java enums already requires Java ≥ 1.5.)
The text was updated successfully, but these errors were encountered:
I think it's okay to require java >= 1.5 now. Please submit a pull request for the change in std_vector.i. Please also look to see if an equivalent enhancement can be made in the other STL wrappers (std_list.i etc). If you can add a runtime test for this improvement to one of the testcases that tests std_vector.i that would be appreciated, but if not, I'll look at adding one in given the motivating examples you've provided here.
This is an issue I recently discovered when working on Java bindings for 2 different optimization solvers in C++. One of them is proprietary, but the other one is the FOSS NLopt project, see pull request stevengj/nlopt#578.
The
std_vector.i
file that SWIG ships for Java contains this constructor in a%proxycode
block:As you can see, the Java type
$typemap(jstype, CTYPE)[] initialElements
is hardcoded except for the$typemap(jstype, CTYPE)
part, in particular, the[]
is hardcoded and not customizable via a typemap.As a result, to construct such a vector in Java, you have to write a nested
new
call, e.g.,new FooVector(new Foo[]{foo1, foo2, foo3})
.Starting from Java 1.5 (released more than 20 years ago, 2004-09-30 – all earlier versions have reached their end of life no later than October 2008), it has been possible to instead use varargs syntax, i.e.,
$typemap(jstype, CTYPE)... initialElements
. That allows constructing the vector using the natural syntaxnew FooVector(foo1, foo2, foo3)
. An explicit array will still be accepted though, so the code is still compatible with application code callingnew FooVector(new Foo[]{foo1, foo2, foo3})
(so it is not even a backwards compatibility issue for the libraries using SWIG), though that feature is most useful if you already have an array and want to pass it to the constructor, as innew FooVector(fooArr)
.Unfortunately, the fact that varargs syntax also accepts an array, and in fact is internally a method taking an array with an extra annotation, means that you cannot have both an array overload and a varargs overload. So something like:
on top of the current
std_vector.i
is not going to compile. The Java compiler will complain about the conflicting overloads (FooVector(Foo[])
vs.FooVector(Foo...)
).So the only way I see to get SWIG to output a varargs constructor would be to replace the entire
std_vector.i
file. Alternatively, one can do what I did and postprocess the SWIG output with a simples/\[\] initialElements/... initialElements/g
text replacement, but this is a pretty ugly hack in my view.Hence, it would be nice to have some kind of flag to get
std_vectors.i
to use the varargs form. Maybe even make it the default or only option, if you decide that supporting Java ≤ 1.4 is not worth it anymore 16 years past its official EOL. (Note that, e.g.,enum
was also added in Java 1.5, so any SWIG binding using proper Javaenum
s already requires Java ≥ 1.5.)The text was updated successfully, but these errors were encountered: