Merge branch 'fflexo-javalist'
* fflexo-javalist: Java std::vector minor improvement Fix Java container tests for change in vector constructor declaration Add in missing Java std::list listIterator index range checking Minor correction in C# std::list doNextIndex Add missing typedefs to Java std::vector Consistent destructor declarations Remove Java std::list::max_size Java std::list std::vector - test addAll and subList Handle length_error exceptions in Java std::vector::reserve Remove Java std::list::assign Additional add/remove methods added to Java std::list wrappers More efficient add implementation for Java std::list Java std::vector std::list: add missing exception handling Java std::vector std::list enhancements Modify std::list declarations to match the C++ standard Fix removing elements from std::list Java wrapper Improve Java std::list std::vector runtime tests and wrap std::list::clear Wrap std::list::empty as isEmpty in Java javabase typemap improvement for std::list Java std::list - fully qualifiy Java class name to avoid potential name ambiguity cosmetics Remove redundant code Java std::list rework to be consistent with std::vector wrappers li_std_list testcase not working for most languages re-enabled li_std_list test Switched from autobox to jboxtype per #842 Document autobox.i Made the conversion from long->int for size_type mapping onto Java interfaces cleaner. Be consistent in semantics of %extend on std::list::iterator Comment on consideration of making iterator non-static. Java style fix: iterator->Iterator Moving iterator functionality into nested Java class now. Removed typedef from li_std_list test as it's not expected to work properly in templated code 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. Drop non-const reference from autobox typemap macro to be consistent. just use a forward declaration for C++ iterator types to fix enum errors Added enum to li_std_list tests Added li_std_list to the Java test-suit makefile added more comments in a few places Base _runme.java for li_std_list off li_std_vector_runme.java Expose more types from li_std_list.i Don't expose sort() to avoid adding dependencies on all std::list users Target each method specificly for setting modifiers Don't expose remove() method from std::list to avoid confusing it with Java's remove() in List - added std_list.i implemenatation that extends Java's AbstractSequentialList base class - added autobox.i that provides supporting typemaps for generics in containers
This commit is contained in:
commit
df899cfef1
9 changed files with 525 additions and 36 deletions
217
Lib/java/std_list.i
Normal file
217
Lib/java/std_list.i
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
%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 (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<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) 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));
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -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<std::vector< CTYPE >::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<std::vector< CTYPE >::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<std::vector< CTYPE >::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<std::vector< CTYPE >::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<std::vector< CTYPE >::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<std::vector< CTYPE >::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<std::vector< CTYPE >::size_type>(self->size());
|
||||
if (0 <= fromIndex && fromIndex <= toIndex && toIndex <= size) {
|
||||
self->erase(self->begin() + fromIndex, self->begin() + toIndex);
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue