Make std::vector<> wrappers conform to List interface in Java
Derive the class wrapping std::vector<> in Java from java.util.AbstractList<>. This makes it possible to use it with various algorithms working with Java collections and, maybe even more importantly, makes it possible to iterate over the wrapped vectors using for-each loops. This commit is based on the original patch by Volker Diels-Grabsch from https://sourceforge.net/p/swig/patches/278/
This commit is contained in:
parent
7c4109c701
commit
c79dd9d420
4 changed files with 126 additions and 7 deletions
|
|
@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release.
|
||||||
Version 3.0.11 (in progress)
|
Version 3.0.11 (in progress)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
2016-11-28: Volker Diels-Grabsch, vadz
|
||||||
|
[Java] Implement java.util.List<> for std::vector. This notably allows to
|
||||||
|
iterate over wrapped vectors in a natural way.
|
||||||
|
|
||||||
2016-11-28: wsfulton
|
2016-11-28: wsfulton
|
||||||
Fix %rename override of wildcard %rename for templates. For example:
|
Fix %rename override of wildcard %rename for templates. For example:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ public class li_std_vector_runme {
|
||||||
|
|
||||||
v1.add(123);
|
v1.add(123);
|
||||||
if (v1.get(0) != 123) throw new RuntimeException("v1 test failed");
|
if (v1.get(0) != 123) throw new RuntimeException("v1 test failed");
|
||||||
|
for (int n : v1) {
|
||||||
|
if (n != 123) throw new RuntimeException("v1 loop test failed");
|
||||||
|
}
|
||||||
|
|
||||||
StructVector v4 = li_std_vector.vecstruct(new StructVector());
|
StructVector v4 = li_std_vector.vecstruct(new StructVector());
|
||||||
StructPtrVector v5 = li_std_vector.vecstructptr(new StructPtrVector());
|
StructPtrVector v5 = li_std_vector.vecstructptr(new StructPtrVector());
|
||||||
|
|
@ -28,9 +31,18 @@ public class li_std_vector_runme {
|
||||||
v5.add(new Struct(34));
|
v5.add(new Struct(34));
|
||||||
v6.add(new Struct(56));
|
v6.add(new Struct(56));
|
||||||
|
|
||||||
Struct s = null;
|
|
||||||
if (v4.get(0).getNum() != 12) throw new RuntimeException("v4 test failed");
|
if (v4.get(0).getNum() != 12) throw new RuntimeException("v4 test failed");
|
||||||
if (v5.get(0).getNum() != 34) throw new RuntimeException("v5 test failed");
|
if (v5.get(0).getNum() != 34) throw new RuntimeException("v5 test failed");
|
||||||
if (v6.get(0).getNum() != 56) throw new RuntimeException("v6 test failed");
|
if (v6.get(0).getNum() != 56) throw new RuntimeException("v6 test failed");
|
||||||
|
|
||||||
|
for (Struct s : v4) {
|
||||||
|
if (s.getNum() != 12) throw new RuntimeException("v4 loop test failed");
|
||||||
|
}
|
||||||
|
for (Struct s : v5) {
|
||||||
|
if (s.getNum() != 34) throw new RuntimeException("v5 loop test failed");
|
||||||
|
}
|
||||||
|
for (Struct s : v6) {
|
||||||
|
if (s.getNum() != 56) throw new RuntimeException("v6 loop test failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,9 +103,25 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
|
||||||
%typemap(jstype) double, const double & "double"
|
%typemap(jstype) double, const double & "double"
|
||||||
%typemap(jstype) void "void"
|
%typemap(jstype) void "void"
|
||||||
|
|
||||||
|
%typemap(jboxtype) bool "Boolean"
|
||||||
|
%typemap(jboxtype) char "Character"
|
||||||
|
%typemap(jboxtype) signed char "Byte"
|
||||||
|
%typemap(jboxtype) unsigned char "Short"
|
||||||
|
%typemap(jboxtype) short "Short"
|
||||||
|
%typemap(jboxtype) unsigned short "Integer"
|
||||||
|
%typemap(jboxtype) int "Integer"
|
||||||
|
%typemap(jboxtype) unsigned int "Long"
|
||||||
|
%typemap(jboxtype) long "Integer"
|
||||||
|
%typemap(jboxtype) unsigned long "Long"
|
||||||
|
%typemap(jboxtype) long long "Long"
|
||||||
|
%typemap(jboxtype) unsigned long long "java.math.BigInteger"
|
||||||
|
%typemap(jboxtype) float "Float"
|
||||||
|
%typemap(jboxtype) double "Double"
|
||||||
|
|
||||||
%typemap(jni) char *, char *&, char[ANY], char[] "jstring"
|
%typemap(jni) char *, char *&, char[ANY], char[] "jstring"
|
||||||
%typemap(jtype) char *, char *&, char[ANY], char[] "String"
|
%typemap(jtype) char *, char *&, char[ANY], char[] "String"
|
||||||
%typemap(jstype) char *, char *&, char[ANY], char[] "String"
|
%typemap(jstype) char *, char *&, char[ANY], char[] "String"
|
||||||
|
%typemap(jboxtype) char *, char *&, char[ANY], char[] "String"
|
||||||
|
|
||||||
/* JNI types */
|
/* JNI types */
|
||||||
%typemap(jni) jboolean "jboolean"
|
%typemap(jni) jboolean "jboolean"
|
||||||
|
|
@ -172,6 +188,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
|
||||||
%typemap(jni) SWIGTYPE "jlong"
|
%typemap(jni) SWIGTYPE "jlong"
|
||||||
%typemap(jtype) SWIGTYPE "long"
|
%typemap(jtype) SWIGTYPE "long"
|
||||||
%typemap(jstype) SWIGTYPE "$&javaclassname"
|
%typemap(jstype) SWIGTYPE "$&javaclassname"
|
||||||
|
%typemap(jboxtype) SWIGTYPE "$typemap(jstype, $1_type)"
|
||||||
|
|
||||||
%typemap(jni) SWIGTYPE [] "jlong"
|
%typemap(jni) SWIGTYPE [] "jlong"
|
||||||
%typemap(jtype) SWIGTYPE [] "long"
|
%typemap(jtype) SWIGTYPE [] "long"
|
||||||
|
|
|
||||||
|
|
@ -10,38 +10,124 @@
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%define SWIG_STD_VECTOR_MINIMUM_INTERNAL(CTYPE, CREF_TYPE)
|
%define SWIG_STD_VECTOR_MINIMUM_INTERNAL(CTYPE, CREF_TYPE)
|
||||||
|
%typemap(javabase) std::vector<CTYPE> "java.util.AbstractList<$typemap(jboxtype, CTYPE)>"
|
||||||
|
%typemap(javainterfaces) std::vector<CTYPE> "java.util.RandomAccess"
|
||||||
|
%typemap(javacode) std::vector<CTYPE> %{
|
||||||
|
public $javaclassname($typemap(jstype, CTYPE)[] initialElements) {
|
||||||
|
this();
|
||||||
|
for ($typemap(jstype, CTYPE) element : initialElements) {
|
||||||
|
add(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public $javaclassname(Iterable<$typemap(jboxtype, CTYPE)> initialElements) {
|
||||||
|
this();
|
||||||
|
for ($typemap(jstype, CTYPE) element : initialElements) {
|
||||||
|
add(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public $typemap(jboxtype, CTYPE) get(int index) {
|
||||||
|
return doGet(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public $typemap(jboxtype, CTYPE) set(int index, $typemap(jboxtype, CTYPE) e) {
|
||||||
|
return doSet(index, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean add($typemap(jboxtype, CTYPE) e) {
|
||||||
|
modCount++;
|
||||||
|
doAdd(e);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int index, $typemap(jboxtype, CTYPE) e) {
|
||||||
|
modCount++;
|
||||||
|
doAdd(index, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public $typemap(jboxtype, CTYPE) remove(int index) {
|
||||||
|
modCount++;
|
||||||
|
return doRemove(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void removeRange(int fromIndex, int toIndex) {
|
||||||
|
modCount++;
|
||||||
|
doRemoveRange(fromIndex, toIndex);
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef size_t size_type;
|
typedef size_t size_type;
|
||||||
typedef CTYPE value_type;
|
typedef CTYPE value_type;
|
||||||
typedef CREF_TYPE const_reference;
|
typedef CREF_TYPE const_reference;
|
||||||
vector();
|
vector();
|
||||||
vector(size_type n);
|
vector(size_type n);
|
||||||
size_type size() const;
|
// Note that it returns int, and not size_type, for compatibility with
|
||||||
|
// the signature of size() in Java interface.
|
||||||
|
int size() const;
|
||||||
size_type capacity() const;
|
size_type capacity() const;
|
||||||
void reserve(size_type n);
|
void reserve(size_type n);
|
||||||
%rename(isEmpty) empty;
|
%rename(isEmpty) empty;
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
void clear();
|
void clear();
|
||||||
%rename(add) push_back;
|
|
||||||
void push_back(const value_type& x);
|
|
||||||
%extend {
|
%extend {
|
||||||
CREF_TYPE get(int i) throw (std::out_of_range) {
|
void doAdd(const value_type& value) {
|
||||||
|
self->push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void doAdd(int index, const value_type& value) throw (std::out_of_range) {
|
||||||
|
const int size = int(self->size());
|
||||||
|
if (0 <= index && index <= size) {
|
||||||
|
self->insert(self->begin() + index, value);
|
||||||
|
} else {
|
||||||
|
throw std::out_of_range("vector index out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value_type doRemove(int index) throw (std::out_of_range) {
|
||||||
|
const int size = int(self->size());
|
||||||
|
if (0 <= index && index < size) {
|
||||||
|
CTYPE const old_value = (*self)[index];
|
||||||
|
self->erase(self->begin() + index);
|
||||||
|
return old_value;
|
||||||
|
} else {
|
||||||
|
throw std::out_of_range("vector index out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CREF_TYPE doGet(int i) throw (std::out_of_range) {
|
||||||
int size = int(self->size());
|
int size = int(self->size());
|
||||||
if (i>=0 && i<size)
|
if (i>=0 && i<size)
|
||||||
return (*self)[i];
|
return (*self)[i];
|
||||||
else
|
else
|
||||||
throw std::out_of_range("vector index out of range");
|
throw std::out_of_range("vector index out of range");
|
||||||
}
|
}
|
||||||
void set(int i, const value_type& val) throw (std::out_of_range) {
|
value_type doSet(int i, const value_type& val) throw (std::out_of_range) {
|
||||||
int size = int(self->size());
|
int size = int(self->size());
|
||||||
if (i>=0 && i<size)
|
if (i>=0 && i<size) {
|
||||||
|
CTYPE const old_value = (*self)[i];
|
||||||
(*self)[i] = val;
|
(*self)[i] = val;
|
||||||
|
return old_value;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
throw std::out_of_range("vector index out of range");
|
throw std::out_of_range("vector index out of range");
|
||||||
}
|
}
|
||||||
|
void doRemoveRange(int fromIndex, int toIndex) throw (std::out_of_range) {
|
||||||
|
const int size = int(self->size());
|
||||||
|
if (0 <= fromIndex && fromIndex <= toIndex && toIndex <= size) {
|
||||||
|
self->erase(self->begin() + fromIndex, self->begin() + toIndex);
|
||||||
|
} else {
|
||||||
|
throw std::out_of_range("vector index out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
%enddef
|
%enddef
|
||||||
|
|
||||||
|
%javamethodmodifiers std::vector::doAdd "private";
|
||||||
|
%javamethodmodifiers std::vector::doGet "private";
|
||||||
|
%javamethodmodifiers std::vector::doSet "private";
|
||||||
|
%javamethodmodifiers std::vector::doRemove "private";
|
||||||
|
%javamethodmodifiers std::vector::doRemoveRange "private";
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
||||||
template<class T> class vector {
|
template<class T> class vector {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue