diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index f68451f87..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 += \ @@ -600,9 +600,7 @@ CPP_STD_TEST_CASES += \ smart_pointer_inherit \ template_typedef_fnc \ template_type_namespace \ - template_opaque -# li_std_list - + template_opaque \ 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 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 */ diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in index d63a25879..503631217 100644 --- a/Examples/test-suite/java/Makefile.in +++ b/Examples/test-suite/java/Makefile.in @@ -40,6 +40,7 @@ CPP_TEST_CASES = \ java_throws \ java_typemaps_proxy \ java_typemaps_typewrapper \ + li_std_list \ # li_boost_intrusive_ptr CPP11_TEST_CASES = \ 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..e45b8968b --- /dev/null +++ b/Examples/test-suite/java/li_std_list_runme.java @@ -0,0 +1,180 @@ +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(); + + 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"); + + 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"); + + 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(); + + v4.add(new Struct(12)); + v5.add(new Struct(34)); + v6.add(new Struct(56)); + + 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); + + 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"); + 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");; + + 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"); + + 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 60776bbf1..d23bbe7cd 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"); @@ -46,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()); @@ -59,13 +73,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()); @@ -117,5 +131,41 @@ 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"); + + 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"); + + 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/Examples/test-suite/li_std_list.i b/Examples/test-suite/li_std_list.i index bae475eea..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,19 +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; - -%inline %{ -typedef float Real; -%} - -namespace std { - %template(RealList) list; -} +%template(StringList) std::list; %inline %{ @@ -40,7 +40,21 @@ struct Struct { Struct(double d) : num(d) {} // 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, + PEAR, + KIWI, +}; %} +%template(StructList) std::list; +%template(StructPtrList) std::list; +%template(StructConstPtrList) std::list; - +%template(FruitList) std::list; diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i new file mode 100644 index 000000000..af6ac075f --- /dev/null +++ b/Lib/java/std_list.i @@ -0,0 +1,217 @@ +%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::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; + +namespace std { + template class list { + +%typemap(javabase) std::list "java.util.AbstractSequentialList<$typemap(jboxtype, T)>" +%proxycode %{ + public $javaclassname(java.util.Collection c) { + this(); + 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); + } + } + + public int size() { + return doSize(); + } + + public boolean add($typemap(jboxtype, T) value) { + addLast(value); + return true; + } + + 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 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; + } + + 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 java.util.NoSuchElementException(); + } + last = pos; + pos = pos.previous_unchecked(); + return last.deref_unchecked(); + } + + public $typemap(jboxtype, T) next() { + if (!hasNext()) { + throw new java.util.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; + + /* + * 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 "java.util.ListIterator<$typemap(jboxtype, T)>" + + struct iterator { + %extend { + void set_unchecked(const T &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; + } + + T deref_unchecked() const { + return **$self; + } + + iterator advance_unchecked(size_type index) const { + std::list::iterator ret = *$self; + std::advance(ret, index); + return ret; + } + } + }; + + list(); + list(const list &other); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(remove) erase; + iterator erase(iterator pos); + %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(); + iterator insert(iterator pos, const T &value); + + %extend { + %fragment("SWIG_ListSize"); + 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) 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); + } + + jint doSize() const throw (std::out_of_range) { + return SWIG_ListSize(self->size()); + } + + 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 throw (std::out_of_range) { + 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 { + return pos != $self->end(); + } + } + }; +} diff --git a/Lib/java/std_vector.i b/Lib/java/std_vector.i index 4f5afe6db..f35376965 100644 --- a/Lib/java/std_vector.i +++ b/Lib/java/std_vector.i @@ -72,17 +72,34 @@ 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(size_type n); + 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(); %extend { %fragment("SWIG_VectorSize"); + 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) 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); + } + jint doSize() const throw (std::out_of_range) { return SWIG_VectorSize(self->size()); } @@ -92,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 { @@ -101,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); @@ -112,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 @@ -120,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; @@ -131,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 {