From 6a4467721bd732820d95b9b7da237adc78c7a5c8 Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Sat, 7 May 2016 22:44:28 +0100 Subject: [PATCH 01/45] - added std_list.i implemenatation that extends Java's AbstractSequentialList base class - added autobox.i that provides supporting typemaps for generics in containers --- Lib/java/autobox.i | 12 ++++ Lib/java/std_list.i | 168 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 Lib/java/autobox.i create mode 100644 Lib/java/std_list.i diff --git a/Lib/java/autobox.i b/Lib/java/autobox.i new file mode 100644 index 000000000..0146faa76 --- /dev/null +++ b/Lib/java/autobox.i @@ -0,0 +1,12 @@ +// Java typemaps for autoboxing in return types of generics +%define AUTOBOX(CTYPE, JTYPE) +%typemap(autobox) CTYPE, const CTYPE&, CTYPE& "JTYPE" +%enddef +AUTOBOX(double, Double) +AUTOBOX(float, Float) +AUTOBOX(boolean, Boolean) +AUTOBOX(signed char, Byte) +AUTOBOX(short, Short) +AUTOBOX(int, Integer) +AUTOBOX(long, Long) +AUTOBOX(SWIGTYPE, $typemap(jstype,$1_basetype)) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i new file mode 100644 index 000000000..0fd24dd51 --- /dev/null +++ b/Lib/java/std_list.i @@ -0,0 +1,168 @@ +%include +%include + +%{ +#include +#include +%} + +namespace std { + template class list { + public: + // This typedef is a weird hack to make stuff work + typedef std::list::iterator iterator; + typedef size_t size_type; + typedef T value_type; + typedef T& reference; + + void assign(size_type n, const value_type &val); + + bool empty() const; + + list(size_type n, const value_type &value=value_type()); + list(const list &o); + list(); + ~list(); + + size_type max_size () const; + + void pop_back(); + void pop_front(); + void push_back(const value_type &x); + void push_front(const value_type &x); + void remove(const T &v); + + // Possible bug: jint != size_type + jint size () const; + void sort(); + +%javamethodmodifiers "private"; + // Only for helping implement listIterator + iterator begin(); + iterator insert(iterator pos, const value_type &v); + + %extend { + static void set(iterator pos, const value_type& v) { + *pos = v; + } + + jint previous_index(const iterator& pos) const { + return pos == self->begin() ? -1 : std::distance(self->begin(), static_cast::const_iterator>(pos)); + } + + jint next_index(const iterator& pos) const { + return pos == self->end() ? self->size() : std::distance(self->begin(), static_cast::const_iterator>(pos)); + } + + static iterator next(iterator pos) { + return ++pos; + } + + static iterator previous(iterator pos) { + return --pos; + } + + static value_type deref(const iterator& pos) { + return *pos; + } + + static void advance(iterator& pos, jint index) { + std::advance(pos, index); + } + + bool has_next(const iterator& pos) const { + return pos != $self->end(); + } + } +%javamethodmodifiers "public"; + }; +} + +%typemap(javaimports) std::list %{ + import java.util.AbstractSequentialList; + import java.util.ListIterator; + import java.util.NoSuchElementException; + import java.util.Collection; +%} + +%typemap(javabase) std::list "AbstractSequentialList<$typemap(autobox,$1_basetype::value_type)>" + +#define JAVA_VALUE_TYPE $typemap(autobox,$1_basetype::value_type) +#define JAVA_ITERATOR_TYPE $typemap(jstype, $1_basetype::iterator) + +%typemap(javacode,noblock=1) std::list { + public $javaclassname(Collection c) { + this(); + ListIterator it = listIterator(0); + for (Object o: c) { + it.add((JAVA_VALUE_TYPE)o); + } + } + + public ListIterator listIterator(int index) { + return new ListIterator() { + private JAVA_ITERATOR_TYPE pos; + private JAVA_ITERATOR_TYPE last; + + private ListIterator init(int index) { + pos = $javaclassname.this.begin(); + $javaclassname.advance(pos, index); + return this; + } + + public void add(JAVA_VALUE_TYPE v) { + // Technically we can invalidate last here, but this makes more sense + last=$javaclassname.this.insert(pos, v); + } + + public void set(JAVA_VALUE_TYPE v) { + if (null==last) { + throw new IllegalStateException(); + } + $javaclassname.set(last, v); + } + + public void remove() { + if (null==last) { + throw new IllegalStateException(); + } + $javaclassname.this.remove(last); + last=null; + } + + public int previousIndex() { + return $javaclassname.this.previous_index(pos); + } + + public int nextIndex() { + return $javaclassname.this.next_index(pos); + } + + public JAVA_VALUE_TYPE previous() { + if (previousIndex() < 0) { + throw new NoSuchElementException(); + } + last = pos; + pos = $javaclassname.previous(pos); + return $javaclassname.deref(last); + } + + public JAVA_VALUE_TYPE next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + last = pos; + pos = $javaclassname.next(pos); + return $javaclassname.deref(last); + } + + public boolean hasPrevious() { + return previousIndex() != -1; + } + + public boolean hasNext() { + return $javaclassname.this.has_next(pos); + } + }.init(index); + } +} From b0de71857e5684dc9119a380edc1d83a19fc5f9c Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Mon, 16 May 2016 20:39:34 +0100 Subject: [PATCH 02/45] Don't expose remove() method from std::list to avoid confusing it with Java's remove() in List --- Lib/java/std_list.i | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 0fd24dd51..b717bbfc2 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -30,7 +30,6 @@ namespace std { void pop_front(); void push_back(const value_type &x); void push_front(const value_type &x); - void remove(const T &v); // Possible bug: jint != size_type jint size () const; From 0094e3c90df80267d03a049ad7a48ce3fe866c17 Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Mon, 16 May 2016 20:49:51 +0100 Subject: [PATCH 03/45] Target each method specificly for setting modifiers --- Lib/java/std_list.i | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index b717bbfc2..f49b11826 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -6,6 +6,17 @@ #include %} +%javamethodmodifiers std::list::begin "private"; +%javamethodmodifiers std::list::insert "private"; +%javamethodmodifiers std::list::set "private"; +%javamethodmodifiers std::list::previous_index "private"; +%javamethodmodifiers std::list::next_index "private"; +%javamethodmodifiers std::list::previous "private"; +%javamethodmodifiers std::list::next "private"; +%javamethodmodifiers std::list::deref "private"; +%javamethodmodifiers std::list::advance "private"; +%javamethodmodifiers std::list::has_next "private"; + namespace std { template class list { public: @@ -35,7 +46,6 @@ namespace std { jint size () const; void sort(); -%javamethodmodifiers "private"; // Only for helping implement listIterator iterator begin(); iterator insert(iterator pos, const value_type &v); @@ -73,7 +83,6 @@ namespace std { return pos != $self->end(); } } -%javamethodmodifiers "public"; }; } From a2b092ab7e2b00a1090651b6ec9f21fa2b4bfb9d Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Mon, 16 May 2016 21:24:11 +0100 Subject: [PATCH 04/45] Don't expose sort() to avoid adding dependencies on all std::list users --- Lib/java/std_list.i | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index f49b11826..932980d67 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -44,7 +44,9 @@ namespace std { // Possible bug: jint != size_type jint size () const; - void sort(); + + // Although sort() is nice it makes operator<() mandatory which it probably shouldn't be + //void sort(); // Only for helping implement listIterator iterator begin(); From 131f5e5a0d78825523eb215f12a24e8219973fa0 Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Mon, 16 May 2016 21:25:08 +0100 Subject: [PATCH 05/45] Expose more types from li_std_list.i --- Examples/test-suite/li_std_list.i | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Examples/test-suite/li_std_list.i b/Examples/test-suite/li_std_list.i index bae475eea..cdf028a50 100644 --- a/Examples/test-suite/li_std_list.i +++ b/Examples/test-suite/li_std_list.i @@ -42,5 +42,7 @@ struct Struct { }; %} - +%template(StructList) std::list; +%template(StructPtrList) std::list; +%template(StructConstPtrList) std::list; From 65483965aba5b9e26a10a1e7c916f749058113c4 Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Mon, 16 May 2016 21:25:47 +0100 Subject: [PATCH 06/45] Base _runme.java for li_std_list off li_std_vector_runme.java --- .../test-suite/java/li_std_list_runme.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Examples/test-suite/java/li_std_list_runme.java diff --git a/Examples/test-suite/java/li_std_list_runme.java b/Examples/test-suite/java/li_std_list_runme.java new file mode 100644 index 000000000..de53a9fa6 --- /dev/null +++ b/Examples/test-suite/java/li_std_list_runme.java @@ -0,0 +1,35 @@ +import li_std_list.*; + +public class li_std_list_runme { + + static { + try { + System.loadLibrary("li_std_list"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) throws Throwable + { + IntList v1 = new IntList(); + DoubleList v2 = new DoubleList(); + + v1.add(123); + if (v1.get(0) != 123) throw new RuntimeException("v1 test failed"); + + StructList v4 = new StructList(); + StructPtrList v5 = new StructPtrList(); + StructConstPtrList v6 = new StructConstPtrList(); + + v4.add(new Struct(12)); + v5.add(new Struct(34)); + v6.add(new Struct(56)); + + Struct s = null; + 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 (v6.get(0).getNum() != 56) throw new RuntimeException("v6 test failed"); + } +} From d217a68908a8c7f5555a56325ba22e92a2bd7e7a Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Mon, 16 May 2016 21:29:22 +0100 Subject: [PATCH 07/45] added more comments in a few places --- Lib/java/std_list.i | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 932980d67..35f0ecac8 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -104,6 +104,7 @@ namespace std { public $javaclassname(Collection c) { this(); ListIterator it = listIterator(0); + // We should special case the "copy constructor" here to avoid lots of cross-language calls for (Object o: c) { it.add((JAVA_VALUE_TYPE)o); } @@ -167,6 +168,7 @@ namespace std { } public boolean hasPrevious() { + // This call to previousIndex() will be much slower than the hasNext() implementation, but it's simpler like this with C++ forward iterators return previousIndex() != -1; } From a3821245eb47d88e995e9598a57f493b4e744a2b Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Mon, 16 May 2016 21:49:45 +0100 Subject: [PATCH 08/45] Added li_std_list to the Java test-suit makefile --- Examples/test-suite/java/Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in index e69964352..b5e8c65f0 100644 --- a/Examples/test-suite/java/Makefile.in +++ b/Examples/test-suite/java/Makefile.in @@ -39,6 +39,7 @@ CPP_TEST_CASES = \ java_throws \ java_typemaps_proxy \ java_typemaps_typewrapper \ + li_std_list \ # li_boost_intrusive_ptr CPP11_TEST_CASES = \ From 4a149f66fdc12e34b33c7189f51082ca9b9af709 Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Mon, 16 May 2016 22:00:37 +0100 Subject: [PATCH 09/45] Added enum to li_std_list tests --- Examples/test-suite/li_std_list.i | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Examples/test-suite/li_std_list.i b/Examples/test-suite/li_std_list.i index cdf028a50..54b4cdfea 100644 --- a/Examples/test-suite/li_std_list.i +++ b/Examples/test-suite/li_std_list.i @@ -40,9 +40,17 @@ struct Struct { Struct(double d) : num(d) {} // bool operator==(const Struct &other) { return (num == other.num); } }; + +enum Fruit { + APPLE, + BANANNA, + PEAR, + KIWI, +}; %} %template(StructList) std::list; %template(StructPtrList) std::list; %template(StructConstPtrList) std::list; +%template(FruitList) std::list; From b09fce84a40c0c806eac3a2de58d97ae69b167ce Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Mon, 16 May 2016 22:01:30 +0100 Subject: [PATCH 10/45] just use a forward declaration for C++ iterator types to fix enum errors --- Lib/java/std_list.i | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 35f0ecac8..0dde17371 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -20,8 +20,7 @@ namespace std { template class list { public: - // This typedef is a weird hack to make stuff work - typedef std::list::iterator iterator; + struct iterator; typedef size_t size_type; typedef T value_type; typedef T& reference; From 9ade17cc5011e09adc4f863618ac324b42854abb Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Tue, 24 May 2016 22:03:53 +0100 Subject: [PATCH 11/45] Drop non-const reference from autobox typemap macro to be consistent. --- Lib/java/autobox.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/java/autobox.i b/Lib/java/autobox.i index 0146faa76..aae197ad8 100644 --- a/Lib/java/autobox.i +++ b/Lib/java/autobox.i @@ -1,6 +1,6 @@ // Java typemaps for autoboxing in return types of generics %define AUTOBOX(CTYPE, JTYPE) -%typemap(autobox) CTYPE, const CTYPE&, CTYPE& "JTYPE" +%typemap(autobox) CTYPE, const CTYPE& "JTYPE" %enddef AUTOBOX(double, Double) AUTOBOX(float, Float) From e561a78205643973318cbbfef5c2376968e9176d Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Tue, 24 May 2016 22:28:59 +0100 Subject: [PATCH 12/45] Added a best case workaround for std::list::size_type vs jint problem. There's a bit of commentry added around it too for clarity. --- Lib/java/std_list.i | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 0dde17371..959fdf25d 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -1,5 +1,5 @@ +%include %include -%include %{ #include @@ -17,6 +17,18 @@ %javamethodmodifiers std::list::advance "private"; %javamethodmodifiers std::list::has_next "private"; +/* + To conform to Java Collection interface we must return int from size(). + Unfortunately that loses precision from the integer types commonly used in + C++ implementations. Since we can't overload on return values the best + workaround here is to expose the real C++ size() return value to Java as a + long under a different name. We can then wrap that with a Java specific + size() implementation that at least checks and fails gracefully in the case + where we have a collection with > 2^31-1 items rather than failing + mysteriously. The wrapper implementaiton is in the javacode typemap later. +*/ +%rename(realSize) std::list::size; + namespace std { template class list { public: @@ -41,8 +53,7 @@ namespace std { void push_back(const value_type &x); void push_front(const value_type &x); - // Possible bug: jint != size_type - jint size () const; + size_type size() const; // Although sort() is nice it makes operator<() mandatory which it probably shouldn't be //void sort(); @@ -109,6 +120,14 @@ namespace std { } } + public int size() { + final long val = realSize(); + if (val > Integer.MAX_VALUE) { + throw new IndexOutOfBoundsException("Size of Collection $javaclassname is not representable as int"); + } + return (int)val; + } + public ListIterator listIterator(int index) { return new ListIterator() { private JAVA_ITERATOR_TYPE pos; From c78a005a294cf919b3fe1c8949d9935e92b71375 Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Tue, 31 May 2016 14:51:37 +0100 Subject: [PATCH 13/45] Removed typedef from li_std_list test as it's not expected to work properly in templated code --- Examples/test-suite/li_std_list.i | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Examples/test-suite/li_std_list.i b/Examples/test-suite/li_std_list.i index 54b4cdfea..3a2d761ff 100644 --- a/Examples/test-suite/li_std_list.i +++ b/Examples/test-suite/li_std_list.i @@ -14,12 +14,8 @@ namespace std { %template(DoubleList) std::list; -%inline %{ -typedef float Real; -%} - namespace std { - %template(RealList) list; + %template(RealList) list; } %inline %{ @@ -53,4 +49,4 @@ enum Fruit { %template(StructPtrList) std::list; %template(StructConstPtrList) std::list; -%template(FruitList) std::list; +%template(FruitList) std::list; From 583fdce790a00ae4cec5fb1cd55f3dfc6d916dc5 Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Tue, 31 May 2016 20:22:39 +0100 Subject: [PATCH 14/45] Moving iterator functionality into nested Java class now. --- Lib/java/std_list.i | 66 +++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 959fdf25d..1e126e35e 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -29,13 +29,41 @@ */ %rename(realSize) std::list::size; +%nodefaultctor std::list::iterator; + namespace std { template class list { public: - struct iterator; typedef size_t size_type; typedef T value_type; typedef T& reference; + struct iterator { + %extend { + void set_unchecked(const value_type& v) { + **$self = v; + } + + iterator next_unchecked() const { + std::list::iterator ret=*$self; + ++ret; + return ret; + } + + iterator previous_unchecked() const { + std::list::iterator ret=*$self; + --ret; + return ret; + } + + value_type deref_unchecked() const { + return **$self; + } + + void advance_unchecked(jint index) { + std::advance(*$self, index); + } + } + }; void assign(size_type n, const value_type &val); @@ -58,15 +86,11 @@ namespace std { // Although sort() is nice it makes operator<() mandatory which it probably shouldn't be //void sort(); - // Only for helping implement listIterator iterator begin(); + iterator end(); iterator insert(iterator pos, const value_type &v); %extend { - static void set(iterator pos, const value_type& v) { - *pos = v; - } - jint previous_index(const iterator& pos) const { return pos == self->begin() ? -1 : std::distance(self->begin(), static_cast::const_iterator>(pos)); } @@ -75,22 +99,6 @@ namespace std { return pos == self->end() ? self->size() : std::distance(self->begin(), static_cast::const_iterator>(pos)); } - static iterator next(iterator pos) { - return ++pos; - } - - static iterator previous(iterator pos) { - return --pos; - } - - static value_type deref(const iterator& pos) { - return *pos; - } - - static void advance(iterator& pos, jint index) { - std::advance(pos, index); - } - bool has_next(const iterator& pos) const { return pos != $self->end(); } @@ -108,7 +116,7 @@ namespace std { %typemap(javabase) std::list "AbstractSequentialList<$typemap(autobox,$1_basetype::value_type)>" #define JAVA_VALUE_TYPE $typemap(autobox,$1_basetype::value_type) -#define JAVA_ITERATOR_TYPE $typemap(jstype, $1_basetype::iterator) +#define JAVA_ITERATOR_TYPE iterator %typemap(javacode,noblock=1) std::list { public $javaclassname(Collection c) { @@ -135,7 +143,7 @@ namespace std { private ListIterator init(int index) { pos = $javaclassname.this.begin(); - $javaclassname.advance(pos, index); + pos.advance_unchecked(index); return this; } @@ -148,7 +156,7 @@ namespace std { if (null==last) { throw new IllegalStateException(); } - $javaclassname.set(last, v); + last.set_unchecked(v); } public void remove() { @@ -172,8 +180,8 @@ namespace std { throw new NoSuchElementException(); } last = pos; - pos = $javaclassname.previous(pos); - return $javaclassname.deref(last); + pos = pos.previous_unchecked(); + return last.deref_unchecked(); } public JAVA_VALUE_TYPE next() { @@ -181,8 +189,8 @@ namespace std { throw new NoSuchElementException(); } last = pos; - pos = $javaclassname.next(pos); - return $javaclassname.deref(last); + pos = pos.next_unchecked(); + return last.deref_unchecked(); } public boolean hasPrevious() { From 1f4a8e62314d42200447ee30ebf63b829cf7b462 Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Tue, 31 May 2016 20:27:16 +0100 Subject: [PATCH 15/45] Java style fix: iterator->Iterator --- Lib/java/std_list.i | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 1e126e35e..cc14d7353 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -29,6 +29,9 @@ */ %rename(realSize) std::list::size; +// Match Java style better: +%rename(Iterator) std::list::iterator; + %nodefaultctor std::list::iterator; namespace std { @@ -116,7 +119,7 @@ namespace std { %typemap(javabase) std::list "AbstractSequentialList<$typemap(autobox,$1_basetype::value_type)>" #define JAVA_VALUE_TYPE $typemap(autobox,$1_basetype::value_type) -#define JAVA_ITERATOR_TYPE iterator +#define JAVA_ITERATOR_TYPE Iterator %typemap(javacode,noblock=1) std::list { public $javaclassname(Collection c) { From 00ac1f38e590618e72a5ba3a46cd732b17123db2 Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Tue, 31 May 2016 20:50:29 +0100 Subject: [PATCH 16/45] Comment on consideration of making iterator non-static. --- Lib/java/std_list.i | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index cc14d7353..dbce830c2 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -40,6 +40,16 @@ namespace std { typedef size_t size_type; typedef T value_type; typedef T& reference; + + /* + * We'd actually be better off having the nested class *not* be static in the wrapper + * output, but this doesn't actually remove the $static from the nested class still. + * (This would allow us to somewhat simplify the implementation of the ListIterator + * interface and give "natural" semantics to Java users of the C++ iterator) + */ + //%typemap(javaclassmodifiers) iterator "public class" + //%typemap(javainterfaces) iterator "ListIterator<$typemap(autobox,$1_basetype::value_type)>" + struct iterator { %extend { void set_unchecked(const value_type& v) { From 5eb46d5f9f106c8367f65ff499d19a6af6c438af Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Tue, 31 May 2016 20:52:58 +0100 Subject: [PATCH 17/45] Be consistent in semantics of %extend on std::list::iterator --- Lib/java/std_list.i | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index dbce830c2..330bff854 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -72,8 +72,10 @@ namespace std { return **$self; } - void advance_unchecked(jint index) { - std::advance(*$self, index); + iterator advance_unchecked(jint index) const { + std::list::iterator ret=*$self; + std::advance(ret, index); + return ret; } } }; @@ -156,7 +158,7 @@ namespace std { private ListIterator init(int index) { pos = $javaclassname.this.begin(); - pos.advance_unchecked(index); + pos = pos.advance_unchecked(index); return this; } From c5a724f1bb1bfbcf4c0b68a9e85e62d476501dd2 Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Tue, 31 May 2016 21:34:48 +0100 Subject: [PATCH 18/45] Made the conversion from long->int for size_type mapping onto Java interfaces cleaner. --- Lib/java/std_list.i | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 330bff854..ac786910a 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -22,12 +22,24 @@ Unfortunately that loses precision from the integer types commonly used in C++ implementations. Since we can't overload on return values the best workaround here is to expose the real C++ size() return value to Java as a - long under a different name. We can then wrap that with a Java specific - size() implementation that at least checks and fails gracefully in the case - where we have a collection with > 2^31-1 items rather than failing - mysteriously. The wrapper implementaiton is in the javacode typemap later. + long and use the javaout typemap to validate. We can then at least fails + gracefully in the case where we have a collection with > 2^31-1 items rather + than failing mysteriously. + + The use of SWIG_list_size_type here allows us to selectively %apply this to + only the cases where we have to conform to the Java interface requirement, + without interfering with other size_type usage. The intention is that + SWIG_list_size_type is both reserved and unique. (Perhaps it could live in + std_common.i later on?) */ -%rename(realSize) std::list::size; +%typemap(jstype) SWIG_list_size_type "int"; +%typemap(javaout) SWIG_list_size_type { + final long result = $jnicall; + if (result > Integer.MAX_VALUE) { + throw new IndexOutOfBoundsException("Size of Collection is not representable as int"); + } + return (int)result; +} // Match Java style better: %rename(Iterator) std::list::iterator; @@ -40,6 +52,7 @@ namespace std { typedef size_t size_type; typedef T value_type; typedef T& reference; + %apply SWIG_list_size_type { size_type next_index, size_type previous_index, size_type size }; /* * We'd actually be better off having the nested class *not* be static in the wrapper @@ -72,7 +85,7 @@ namespace std { return **$self; } - iterator advance_unchecked(jint index) const { + iterator advance_unchecked(const size_type index) const { std::list::iterator ret=*$self; std::advance(ret, index); return ret; @@ -106,11 +119,11 @@ namespace std { iterator insert(iterator pos, const value_type &v); %extend { - jint previous_index(const iterator& pos) const { + size_type previous_index(const iterator& pos) const { return pos == self->begin() ? -1 : std::distance(self->begin(), static_cast::const_iterator>(pos)); } - jint next_index(const iterator& pos) const { + size_type next_index(const iterator& pos) const { return pos == self->end() ? self->size() : std::distance(self->begin(), static_cast::const_iterator>(pos)); } @@ -143,14 +156,6 @@ namespace std { } } - public int size() { - final long val = realSize(); - if (val > Integer.MAX_VALUE) { - throw new IndexOutOfBoundsException("Size of Collection $javaclassname is not representable as int"); - } - return (int)val; - } - public ListIterator listIterator(int index) { return new ListIterator() { private JAVA_ITERATOR_TYPE pos; From 3908817fc39625fb76b49c9f96d9e535f6450d8e Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Tue, 31 May 2016 22:11:15 +0100 Subject: [PATCH 19/45] Document autobox.i --- Lib/java/autobox.i | 60 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/Lib/java/autobox.i b/Lib/java/autobox.i index aae197ad8..9fe6b995c 100644 --- a/Lib/java/autobox.i +++ b/Lib/java/autobox.i @@ -1,4 +1,62 @@ -// Java typemaps for autoboxing in return types of generics +/* + Java typemaps for autoboxing in return types of generics. + + Java generics let you define interfaces, e.g. Collection which operate on any homogenous + collection of Objects, with compile time type checking. For example Collection can + only store String objects and the compiler helps enforce that. + + Unfortunately Java treats primitive types as a special case. They're not first class objects, + so in order to have a collection of ints we have to actually maintain a Collection. + For each primitive type in Java (boolean, byte, short, int, long, float, double) there + exists a corresponding "proper" Object type in java.lang.*. + + Although these proper Objects include a constructor and a xValue() method that allow for + explicit conversion between primitives and the corresponding Object type if programmers + were required to explicitly perform this conversion every time it would rapidly become + tedious for no real benefits. To address this the language designers introduced the + concepts of "autoboxing" and a corresponding unboxing which can happen implicitly. Thus it + becomes legal to write: + + Collection c = new ArrayList(); + double d1 = 0; + c.add(d1); // 1: void add(Double); + double d2 = c.iterator().next(); // 2: Double next(); + + The conversions required to allow lines commented 1: and 2: to compile are inserted + implicitly. + + When it comes to wrapping primitives from C or C++ code to Java SWIG by default take the path + most expected. This means that double in C++ is represented by double in Java etc. as expected. + Normally this behaviour is ideal, however when it comes to wrapping C++ templates which are + being mapped onto implementations of Java interfaces this behaviour is unhelpful because it + is a syntax error in Java to claim to implement Collection instead of + Collection. + + So to transparently allow a C++ template when wrapped to Java to accept template type + parameters of primitive, struct, enum etc. fluidly from the user perspective we need to support + the same mapping, outside of the normal default. + + This autobox typemap exists to solve exactly that problem. With it we can map primitives onto + the corresponding java.lang.* type, whilst mapping all other types onto type that they would + usually map onto. (That is to say it falls back to simply be the result of the jstype typemap + for all non-primitive types). + + So for example if a given container template in exists in C++: + + template + struct ExampleContainer { + typedef T value_type; + // ..... + }; + + When wrapped in Java we'd like it to implement the Collection interface correctly, even for + primitives. With these autobox typemaps we can now simply write the following for example: + + %typemap(javabase) ExampleContainer "Collection<$typemap(autobox,$1_basetype::value_type)>" + + Which does exactly the right thing for both primitive and non-primitive types. + +*/ %define AUTOBOX(CTYPE, JTYPE) %typemap(autobox) CTYPE, const CTYPE& "JTYPE" %enddef From 0083d451db637a625069ef340ff87f336585bf0b Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Mon, 5 Jun 2017 21:57:23 +0100 Subject: [PATCH 20/45] Switched from autobox to jboxtype per #842 --- Lib/java/autobox.i | 70 --------------------------------------------- Lib/java/std_list.i | 7 ++--- 2 files changed, 3 insertions(+), 74 deletions(-) delete mode 100644 Lib/java/autobox.i diff --git a/Lib/java/autobox.i b/Lib/java/autobox.i deleted file mode 100644 index 9fe6b995c..000000000 --- a/Lib/java/autobox.i +++ /dev/null @@ -1,70 +0,0 @@ -/* - Java typemaps for autoboxing in return types of generics. - - Java generics let you define interfaces, e.g. Collection which operate on any homogenous - collection of Objects, with compile time type checking. For example Collection can - only store String objects and the compiler helps enforce that. - - Unfortunately Java treats primitive types as a special case. They're not first class objects, - so in order to have a collection of ints we have to actually maintain a Collection. - For each primitive type in Java (boolean, byte, short, int, long, float, double) there - exists a corresponding "proper" Object type in java.lang.*. - - Although these proper Objects include a constructor and a xValue() method that allow for - explicit conversion between primitives and the corresponding Object type if programmers - were required to explicitly perform this conversion every time it would rapidly become - tedious for no real benefits. To address this the language designers introduced the - concepts of "autoboxing" and a corresponding unboxing which can happen implicitly. Thus it - becomes legal to write: - - Collection c = new ArrayList(); - double d1 = 0; - c.add(d1); // 1: void add(Double); - double d2 = c.iterator().next(); // 2: Double next(); - - The conversions required to allow lines commented 1: and 2: to compile are inserted - implicitly. - - When it comes to wrapping primitives from C or C++ code to Java SWIG by default take the path - most expected. This means that double in C++ is represented by double in Java etc. as expected. - Normally this behaviour is ideal, however when it comes to wrapping C++ templates which are - being mapped onto implementations of Java interfaces this behaviour is unhelpful because it - is a syntax error in Java to claim to implement Collection instead of - Collection. - - So to transparently allow a C++ template when wrapped to Java to accept template type - parameters of primitive, struct, enum etc. fluidly from the user perspective we need to support - the same mapping, outside of the normal default. - - This autobox typemap exists to solve exactly that problem. With it we can map primitives onto - the corresponding java.lang.* type, whilst mapping all other types onto type that they would - usually map onto. (That is to say it falls back to simply be the result of the jstype typemap - for all non-primitive types). - - So for example if a given container template in exists in C++: - - template - struct ExampleContainer { - typedef T value_type; - // ..... - }; - - When wrapped in Java we'd like it to implement the Collection interface correctly, even for - primitives. With these autobox typemaps we can now simply write the following for example: - - %typemap(javabase) ExampleContainer "Collection<$typemap(autobox,$1_basetype::value_type)>" - - Which does exactly the right thing for both primitive and non-primitive types. - -*/ -%define AUTOBOX(CTYPE, JTYPE) -%typemap(autobox) CTYPE, const CTYPE& "JTYPE" -%enddef -AUTOBOX(double, Double) -AUTOBOX(float, Float) -AUTOBOX(boolean, Boolean) -AUTOBOX(signed char, Byte) -AUTOBOX(short, Short) -AUTOBOX(int, Integer) -AUTOBOX(long, Long) -AUTOBOX(SWIGTYPE, $typemap(jstype,$1_basetype)) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index ac786910a..804223efd 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -1,5 +1,4 @@ %include -%include %{ #include @@ -61,7 +60,7 @@ namespace std { * interface and give "natural" semantics to Java users of the C++ iterator) */ //%typemap(javaclassmodifiers) iterator "public class" - //%typemap(javainterfaces) iterator "ListIterator<$typemap(autobox,$1_basetype::value_type)>" + //%typemap(javainterfaces) iterator "ListIterator<$typemap(jboxtype,$1_basetype::value_type)>" struct iterator { %extend { @@ -141,9 +140,9 @@ namespace std { import java.util.Collection; %} -%typemap(javabase) std::list "AbstractSequentialList<$typemap(autobox,$1_basetype::value_type)>" +%typemap(javabase) std::list "AbstractSequentialList<$typemap(jboxtype,$1_basetype::value_type)>" -#define JAVA_VALUE_TYPE $typemap(autobox,$1_basetype::value_type) +#define JAVA_VALUE_TYPE $typemap(jboxtype,$1_basetype::value_type) #define JAVA_ITERATOR_TYPE Iterator %typemap(javacode,noblock=1) std::list { From 0695cb72cb9727ea8ffbe7a41674f91a8f389a3c Mon Sep 17 00:00:00 2001 From: Alan Woodland Date: Mon, 5 Jun 2017 22:09:41 +0100 Subject: [PATCH 21/45] re-enabled li_std_list test --- Examples/test-suite/common.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index f68451f87..11b1446e0 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -600,8 +600,8 @@ CPP_STD_TEST_CASES += \ smart_pointer_inherit \ template_typedef_fnc \ template_type_namespace \ - template_opaque -# li_std_list + template_opaque \ + li_std_list ifndef SKIP_CPP_STD_CASES From fa416e4d4092331d6d77129adfe9c5d202903f2f Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 21 Jun 2017 15:51:52 +0100 Subject: [PATCH 22/45] li_std_list testcase not working for most languages --- Examples/test-suite/common.mk | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 11b1446e0..146ada2c6 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -99,7 +99,7 @@ CPP_TEST_BROKEN += \ # Broken C test cases. (Can be run individually using: make testcase.ctest) C_TEST_BROKEN += \ - tag_no_clash_with_variable + tag_no_clash_with_variable \ # C++ test cases. (Can be run individually using: make testcase.cpptest) CPP_TEST_CASES += \ @@ -533,7 +533,7 @@ CPP_TEST_CASES += \ virtual_vs_nonvirtual_base \ voidtest \ wallkw \ - wrapmacro + wrapmacro \ # C++11 test cases. CPP11_TEST_CASES += \ @@ -601,8 +601,6 @@ CPP_STD_TEST_CASES += \ template_typedef_fnc \ template_type_namespace \ template_opaque \ - li_std_list - ifndef SKIP_CPP_STD_CASES CPP_TEST_CASES += ${CPP_STD_TEST_CASES} @@ -666,7 +664,7 @@ C_TEST_CASES += \ typedef_struct \ typemap_subst \ union_parameter \ - unions + unions \ # Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest) @@ -677,7 +675,7 @@ MULTI_CPP_TEST_CASES += \ packageoption \ mod \ template_typedef_import \ - multi_import + multi_import \ # Custom tests - tests with additional commandline options wallkw.cpptest: SWIGOPT += -Wallkw From dd25f5b722499aa1ec9220ce5b70142c869d6b26 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 22 Jun 2017 11:47:56 +0100 Subject: [PATCH 23/45] Java std::list rework to be consistent with std::vector wrappers --- Lib/java/std_list.i | 274 +++++++++++++++++++++----------------------- 1 file changed, 128 insertions(+), 146 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 804223efd..70bb6e20a 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -2,56 +2,134 @@ %{ #include -#include +#include %} +%fragment("SWIG_ListSize", "header", fragment="SWIG_JavaIntFromSize_t") { +SWIGINTERN jint SWIG_ListSize(size_t size) { + jint sz = SWIG_JavaIntFromSize_t(size); + if (sz == -1) + throw std::out_of_range("list size is too large to fit into a Java int"); + return sz; +} +} + %javamethodmodifiers std::list::begin "private"; %javamethodmodifiers std::list::insert "private"; %javamethodmodifiers std::list::set "private"; -%javamethodmodifiers std::list::previous_index "private"; -%javamethodmodifiers std::list::next_index "private"; %javamethodmodifiers std::list::previous "private"; %javamethodmodifiers std::list::next "private"; %javamethodmodifiers std::list::deref "private"; %javamethodmodifiers std::list::advance "private"; -%javamethodmodifiers std::list::has_next "private"; - -/* - To conform to Java Collection interface we must return int from size(). - Unfortunately that loses precision from the integer types commonly used in - C++ implementations. Since we can't overload on return values the best - workaround here is to expose the real C++ size() return value to Java as a - long and use the javaout typemap to validate. We can then at least fails - gracefully in the case where we have a collection with > 2^31-1 items rather - than failing mysteriously. - - The use of SWIG_list_size_type here allows us to selectively %apply this to - only the cases where we have to conform to the Java interface requirement, - without interfering with other size_type usage. The intention is that - SWIG_list_size_type is both reserved and unique. (Perhaps it could live in - std_common.i later on?) -*/ -%typemap(jstype) SWIG_list_size_type "int"; -%typemap(javaout) SWIG_list_size_type { - final long result = $jnicall; - if (result > Integer.MAX_VALUE) { - throw new IndexOutOfBoundsException("Size of Collection is not representable as int"); - } - return (int)result; -} +%javamethodmodifiers std::list::doSize "private"; +%javamethodmodifiers std::list::doPreviousIndex "private"; +%javamethodmodifiers std::list::doNextIndex "private"; +%javamethodmodifiers std::list::doHasNext "private"; // Match Java style better: %rename(Iterator) std::list::iterator; %nodefaultctor std::list::iterator; +%typemap(javaimports) std::list %{ + import java.util.AbstractSequentialList; + import java.util.ListIterator; + import java.util.NoSuchElementException; + import java.util.Collection; +%} + +%typemap(javabase) std::list "AbstractSequentialList<$typemap(jboxtype, $1_basetype::value_type)>" + namespace std { template class list { + +%proxycode %{ + public $javaclassname(Collection c) { + this(); + ListIterator<$typemap(jboxtype, T)> it = listIterator(0); + // Special case the "copy constructor" here to avoid lots of cross-language calls + for (Object o : c) { + it.add(($typemap(jboxtype, T))o); + } + } + + public int size() { + return doSize(); + } + + public ListIterator<$typemap(jboxtype, T)> listIterator(int index) { + return new ListIterator<$typemap(jboxtype, T)>() { + private Iterator pos; + private Iterator last; + + private ListIterator<$typemap(jboxtype, T)> init(int index) { + pos = $javaclassname.this.begin(); + pos = pos.advance_unchecked(index); + return this; + } + + public void add($typemap(jboxtype, T) v) { + // Technically we can invalidate last here, but this makes more sense + last = $javaclassname.this.insert(pos, v); + } + + public void set($typemap(jboxtype, T) v) { + if (null == last) { + throw new IllegalStateException(); + } + last.set_unchecked(v); + } + + public void remove() { + if (null == last) { + throw new IllegalStateException(); + } + $javaclassname.this.remove(last); + last = null; + } + + public int previousIndex() { + return $javaclassname.this.doPreviousIndex(pos); + } + + public int nextIndex() { + return $javaclassname.this.doNextIndex(pos); + } + + public $typemap(jboxtype, T) previous() { + if (previousIndex() < 0) { + throw new NoSuchElementException(); + } + last = pos; + pos = pos.previous_unchecked(); + return last.deref_unchecked(); + } + + public $typemap(jboxtype, T) next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + last = pos; + pos = pos.next_unchecked(); + return last.deref_unchecked(); + } + + public boolean hasPrevious() { + // This call to previousIndex() will be much slower than the hasNext() implementation, but it's simpler like this with C++ forward iterators + return previousIndex() != -1; + } + + public boolean hasNext() { + return $javaclassname.this.doHasNext(pos); + } + }.init(index); + } +%} + public: typedef size_t size_type; typedef T value_type; - typedef T& reference; - %apply SWIG_list_size_type { size_type next_index, size_type previous_index, size_type size }; + typedef T &reference; /* * We'd actually be better off having the nested class *not* be static in the wrapper @@ -60,22 +138,22 @@ namespace std { * interface and give "natural" semantics to Java users of the C++ iterator) */ //%typemap(javaclassmodifiers) iterator "public class" - //%typemap(javainterfaces) iterator "ListIterator<$typemap(jboxtype,$1_basetype::value_type)>" + //%typemap(javainterfaces) iterator "ListIterator<$typemap(jboxtype, $1_basetype::value_type)>" struct iterator { %extend { - void set_unchecked(const value_type& v) { + void set_unchecked(const value_type &v) { **$self = v; } iterator next_unchecked() const { - std::list::iterator ret=*$self; + std::list::iterator ret = *$self; ++ret; return ret; } iterator previous_unchecked() const { - std::list::iterator ret=*$self; + std::list::iterator ret = *$self; --ret; return ret; } @@ -85,141 +163,45 @@ namespace std { } iterator advance_unchecked(const size_type index) const { - std::list::iterator ret=*$self; + std::list::iterator ret = *$self; std::advance(ret, index); return ret; } } }; - void assign(size_type n, const value_type &val); - - bool empty() const; - - list(size_type n, const value_type &value=value_type()); - list(const list &o); list(); + list(size_type n, const value_type &value = value_type()); + list(const list &o); ~list(); - - size_type max_size () const; - + void assign(size_type n, const value_type &val); + bool empty() const; + size_type max_size() const; void pop_back(); void pop_front(); void push_back(const value_type &x); void push_front(const value_type &x); - - size_type size() const; - - // Although sort() is nice it makes operator<() mandatory which it probably shouldn't be - //void sort(); - iterator begin(); iterator end(); iterator insert(iterator pos, const value_type &v); %extend { - size_type previous_index(const iterator& pos) const { - return pos == self->begin() ? -1 : std::distance(self->begin(), static_cast::const_iterator>(pos)); + %fragment("SWIG_ListSize"); + jint doSize() const throw (std::out_of_range) { + return SWIG_ListSize(self->size()); } - size_type next_index(const iterator& pos) const { - return pos == self->end() ? self->size() : std::distance(self->begin(), static_cast::const_iterator>(pos)); + jint doPreviousIndex(const iterator &pos) const { + return pos == self->begin() ? -1 : SWIG_ListSize(std::distance(self->begin(), static_cast::const_iterator>(pos))); } - bool has_next(const iterator& pos) const { + jint doNextIndex(const iterator &pos) const { + return pos == self->end() ? self->size() : SWIG_ListSize(std::distance(self->begin(), static_cast::const_iterator>(pos))); + } + + bool doHasNext(const iterator &pos) const { return pos != $self->end(); } } }; } - -%typemap(javaimports) std::list %{ - import java.util.AbstractSequentialList; - import java.util.ListIterator; - import java.util.NoSuchElementException; - import java.util.Collection; -%} - -%typemap(javabase) std::list "AbstractSequentialList<$typemap(jboxtype,$1_basetype::value_type)>" - -#define JAVA_VALUE_TYPE $typemap(jboxtype,$1_basetype::value_type) -#define JAVA_ITERATOR_TYPE Iterator - -%typemap(javacode,noblock=1) std::list { - public $javaclassname(Collection c) { - this(); - ListIterator it = listIterator(0); - // We should special case the "copy constructor" here to avoid lots of cross-language calls - for (Object o: c) { - it.add((JAVA_VALUE_TYPE)o); - } - } - - public ListIterator listIterator(int index) { - return new ListIterator() { - private JAVA_ITERATOR_TYPE pos; - private JAVA_ITERATOR_TYPE last; - - private ListIterator init(int index) { - pos = $javaclassname.this.begin(); - pos = pos.advance_unchecked(index); - return this; - } - - public void add(JAVA_VALUE_TYPE v) { - // Technically we can invalidate last here, but this makes more sense - last=$javaclassname.this.insert(pos, v); - } - - public void set(JAVA_VALUE_TYPE v) { - if (null==last) { - throw new IllegalStateException(); - } - last.set_unchecked(v); - } - - public void remove() { - if (null==last) { - throw new IllegalStateException(); - } - $javaclassname.this.remove(last); - last=null; - } - - public int previousIndex() { - return $javaclassname.this.previous_index(pos); - } - - public int nextIndex() { - return $javaclassname.this.next_index(pos); - } - - public JAVA_VALUE_TYPE previous() { - if (previousIndex() < 0) { - throw new NoSuchElementException(); - } - last = pos; - pos = pos.previous_unchecked(); - return last.deref_unchecked(); - } - - public JAVA_VALUE_TYPE next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - last = pos; - pos = pos.next_unchecked(); - return last.deref_unchecked(); - } - - public boolean hasPrevious() { - // This call to previousIndex() will be much slower than the hasNext() implementation, but it's simpler like this with C++ forward iterators - return previousIndex() != -1; - } - - public boolean hasNext() { - return $javaclassname.this.has_next(pos); - } - }.init(index); - } -} From 02a00db9f5a765daeb7e663a783340edbe2bf51e Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 22 Jun 2017 20:30:11 +0100 Subject: [PATCH 24/45] Remove redundant code --- Lib/java/std_list.i | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 70bb6e20a..070f6a606 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -16,11 +16,6 @@ SWIGINTERN jint SWIG_ListSize(size_t size) { %javamethodmodifiers std::list::begin "private"; %javamethodmodifiers std::list::insert "private"; -%javamethodmodifiers std::list::set "private"; -%javamethodmodifiers std::list::previous "private"; -%javamethodmodifiers std::list::next "private"; -%javamethodmodifiers std::list::deref "private"; -%javamethodmodifiers std::list::advance "private"; %javamethodmodifiers std::list::doSize "private"; %javamethodmodifiers std::list::doPreviousIndex "private"; %javamethodmodifiers std::list::doNextIndex "private"; From 7b7f921ccb9e1e4de193f073d07af87445ecb393 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 22 Jun 2017 20:38:19 +0100 Subject: [PATCH 25/45] cosmetics --- Lib/java/std_list.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 070f6a606..f9986b11e 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -157,7 +157,7 @@ namespace std { return **$self; } - iterator advance_unchecked(const size_type index) const { + iterator advance_unchecked(size_type index) const { std::list::iterator ret = *$self; std::advance(ret, index); return ret; From 430376e1159eb578537de7c88b1dc9264d4128a8 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 22 Jun 2017 21:49:58 +0100 Subject: [PATCH 26/45] Java std::list - fully qualifiy Java class name to avoid potential name ambiguity --- Lib/java/std_list.i | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index f9986b11e..c6f074417 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -26,22 +26,15 @@ SWIGINTERN jint SWIG_ListSize(size_t size) { %nodefaultctor std::list::iterator; -%typemap(javaimports) std::list %{ - import java.util.AbstractSequentialList; - import java.util.ListIterator; - import java.util.NoSuchElementException; - import java.util.Collection; -%} - -%typemap(javabase) std::list "AbstractSequentialList<$typemap(jboxtype, $1_basetype::value_type)>" +%typemap(javabase) std::list "java.util.AbstractSequentialList<$typemap(jboxtype, $1_basetype::value_type)>" namespace std { template class list { %proxycode %{ - public $javaclassname(Collection c) { + public $javaclassname(java.util.Collection c) { this(); - ListIterator<$typemap(jboxtype, T)> it = listIterator(0); + java.util.ListIterator<$typemap(jboxtype, T)> it = listIterator(0); // Special case the "copy constructor" here to avoid lots of cross-language calls for (Object o : c) { it.add(($typemap(jboxtype, T))o); @@ -52,12 +45,12 @@ namespace std { return doSize(); } - public ListIterator<$typemap(jboxtype, T)> listIterator(int index) { - return new ListIterator<$typemap(jboxtype, T)>() { + public java.util.ListIterator<$typemap(jboxtype, T)> listIterator(int index) { + return new java.util.ListIterator<$typemap(jboxtype, T)>() { private Iterator pos; private Iterator last; - private ListIterator<$typemap(jboxtype, T)> init(int index) { + private java.util.ListIterator<$typemap(jboxtype, T)> init(int index) { pos = $javaclassname.this.begin(); pos = pos.advance_unchecked(index); return this; @@ -93,7 +86,7 @@ namespace std { public $typemap(jboxtype, T) previous() { if (previousIndex() < 0) { - throw new NoSuchElementException(); + throw new java.util.NoSuchElementException(); } last = pos; pos = pos.previous_unchecked(); @@ -102,7 +95,7 @@ namespace std { public $typemap(jboxtype, T) next() { if (!hasNext()) { - throw new NoSuchElementException(); + throw new java.util.NoSuchElementException(); } last = pos; pos = pos.next_unchecked(); @@ -133,7 +126,7 @@ namespace std { * interface and give "natural" semantics to Java users of the C++ iterator) */ //%typemap(javaclassmodifiers) iterator "public class" - //%typemap(javainterfaces) iterator "ListIterator<$typemap(jboxtype, $1_basetype::value_type)>" + //%typemap(javainterfaces) iterator "java.util.ListIterator<$typemap(jboxtype, $1_basetype::value_type)>" struct iterator { %extend { From 109a60add684e1991285c35b024b53a076f45737 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 22 Jun 2017 22:17:59 +0100 Subject: [PATCH 27/45] javabase typemap improvement for std::list --- Lib/java/std_list.i | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index c6f074417..38742632e 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -26,11 +26,10 @@ SWIGINTERN jint SWIG_ListSize(size_t size) { %nodefaultctor std::list::iterator; -%typemap(javabase) std::list "java.util.AbstractSequentialList<$typemap(jboxtype, $1_basetype::value_type)>" - namespace std { template class list { +%typemap(javabase) std::list< T > "java.util.AbstractSequentialList<$typemap(jboxtype, T)>" %proxycode %{ public $javaclassname(java.util.Collection c) { this(); From 990c5973657bbf25d50d65fc3d40d8bf3b4df0a9 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 23 Jun 2017 15:26:53 +0100 Subject: [PATCH 28/45] Wrap std::list::empty as isEmpty in Java --- Examples/test-suite/java/li_std_list_runme.java | 7 ++++++- Lib/java/std_list.i | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Examples/test-suite/java/li_std_list_runme.java b/Examples/test-suite/java/li_std_list_runme.java index de53a9fa6..c3c666c51 100644 --- a/Examples/test-suite/java/li_std_list_runme.java +++ b/Examples/test-suite/java/li_std_list_runme.java @@ -16,7 +16,12 @@ public class li_std_list_runme { IntList v1 = new IntList(); DoubleList v2 = new DoubleList(); - v1.add(123); + if (!v1.isEmpty()) throw new RuntimeException("v1 test (1) failed"); + if (v1.size() != 0) throw new RuntimeException("v1 test (2) failed"); + if (!v1.add(123)) throw new RuntimeException("v1 test (3) failed"); + if (v1.size() != 1) throw new RuntimeException("v1 test (4) failed"); + if (v1.isEmpty()) throw new RuntimeException("v1 test (5) failed"); + if (v1.get(0) != 123) throw new RuntimeException("v1 test failed"); StructList v4 = new StructList(); diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 38742632e..8714be0f4 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -162,6 +162,7 @@ namespace std { list(const list &o); ~list(); void assign(size_type n, const value_type &val); + %rename(isEmpty) empty; bool empty() const; size_type max_size() const; void pop_back(); From 428b332e6845093abc68a1f704db714beaa86cf8 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 23 Jun 2017 15:35:10 +0100 Subject: [PATCH 29/45] Improve Java std::list std::vector runtime tests and wrap std::list::clear --- .../test-suite/java/li_std_list_runme.java | 13 +++++++++++ .../test-suite/java/li_std_vector_runme.java | 22 +++++++++++++------ Lib/java/std_list.i | 1 + 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Examples/test-suite/java/li_std_list_runme.java b/Examples/test-suite/java/li_std_list_runme.java index c3c666c51..05be034ff 100644 --- a/Examples/test-suite/java/li_std_list_runme.java +++ b/Examples/test-suite/java/li_std_list_runme.java @@ -22,7 +22,20 @@ public class li_std_list_runme { if (v1.size() != 1) throw new RuntimeException("v1 test (4) failed"); if (v1.isEmpty()) throw new RuntimeException("v1 test (5) failed"); + int sum = 0; + for (int n : v1) { + if (n != 123) throw new RuntimeException("v1 loop test failed"); + sum += n; + } + if (sum != 123) throw new RuntimeException("v1 sum test failed"); if (v1.get(0) != 123) throw new RuntimeException("v1 test failed"); + v1.clear(); + if (!v1.isEmpty()) throw new RuntimeException("v1 test clear failed"); + v1.add(123); + + if (v1.set(0, 456) != 123) throw new RuntimeException("v1 test (6) failed"); + if (v1.size() != 1) throw new RuntimeException("v1 test (7) failed"); + if (v1.get(0) != 456) throw new RuntimeException("v1 test (8) failed"); StructList v4 = new StructList(); StructPtrList v5 = new StructPtrList(); diff --git a/Examples/test-suite/java/li_std_vector_runme.java b/Examples/test-suite/java/li_std_vector_runme.java index 60776bbf1..56a2e4359 100644 --- a/Examples/test-suite/java/li_std_vector_runme.java +++ b/Examples/test-suite/java/li_std_vector_runme.java @@ -17,15 +17,23 @@ public class li_std_vector_runme { IntPtrVector v2 = li_std_vector.vecintptr(new IntPtrVector()); IntConstPtrVector v3 = li_std_vector.vecintconstptr(new IntConstPtrVector()); - for (int n : v1) { - if (n != 123) throw new RuntimeException("v1 loop test failed"); - } - if (!v1.isEmpty()) throw new RuntimeException("v1 test (1) failed"); if (v1.size() != 0) throw new RuntimeException("v1 test (2) failed"); if (!v1.add(123)) throw new RuntimeException("v1 test (3) failed"); if (v1.size() != 1) throw new RuntimeException("v1 test (4) failed"); if (v1.isEmpty()) throw new RuntimeException("v1 test (5) failed"); + + int sum = 0; + for (int n : v1) { + if (n != 123) throw new RuntimeException("v1 loop test failed"); + sum += n; + } + if (sum != 123) throw new RuntimeException("v1 sum test failed"); + if (v1.get(0) != 123) throw new RuntimeException("v1 test failed"); + v1.clear(); + if (!v1.isEmpty()) throw new RuntimeException("v1 test clear failed"); + v1.add(123); + if (v1.set(0, 456) != 123) throw new RuntimeException("v1 test (6) failed"); if (v1.size() != 1) throw new RuntimeException("v1 test (7) failed"); if (v1.get(0) != 456) throw new RuntimeException("v1 test (8) failed"); @@ -59,13 +67,13 @@ public class li_std_vector_runme { 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"); + 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"); + 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"); + if (s.getNum() != 56) throw new RuntimeException("v6 loop test failed"); } StructVector v7 = li_std_vector.vecstruct(new StructVector()); diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 8714be0f4..ab824e512 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -164,6 +164,7 @@ namespace std { void assign(size_type n, const value_type &val); %rename(isEmpty) empty; bool empty() const; + void clear(); size_type max_size() const; void pop_back(); void pop_front(); From 2d99027935a95d6b02bb6904bdbea1eff52c6f4d Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 23 Jun 2017 16:17:00 +0100 Subject: [PATCH 30/45] Fix removing elements from std::list Java wrapper Add missing remove method on Java side (without it elements aren't removed). --- Examples/test-suite/java/li_std_list_runme.java | 16 ++++++++++++++++ Lib/java/std_list.i | 2 ++ 2 files changed, 18 insertions(+) diff --git a/Examples/test-suite/java/li_std_list_runme.java b/Examples/test-suite/java/li_std_list_runme.java index 05be034ff..ca40db2f2 100644 --- a/Examples/test-suite/java/li_std_list_runme.java +++ b/Examples/test-suite/java/li_std_list_runme.java @@ -37,6 +37,22 @@ public class li_std_list_runme { if (v1.size() != 1) throw new RuntimeException("v1 test (7) failed"); if (v1.get(0) != 456) throw new RuntimeException("v1 test (8) failed"); + java.util.Iterator v1_iterator = v1.iterator(); + if (!v1_iterator.hasNext()) throw new RuntimeException("v1 test (9) failed"); + if (v1_iterator.next() != 456) throw new RuntimeException("v1 test (10) failed"); + if (v1_iterator.hasNext()) throw new RuntimeException("v1 test (11) failed"); + try { + v1_iterator.next(); + throw new RuntimeException("v1 test (12) failed"); + } catch (java.util.NoSuchElementException e) { + } + + if (v1.remove(new Integer(123))) throw new RuntimeException("v1 test (13) failed"); + if (!v1.remove(new Integer(456))) throw new RuntimeException("v1 test (14) failed"); + if (!v1.isEmpty()) throw new RuntimeException("v1 test (15) failed"); + if (v1.size() != 0) throw new RuntimeException("v1 test (16) failed"); + if (v1.remove(new Integer(456))) throw new RuntimeException("v1 test (17) failed"); + StructList v4 = new StructList(); StructPtrList v5 = new StructPtrList(); StructConstPtrList v6 = new StructConstPtrList(); diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index ab824e512..0eca5a970 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -165,6 +165,8 @@ namespace std { %rename(isEmpty) empty; bool empty() const; void clear(); + %rename(remove) erase; + iterator erase(iterator pos); size_type max_size() const; void pop_back(); void pop_front(); From b40b9aee83f25796aa64a2288a351ed55302e1ba Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 23 Jun 2017 20:10:26 +0100 Subject: [PATCH 31/45] Modify std::list declarations to match the C++ standard --- Lib/java/std_list.i | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 0eca5a970..0ce26ad0f 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -125,11 +125,11 @@ namespace std { * interface and give "natural" semantics to Java users of the C++ iterator) */ //%typemap(javaclassmodifiers) iterator "public class" - //%typemap(javainterfaces) iterator "java.util.ListIterator<$typemap(jboxtype, $1_basetype::value_type)>" + //%typemap(javainterfaces) iterator "java.util.ListIterator<$typemap(jboxtype, T)>" struct iterator { %extend { - void set_unchecked(const value_type &v) { + void set_unchecked(const T &v) { **$self = v; } @@ -145,7 +145,7 @@ namespace std { return ret; } - value_type deref_unchecked() const { + T deref_unchecked() const { return **$self; } @@ -158,10 +158,10 @@ namespace std { }; list(); - list(size_type n, const value_type &value = value_type()); - list(const list &o); + list(size_type n, const T &value = T()); + list(const list &other); ~list(); - void assign(size_type n, const value_type &val); + void assign(size_type n, const T &value); %rename(isEmpty) empty; bool empty() const; void clear(); @@ -170,11 +170,11 @@ namespace std { size_type max_size() const; void pop_back(); void pop_front(); - void push_back(const value_type &x); - void push_front(const value_type &x); + void push_back(const T &value); + void push_front(const T &value); iterator begin(); iterator end(); - iterator insert(iterator pos, const value_type &v); + iterator insert(iterator pos, const T &value); %extend { %fragment("SWIG_ListSize"); From ea55c5bba0596676668b23877e256a510a60807a Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 24 Jun 2017 14:21:34 +0100 Subject: [PATCH 32/45] Java std::vector std::list enhancements - Add missing vector copy constructor - Add constructor to initialize the containers. Note that Java's equivalent constructor for ArrayList just sets the capacity, whereas the wrappers behave like the C++ constructor and set the size. I've done this mainly because there has been a vector(size_type) constructor in the Java wrappers for many years, so best to keep this unchanged. --- .../test-suite/java/li_std_list_runme.java | 67 ++++++++++++++++++- .../test-suite/java/li_std_vector_runme.java | 6 ++ Examples/test-suite/li_std_list.i | 24 ++++--- Lib/java/std_list.i | 15 ++++- Lib/java/std_vector.i | 14 +++- 5 files changed, 114 insertions(+), 12 deletions(-) diff --git a/Examples/test-suite/java/li_std_list_runme.java b/Examples/test-suite/java/li_std_list_runme.java index ca40db2f2..f0e48804b 100644 --- a/Examples/test-suite/java/li_std_list_runme.java +++ b/Examples/test-suite/java/li_std_list_runme.java @@ -53,6 +53,12 @@ public class li_std_list_runme { if (v1.size() != 0) throw new RuntimeException("v1 test (16) failed"); if (v1.remove(new Integer(456))) throw new RuntimeException("v1 test (17) failed"); + if (new IntList(3).size() != 3) throw new RuntimeException("constructor initial size test failed"); + for (int n : new IntList(10, 999)) + if (n != 999) throw new RuntimeException("constructor initialization with value failed"); + for (int n : new IntList(new IntList(10, 999))) + if (n != 999) throw new RuntimeException("copy constructor initialization with value failed"); + StructList v4 = new StructList(); StructPtrList v5 = new StructPtrList(); StructConstPtrList v6 = new StructConstPtrList(); @@ -61,9 +67,68 @@ public class li_std_list_runme { v5.add(new Struct(34)); v6.add(new Struct(56)); - Struct s = null; 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 (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"); + } + + StructList v7 = li_std_list.CopyContainerStruct(new StructList()); + v7.add(new Struct(1)); + v7.add(new Struct(23)); + v7.add(new Struct(456)); + v7.add(new Struct(7890)); + if (v7.size() != 4) throw new RuntimeException("v7 test (1) failed"); + { + double[] a7 = {1, 23, 456, 7890}; + int i7 = 0; + for (Struct s7 : v7) { + if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (2) failed"); + i7++; + } + if (i7 != a7.length) throw new RuntimeException("v7 test (3) failed"); + } + if (v7.remove(2).getNum() != 456) throw new RuntimeException("v7 test (4) failed"); + { + double[] a7 = {1, 23, 7890}; + int i7 = 0; + for (Struct s7 : v7) { + if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (5) failed"); + i7++; + } + if (i7 != a7.length) throw new RuntimeException("v7 test (6) failed"); + } + v7.add(1, new Struct(123)); + { + double[] a7 = {1, 123, 23, 7890}; + int i7 = 0; + for (Struct s7 : v7) { + if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (7) failed"); + i7++; + } + if (i7 != a7.length) throw new RuntimeException("v7 test (8) failed"); + } + + BoolList v8 = new BoolList(); + if (!v8.add(true)) throw new RuntimeException("v8 test (1) failed");; + if (v8.get(0) != true) throw new RuntimeException("v8 test (2) failed");; + if (v8.set(0, false) != true) throw new RuntimeException("v8 test (3) failed");; + if (v8.set(0, false) != false) throw new RuntimeException("v8 test (4) failed");; + if (v8.size() != 1) throw new RuntimeException("v8 test (5) failed");; + + java.util.ArrayList bl = new java.util.ArrayList(java.util.Arrays.asList(true, false, true, false)); + BoolList bv = new BoolList(java.util.Arrays.asList(true, false, true, false)); + BoolList bv2 = new BoolList(bl); + java.util.ArrayList bl2 = new java.util.ArrayList(bv); + boolean bbb1 = bv.get(0); + Boolean bbb2 = bv.get(0); } } diff --git a/Examples/test-suite/java/li_std_vector_runme.java b/Examples/test-suite/java/li_std_vector_runme.java index 56a2e4359..b63df0210 100644 --- a/Examples/test-suite/java/li_std_vector_runme.java +++ b/Examples/test-suite/java/li_std_vector_runme.java @@ -54,6 +54,12 @@ public class li_std_vector_runme { if (v1.size() != 0) throw new RuntimeException("v1 test (16) failed"); if (v1.remove(new Integer(456))) throw new RuntimeException("v1 test (17) failed"); + if (new IntVector(3).size() != 3) throw new RuntimeException("constructor initial size test failed"); + for (int n : new IntVector(10, 999)) + if (n != 999) throw new RuntimeException("constructor initialization with value failed"); + for (int n : new IntVector(new IntVector(10, 999))) + if (n != 999) throw new RuntimeException("copy constructor initialization with value failed"); + StructVector v4 = li_std_vector.vecstruct(new StructVector()); StructPtrVector v5 = li_std_vector.vecstructptr(new StructPtrVector()); StructConstPtrVector v6 = li_std_vector.vecstructconstptr(new StructConstPtrVector()); diff --git a/Examples/test-suite/li_std_list.i b/Examples/test-suite/li_std_list.i index 3a2d761ff..d1ec4e7e4 100644 --- a/Examples/test-suite/li_std_list.i +++ b/Examples/test-suite/li_std_list.i @@ -1,6 +1,7 @@ %module li_std_list %include "std_list.i" +%include "std_string.i" %{ #include @@ -8,15 +9,18 @@ #include %} -namespace std { - %template(IntList) list; -} - +%template(BoolList) std::list; +%template(CharList) std::list; +%template(ShortList) std::list; +%template(IntList) std::list; +%template(LongList) std::list; +%template(UCharList) std::list; +%template(UIntList) std::list; +%template(UShortList) std::list; +%template(ULongList) std::list; +%template(FloatList) std::list; %template(DoubleList) std::list; - -namespace std { - %template(RealList) list; -} +%template(StringList) std::list; %inline %{ @@ -37,6 +41,10 @@ struct Struct { // bool operator==(const Struct &other) { return (num == other.num); } }; +const std::list & CopyContainerStruct(const std::list & container) { return container; } +const std::list & CopyContainerStructPtr(const std::list & container) { return container; } +const std::list & CopyContainerStructConstPtr(const std::list & container) { return container; } + enum Fruit { APPLE, BANANNA, diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 0ce26ad0f..619afbb1d 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -29,7 +29,7 @@ SWIGINTERN jint SWIG_ListSize(size_t size) { namespace std { template class list { -%typemap(javabase) std::list< T > "java.util.AbstractSequentialList<$typemap(jboxtype, T)>" +%typemap(javabase) std::list "java.util.AbstractSequentialList<$typemap(jboxtype, T)>" %proxycode %{ public $javaclassname(java.util.Collection c) { this(); @@ -158,7 +158,6 @@ namespace std { }; list(); - list(size_type n, const T &value = T()); list(const list &other); ~list(); void assign(size_type n, const T &value); @@ -178,6 +177,18 @@ namespace std { %extend { %fragment("SWIG_ListSize"); + list(jint count) { + if (count < 0) + throw std::out_of_range("list count must be positive"); + return new std::list(static_cast::size_type>(count)); + } + + list(jint count, const T &value) { + if (count < 0) + throw std::out_of_range("list count must be positive"); + return new std::list(static_cast::size_type>(count), value); + } + jint doSize() const throw (std::out_of_range) { return SWIG_ListSize(self->size()); } diff --git a/Lib/java/std_vector.i b/Lib/java/std_vector.i index 4f5afe6db..2f6f07096 100644 --- a/Lib/java/std_vector.i +++ b/Lib/java/std_vector.i @@ -75,7 +75,7 @@ SWIGINTERN jint SWIG_VectorSize(size_t size) { typedef CTYPE value_type; typedef CREF_TYPE const_reference; vector(); - vector(size_type n); + vector(const vector &other); size_type capacity() const; void reserve(size_type n); %rename(isEmpty) empty; @@ -83,6 +83,18 @@ SWIGINTERN jint SWIG_VectorSize(size_t size) { void clear(); %extend { %fragment("SWIG_VectorSize"); + vector(jint count) { + if (count < 0) + throw std::out_of_range("vector count must be positive"); + return new std::vector< CTYPE >(static_cast::size_type>(count)); + } + + vector(jint count, const CTYPE &value) { + if (count < 0) + throw std::out_of_range("vector count must be positive"); + return new std::vector< CTYPE >(static_cast::size_type>(count), value); + } + jint doSize() const throw (std::out_of_range) { return SWIG_VectorSize(self->size()); } From a8e948e96de007cb4c7b8f69242dd5cb2310c1bf Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 24 Jun 2017 22:53:11 +0100 Subject: [PATCH 33/45] Java std::vector std::list: add missing exception handling --- Lib/java/std_list.i | 8 ++++---- Lib/java/std_vector.i | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 619afbb1d..05c5683fa 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -177,13 +177,13 @@ namespace std { %extend { %fragment("SWIG_ListSize"); - list(jint count) { + list(jint count) throw (std::out_of_range) { if (count < 0) throw std::out_of_range("list count must be positive"); return new std::list(static_cast::size_type>(count)); } - list(jint count, const T &value) { + list(jint count, const T &value) throw (std::out_of_range) { if (count < 0) throw std::out_of_range("list count must be positive"); return new std::list(static_cast::size_type>(count), value); @@ -193,11 +193,11 @@ namespace std { return SWIG_ListSize(self->size()); } - jint doPreviousIndex(const iterator &pos) const { + jint doPreviousIndex(const iterator &pos) const throw (std::out_of_range) { return pos == self->begin() ? -1 : SWIG_ListSize(std::distance(self->begin(), static_cast::const_iterator>(pos))); } - jint doNextIndex(const iterator &pos) const { + jint doNextIndex(const iterator &pos) const throw (std::out_of_range) { return pos == self->end() ? self->size() : SWIG_ListSize(std::distance(self->begin(), static_cast::const_iterator>(pos))); } diff --git a/Lib/java/std_vector.i b/Lib/java/std_vector.i index 2f6f07096..774b6c911 100644 --- a/Lib/java/std_vector.i +++ b/Lib/java/std_vector.i @@ -83,13 +83,13 @@ SWIGINTERN jint SWIG_VectorSize(size_t size) { void clear(); %extend { %fragment("SWIG_VectorSize"); - vector(jint count) { + vector(jint count) throw (std::out_of_range) { if (count < 0) throw std::out_of_range("vector count must be positive"); return new std::vector< CTYPE >(static_cast::size_type>(count)); } - vector(jint count, const CTYPE &value) { + vector(jint count, const CTYPE &value) throw (std::out_of_range) { if (count < 0) throw std::out_of_range("vector count must be positive"); return new std::vector< CTYPE >(static_cast::size_type>(count), value); From c686045f552f3b157b20fe86fc3c4b5611c6becb Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 24 Jun 2017 23:33:31 +0100 Subject: [PATCH 34/45] More efficient add implementation for Java std::list The default implementation in AbstractSequentialList calls add(size(), e) and size() might be expensive. --- Examples/test-suite/java/li_std_list_runme.java | 8 ++++++++ Examples/test-suite/java/li_std_vector_runme.java | 8 ++++++++ Lib/java/std_list.i | 6 ++++++ 3 files changed, 22 insertions(+) diff --git a/Examples/test-suite/java/li_std_list_runme.java b/Examples/test-suite/java/li_std_list_runme.java index f0e48804b..0af9fbc48 100644 --- a/Examples/test-suite/java/li_std_list_runme.java +++ b/Examples/test-suite/java/li_std_list_runme.java @@ -130,5 +130,13 @@ public class li_std_list_runme { java.util.ArrayList bl2 = new java.util.ArrayList(bv); boolean bbb1 = bv.get(0); Boolean bbb2 = bv.get(0); + + IntList v9 = new IntList(java.util.Arrays.asList(10, 20, 30, 40)); + v9.add(50); + v9.add(60); + v9.add(70); + if (v9.size() != 7) throw new RuntimeException("v9 test (1) failed"); + if (!v9.remove(new Integer(60))) throw new RuntimeException("v9 test (2) failed"); + if (v9.size() != 6) throw new RuntimeException("v9 test (3) failed"); } } diff --git a/Examples/test-suite/java/li_std_vector_runme.java b/Examples/test-suite/java/li_std_vector_runme.java index b63df0210..4d28b30de 100644 --- a/Examples/test-suite/java/li_std_vector_runme.java +++ b/Examples/test-suite/java/li_std_vector_runme.java @@ -131,5 +131,13 @@ public class li_std_vector_runme { java.util.ArrayList bl2 = new java.util.ArrayList(bv); boolean bbb1 = bv.get(0); Boolean bbb2 = bv.get(0); + + IntVector v9 = new IntVector(java.util.Arrays.asList(10, 20, 30, 40)); + v9.add(50); + v9.add(60); + v9.add(70); + if (v9.size() != 7) throw new RuntimeException("v9 test (1) failed"); + if (!v9.remove(new Integer(60))) throw new RuntimeException("v9 test (2) failed"); + if (v9.size() != 6) throw new RuntimeException("v9 test (3) failed"); } } diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 05c5683fa..d98fde731 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -14,6 +14,7 @@ SWIGINTERN jint SWIG_ListSize(size_t size) { } } +%javamethodmodifiers std::list::push_back "private"; %javamethodmodifiers std::list::begin "private"; %javamethodmodifiers std::list::insert "private"; %javamethodmodifiers std::list::doSize "private"; @@ -44,6 +45,11 @@ namespace std { return doSize(); } + public boolean add($typemap(jboxtype, T) value) { + push_back(value); + return true; + } + public java.util.ListIterator<$typemap(jboxtype, T)> listIterator(int index) { return new java.util.ListIterator<$typemap(jboxtype, T)>() { private Iterator pos; From ecebbdd0df3748e376c4e160346d9429493b669b Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 25 Jun 2017 00:10:06 +0100 Subject: [PATCH 35/45] Additional add/remove methods added to Java std::list wrappers Add functions similar to java.util.LinkedList: addFirst addLast removeFirst removeLast --- Examples/test-suite/java/li_std_list_runme.java | 10 ++++++++++ Lib/java/std_list.i | 7 +++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/java/li_std_list_runme.java b/Examples/test-suite/java/li_std_list_runme.java index 0af9fbc48..e0d97b893 100644 --- a/Examples/test-suite/java/li_std_list_runme.java +++ b/Examples/test-suite/java/li_std_list_runme.java @@ -138,5 +138,15 @@ public class li_std_list_runme { if (v9.size() != 7) throw new RuntimeException("v9 test (1) failed"); if (!v9.remove(new Integer(60))) throw new RuntimeException("v9 test (2) failed"); if (v9.size() != 6) throw new RuntimeException("v9 test (3) failed"); + v9.addFirst(-10); + v9.addLast(80); + if (v9.size() != 8) throw new RuntimeException("v9 test (4) failed"); + if (v9.get(0) != -10) throw new RuntimeException("v9 test (5) failed");; + if (v9.get(v9.size()-1) != 80) throw new RuntimeException("v9 test (6) failed");; + v9.removeFirst(); + if (v9.get(0) != 10) throw new RuntimeException("v9 test (7) failed");; + v9.removeLast(); + if (v9.size() != 6) throw new RuntimeException("v9 test (8) failed"); + if (v9.get(v9.size()-1) != 70) throw new RuntimeException("v9 test (9) failed");; } } diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index d98fde731..86024a903 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -14,7 +14,6 @@ SWIGINTERN jint SWIG_ListSize(size_t size) { } } -%javamethodmodifiers std::list::push_back "private"; %javamethodmodifiers std::list::begin "private"; %javamethodmodifiers std::list::insert "private"; %javamethodmodifiers std::list::doSize "private"; @@ -46,7 +45,7 @@ namespace std { } public boolean add($typemap(jboxtype, T) value) { - push_back(value); + addLast(value); return true; } @@ -173,9 +172,13 @@ namespace std { %rename(remove) erase; iterator erase(iterator pos); size_type max_size() const; + %rename(removeLast) pop_back; void pop_back(); + %rename(removeFirst) pop_front; void pop_front(); + %rename(addLast) push_back; void push_back(const T &value); + %rename(addFirst) push_front; void push_front(const T &value); iterator begin(); iterator end(); From 6daed2cea10d51c41e363d734921f944e75028b1 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 26 Jun 2017 12:28:02 +0100 Subject: [PATCH 36/45] Remove Java std::list::assign This doesn't exist in equivalent Java containers. If we put it back, the full set of overloaded assign wrappers ought to be added. --- Lib/java/std_list.i | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 86024a903..a634de382 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -165,7 +165,6 @@ namespace std { list(); list(const list &other); ~list(); - void assign(size_type n, const T &value); %rename(isEmpty) empty; bool empty() const; void clear(); From 3af40e74231b5c7f79f00b7e01e9f906dc60e2ae Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 26 Jun 2017 12:46:22 +0100 Subject: [PATCH 37/45] Handle length_error exceptions in Java std::vector::reserve --- Lib/java/std_vector.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/java/std_vector.i b/Lib/java/std_vector.i index 774b6c911..d22896390 100644 --- a/Lib/java/std_vector.i +++ b/Lib/java/std_vector.i @@ -77,7 +77,7 @@ SWIGINTERN jint SWIG_VectorSize(size_t size) { vector(); vector(const vector &other); size_type capacity() const; - void reserve(size_type n); + void reserve(size_type n) throw (std::length_error); %rename(isEmpty) empty; bool empty() const; void clear(); From 90d2ba884c92ce799c8e8c7b4684e778f7b77ec2 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 26 Jun 2017 13:42:19 +0100 Subject: [PATCH 38/45] Java std::list std::vector - test addAll and subList --- Examples/test-suite/java/li_std_list_runme.java | 10 ++++++++++ Examples/test-suite/java/li_std_vector_runme.java | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/Examples/test-suite/java/li_std_list_runme.java b/Examples/test-suite/java/li_std_list_runme.java index e0d97b893..ea2227faf 100644 --- a/Examples/test-suite/java/li_std_list_runme.java +++ b/Examples/test-suite/java/li_std_list_runme.java @@ -148,5 +148,15 @@ public class li_std_list_runme { v9.removeLast(); if (v9.size() != 6) throw new RuntimeException("v9 test (8) failed"); if (v9.get(v9.size()-1) != 70) throw new RuntimeException("v9 test (9) failed");; + + IntList v10 = new IntList(java.util.Arrays.asList(10, 20, 30, 40, 50)); + v10.subList(1, 4).clear(); // Recommended way to call protected method removeRange(1,3) + if (v10.size() != 2) throw new RuntimeException("v10 test (1) failed"); + if (v10.get(0) != 10) throw new RuntimeException("v10 test (2) failed"); + if (v10.get(1) != 50) throw new RuntimeException("v10 test (3) failed"); + v10.addAll(1, java.util.Arrays.asList(22, 33)); + if (v10.size() != 4) throw new RuntimeException("v10 test (4) failed"); + if (v10.get(1) != 22) throw new RuntimeException("v10 test (5) failed"); + if (v10.get(2) != 33) throw new RuntimeException("v10 test (6) failed"); } } diff --git a/Examples/test-suite/java/li_std_vector_runme.java b/Examples/test-suite/java/li_std_vector_runme.java index 4d28b30de..5371a2ba2 100644 --- a/Examples/test-suite/java/li_std_vector_runme.java +++ b/Examples/test-suite/java/li_std_vector_runme.java @@ -139,5 +139,15 @@ public class li_std_vector_runme { if (v9.size() != 7) throw new RuntimeException("v9 test (1) failed"); if (!v9.remove(new Integer(60))) throw new RuntimeException("v9 test (2) failed"); if (v9.size() != 6) throw new RuntimeException("v9 test (3) failed"); + + IntVector v10 = new IntVector(java.util.Arrays.asList(10, 20, 30, 40, 50)); + v10.subList(1, 4).clear(); // Recommended way to call protected method removeRange(1,3) + if (v10.size() != 2) throw new RuntimeException("v10 test (1) failed"); + if (v10.get(0) != 10) throw new RuntimeException("v10 test (2) failed"); + if (v10.get(1) != 50) throw new RuntimeException("v10 test (3) failed"); + v10.addAll(1, java.util.Arrays.asList(22, 33)); + if (v10.size() != 4) throw new RuntimeException("v10 test (4) failed"); + if (v10.get(1) != 22) throw new RuntimeException("v10 test (5) failed"); + if (v10.get(2) != 33) throw new RuntimeException("v10 test (6) failed"); } } From d92faa7f7fc94067155ecab4d2ce4610ddc3fa0f Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 26 Jun 2017 13:43:57 +0100 Subject: [PATCH 39/45] Remove Java std::list::max_size Not in any Java equivalent containers nor std::vector wrapper. --- Lib/java/std_list.i | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index a634de382..d937bcfe3 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -170,7 +170,6 @@ namespace std { void clear(); %rename(remove) erase; iterator erase(iterator pos); - size_type max_size() const; %rename(removeLast) pop_back; void pop_back(); %rename(removeFirst) pop_front; From d04eb8874251f029a50699736dc2889f777c526e Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 26 Jun 2017 13:53:49 +0100 Subject: [PATCH 40/45] Consistent destructor declarations --- Lib/java/std_list.i | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index d937bcfe3..766fb184c 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -164,7 +164,6 @@ namespace std { list(); list(const list &other); - ~list(); %rename(isEmpty) empty; bool empty() const; void clear(); From f4aa8b33218beab0ea4022a1aa77cac4e73b9c16 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 26 Jun 2017 15:28:43 +0100 Subject: [PATCH 41/45] Add missing typedefs to Java std::vector --- Lib/java/std_vector.i | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lib/java/std_vector.i b/Lib/java/std_vector.i index d22896390..c7fd73b37 100644 --- a/Lib/java/std_vector.i +++ b/Lib/java/std_vector.i @@ -72,8 +72,13 @@ SWIGINTERN jint SWIG_VectorSize(size_t size) { public: typedef size_t size_type; + typedef ptrdiff_t difference_type; typedef CTYPE value_type; + typedef CTYPE &reference; typedef CREF_TYPE const_reference; + typedef CTYPE *pointer; + typedef CTYPE const *const_pointer; + vector(); vector(const vector &other); size_type capacity() const; From fccf5c29b481bc55766daebc0b79a2c0e2b1ff42 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 29 Jun 2017 15:34:05 +0100 Subject: [PATCH 42/45] Minor correction in C# std::list doNextIndex --- Lib/java/std_list.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index 766fb184c..e511ea006 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -204,7 +204,7 @@ namespace std { } jint doNextIndex(const iterator &pos) const throw (std::out_of_range) { - return pos == self->end() ? self->size() : SWIG_ListSize(std::distance(self->begin(), static_cast::const_iterator>(pos))); + return pos == self->end() ? SWIG_ListSize(self->size()) : SWIG_ListSize(std::distance(self->begin(), static_cast::const_iterator>(pos))); } bool doHasNext(const iterator &pos) const { From 44cd658a53e457c363a72b11aba6ec52677f4f82 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 29 Jun 2017 19:32:34 +0100 Subject: [PATCH 43/45] Add in missing Java std::list listIterator index range checking --- .../test-suite/java/li_std_list_runme.java | 18 ++++++++++++++++++ .../test-suite/java/li_std_vector_runme.java | 18 ++++++++++++++++++ Lib/java/std_list.i | 2 ++ 3 files changed, 38 insertions(+) diff --git a/Examples/test-suite/java/li_std_list_runme.java b/Examples/test-suite/java/li_std_list_runme.java index ea2227faf..e45b8968b 100644 --- a/Examples/test-suite/java/li_std_list_runme.java +++ b/Examples/test-suite/java/li_std_list_runme.java @@ -158,5 +158,23 @@ public class li_std_list_runme { if (v10.size() != 4) throw new RuntimeException("v10 test (4) failed"); if (v10.get(1) != 22) throw new RuntimeException("v10 test (5) failed"); if (v10.get(2) != 33) throw new RuntimeException("v10 test (6) failed"); + + v10.add(v10.size(), 55); + if (v10.size() != 5) throw new RuntimeException("v10 test (7) failed"); + if (v10.get(4) != 55) throw new RuntimeException("v10 test (8) failed"); + + IntList v11 = new IntList(java.util.Arrays.asList(11, 22, 33, 44)); + v11.listIterator(0); + v11.listIterator(v11.size()); + try { + v11.listIterator(v11.size() + 1); + throw new RuntimeException("v11 test (1) failed"); + } catch (IndexOutOfBoundsException e) { + } + try { + v11.listIterator(-1); + throw new RuntimeException("v11 test (2) failed"); + } catch (IndexOutOfBoundsException e) { + } } } diff --git a/Examples/test-suite/java/li_std_vector_runme.java b/Examples/test-suite/java/li_std_vector_runme.java index 5371a2ba2..d23bbe7cd 100644 --- a/Examples/test-suite/java/li_std_vector_runme.java +++ b/Examples/test-suite/java/li_std_vector_runme.java @@ -149,5 +149,23 @@ public class li_std_vector_runme { if (v10.size() != 4) throw new RuntimeException("v10 test (4) failed"); if (v10.get(1) != 22) throw new RuntimeException("v10 test (5) failed"); if (v10.get(2) != 33) throw new RuntimeException("v10 test (6) failed"); + + v10.add(v10.size(), 55); + if (v10.size() != 5) throw new RuntimeException("v10 test (7) failed"); + if (v10.get(4) != 55) throw new RuntimeException("v10 test (8) failed"); + + IntVector v11 = new IntVector(java.util.Arrays.asList(11, 22, 33, 44)); + v11.listIterator(0); + v11.listIterator(v11.size()); + try { + v11.listIterator(v11.size() + 1); + throw new RuntimeException("v11 test (1) failed"); + } catch (IndexOutOfBoundsException e) { + } + try { + v11.listIterator(-1); + throw new RuntimeException("v11 test (2) failed"); + } catch (IndexOutOfBoundsException e) { + } } } diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i index e511ea006..af6ac075f 100644 --- a/Lib/java/std_list.i +++ b/Lib/java/std_list.i @@ -55,6 +55,8 @@ namespace std { private Iterator last; private java.util.ListIterator<$typemap(jboxtype, T)> init(int index) { + if (index < 0 || index > $javaclassname.this.size()) + throw new IndexOutOfBoundsException("Index: " + index); pos = $javaclassname.this.begin(); pos = pos.advance_unchecked(index); return this; From 0b390a5473eb36b931046c19c677c3a3545920d6 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 29 Jun 2017 19:59:19 +0100 Subject: [PATCH 44/45] Fix Java container tests for change in vector constructor declaration --- Examples/test-suite/constructor_copy.i | 8 +++++++- Examples/test-suite/ignore_template_constructor.i | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/constructor_copy.i b/Examples/test-suite/constructor_copy.i index 7dcd05e8b..222c12f32 100644 --- a/Examples/test-suite/constructor_copy.i +++ b/Examples/test-suite/constructor_copy.i @@ -73,12 +73,18 @@ public: %include "std_vector.i" -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) || defined(SWIGSCILAB) +#if defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) || defined(SWIGSCILAB) #define SWIG_GOOD_VECTOR %ignore std::vector::vector(size_type); %ignore std::vector::resize(size_type); #endif +#if defined(SWIGJAVA) +#define SWIG_GOOD_VECTOR +%ignore std::vector::vector(jint); +%ignore std::vector::resize(jint); +#endif + #if defined(SWIGTCL) || defined(SWIGPERL) #define SWIG_GOOD_VECTOR /* here, for languages with bad declaration */ diff --git a/Examples/test-suite/ignore_template_constructor.i b/Examples/test-suite/ignore_template_constructor.i index 31a5505fb..bdffbec3e 100644 --- a/Examples/test-suite/ignore_template_constructor.i +++ b/Examples/test-suite/ignore_template_constructor.i @@ -1,12 +1,18 @@ %module ignore_template_constructor %include std_vector.i -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGPERL) || defined(SWIGRUBY) +#if defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGPERL) || defined(SWIGRUBY) #define SWIG_GOOD_VECTOR %ignore std::vector::vector(size_type); %ignore std::vector::resize(size_type); #endif +#if defined(SWIGJAVA) +#define SWIG_GOOD_VECTOR +%ignore std::vector::vector(jint); +%ignore std::vector::resize(jint); +#endif + #if defined(SWIGTCL) || defined(SWIGPERL) #define SWIG_GOOD_VECTOR /* here, for languages with bad declaration */ From abe53e39a9f3602a65a9b6b5dea0c74a12d7e1c9 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 29 Jun 2017 20:19:59 +0100 Subject: [PATCH 45/45] Java std::vector minor improvement --- Lib/java/std_vector.i | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/java/std_vector.i b/Lib/java/std_vector.i index c7fd73b37..f35376965 100644 --- a/Lib/java/std_vector.i +++ b/Lib/java/std_vector.i @@ -109,7 +109,7 @@ SWIGINTERN jint SWIG_VectorSize(size_t size) { } void doAdd(jint index, const value_type& value) throw (std::out_of_range) { - const jint size = SWIG_VectorSize(self->size()); + const jint size = static_cast::size_type>(self->size()); if (0 <= index && index <= size) { self->insert(self->begin() + index, value); } else { @@ -118,7 +118,7 @@ SWIGINTERN jint SWIG_VectorSize(size_t size) { } value_type doRemove(jint index) throw (std::out_of_range) { - const jint size = SWIG_VectorSize(self->size()); + const jint size = static_cast::size_type>(self->size()); if (0 <= index && index < size) { CTYPE const old_value = (*self)[index]; self->erase(self->begin() + index); @@ -129,7 +129,7 @@ SWIGINTERN jint SWIG_VectorSize(size_t size) { } CREF_TYPE doGet(jint index) throw (std::out_of_range) { - const jint size = SWIG_VectorSize(self->size()); + const jint size = static_cast::size_type>(self->size()); if (index >= 0 && index < size) return (*self)[index]; else @@ -137,7 +137,7 @@ SWIGINTERN jint SWIG_VectorSize(size_t size) { } value_type doSet(jint index, const value_type& value) throw (std::out_of_range) { - const jint size = SWIG_VectorSize(self->size()); + const jint size = static_cast::size_type>(self->size()); if (index >= 0 && index < size) { CTYPE const old_value = (*self)[index]; (*self)[index] = value; @@ -148,7 +148,7 @@ SWIGINTERN jint SWIG_VectorSize(size_t size) { } void doRemoveRange(jint fromIndex, jint toIndex) throw (std::out_of_range) { - const jint size = SWIG_VectorSize(self->size()); + const jint size = static_cast::size_type>(self->size()); if (0 <= fromIndex && fromIndex <= toIndex && toIndex <= size) { self->erase(self->begin() + fromIndex, self->begin() + toIndex); } else {