diff options
author | Haibo Huang <hhb@google.com> | 2019-10-08 15:48:26 -0700 |
---|---|---|
committer | Haibo Huang <hhb@google.com> | 2019-11-14 22:14:23 +0000 |
commit | 80b4251e302efb18c145a4786249d695397ed42a (patch) | |
tree | 12b9dec2513f7caa92e7835bc17ab16ae5635df6 /Lib/java/std_list.i | |
parent | 189852d8cdfd5863c52ec7aa73affd926c5a3f43 (diff) | |
parent | 1e36f51346d95f8b9848e682c2eb986e9cb9b4f4 (diff) | |
download | swig-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.i | 225 |
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(); + } + } + }; +} |