aboutsummaryrefslogtreecommitdiff
path: root/Lib/java/std_list.i
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2019-10-08 15:48:26 -0700
committerHaibo Huang <hhb@google.com>2019-11-14 22:14:23 +0000
commit80b4251e302efb18c145a4786249d695397ed42a (patch)
tree12b9dec2513f7caa92e7835bc17ab16ae5635df6 /Lib/java/std_list.i
parent189852d8cdfd5863c52ec7aa73affd926c5a3f43 (diff)
parent1e36f51346d95f8b9848e682c2eb986e9cb9b4f4 (diff)
downloadswig-80b4251e302efb18c145a4786249d695397ed42a.tar.gz
Upgrade swig to 'rel-4.0.1'llvm-r383902b
Also run autogen.sh to generate configure files. Exempt-From-Owner-Approval: add myself to owners Change-Id: I391aa20428836ae74dab8c8427627ca4dbc8ecf4
Diffstat (limited to 'Lib/java/std_list.i')
-rw-r--r--Lib/java/std_list.i225
1 files changed, 225 insertions, 0 deletions
diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i
new file mode 100644
index 000000000..1077bd0a0
--- /dev/null
+++ b/Lib/java/std_list.i
@@ -0,0 +1,225 @@
+/* -----------------------------------------------------------------------------
+ * std_list.i
+ *
+ * SWIG typemaps for std::list.
+ * The Java proxy class extends java.util.AbstractSequentialList. The std::list
+ * container looks and feels much like a java.util.LinkedList from Java.
+ * ----------------------------------------------------------------------------- */
+
+%include <std_common.i>
+
+%{
+#include <list>
+#include <stdexcept>
+%}
+
+%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 <typename T> class list {
+
+%typemap(javabase) std::list<T> "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 (java.lang.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 ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_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<T>::iterator ret = *$self;
+ ++ret;
+ return ret;
+ }
+
+ iterator previous_unchecked() const {
+ std::list<T>::iterator ret = *$self;
+ --ret;
+ return ret;
+ }
+
+ T deref_unchecked() const {
+ return **$self;
+ }
+
+ iterator advance_unchecked(size_type index) const {
+ std::list<T>::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, 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<T>(static_cast<std::list<T>::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<std::list<T>::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<std::list<T>::const_iterator>(pos)));
+ }
+
+ bool doHasNext(const iterator &pos) const {
+ return pos != $self->end();
+ }
+ }
+ };
+}