1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 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(int 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();
}
}
};
}
|