Mostly working for map

This commit is contained in:
Brad Kotsopoulos 2018-12-04 01:08:47 -05:00
commit e6d8675513
2 changed files with 187 additions and 110 deletions

View file

@ -2,9 +2,12 @@
* std_map.i
*
* SWIG typemaps for std::map
* The Java proxy class extends java.util.AbstractMap. The std::map
* container looks and feels much like a java.util.HashMap from Java.
* ----------------------------------------------------------------------------- */
%include <std_common.i>
%include <std_set.i>
// ------------------------------------------------------------------------
// std::map
@ -12,60 +15,133 @@
%{
#include <map>
#include <algorithm>
#include <stdexcept>
%}
%fragment("SWIG_MapSize", "header", fragment="SWIG_JavaIntFromSize_t") {
SWIGINTERN jint SWIG_MapSize(size_t size) {
jint sz = SWIG_JavaIntFromSize_t(size);
if (sz == -1) {
throw std::out_of_range("map size is too large to fit into a Java int");
}
return sz;
}
}
%javamethodmodifiers std::map::sizeImpl "private";
%javamethodmodifiers std::map::containsImpl "private";
%javamethodmodifiers std::map::getImpl "private";
%javamethodmodifiers std::map::putImpl "private";
%javamethodmodifiers std::map::removeImpl "private";
namespace std {
template<class K, class T, class C = std::less<K> > class map {
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef K key_type;
typedef T mapped_type;
map();
map(const map< K, T, C > &);
template<class KeyType, class ValueType, class Comparator = std::less<KeyType> > class map {
unsigned int size() const;
bool empty() const;
void clear();
%extend {
const T& get(const K& key) throw (std::out_of_range) {
std::map< K, T, C >::iterator i = self->find(key);
if (i != self->end())
return i->second;
else
throw std::out_of_range("key not found");
}
void set(const K& key, const T& x) {
(*self)[key] = x;
}
void del(const K& key) throw (std::out_of_range) {
std::map< K, T, C >::iterator i = self->find(key);
if (i != self->end())
self->erase(i);
else
throw std::out_of_range("key not found");
}
bool has_key(const K& key) {
std::map< K, T, C >::iterator i = self->find(key);
return i != self->end();
%typemap(javabase) std::map<KeyType, ValueType, Comparator>
"java.util.AbstractMap<$typemap(jboxtype, KeyType), $typemap(jboxtype, ValueType)>"
%proxycode %{
public int size() {
return sizeImpl();
}
public boolean containsKey(Object object) {
if (!(object instanceof $typemap(jboxtype, KeyType))) {
return false;
}
return containsImpl(($typemap(jboxtype, KeyType))object);
}
public $typemap(jboxtype, ValueType) get(Object object) {
if (!(object instanceof $typemap(jboxtype, KeyType))) {
return null;
}
try {
getImpl(($typemap(jboxtype, KeyType)) object);
} catch (IndexOutOfBoundsException e) {}
return null;
}
public $typemap(jboxtype, ValueType) put($typemap(jboxtype, KeyType) key,
$typemap(jboxtype, ValueType) value) {
try {
$typemap(jboxtype, ValueType) oldValue = putImpl(key, value);
return oldValue;
} catch (IndexOutOfBoundsException e) {}
return null;
}
public $typemap(jboxtype, ValueType) remove($typemap(jboxtype, KeyType) key) {
try {
$typemap(jboxtype, ValueType) oldValue = removeImpl(key);
return oldValue;
} catch (IndexOutOfBoundsException e) {}
return null;
}
public java.util.Set<Entry<$typemap(jboxtype, KeyType), $typemap(jboxtype, ValueType)>> entrySet() {
throw new RuntimeException("Stub");
}
%}
public:
map();
map(const map<KeyType, ValueType, Comparator >&);
%rename(isEmpty) empty;
bool empty() const;
void clear();
%extend {
%fragment("SWIG_MapSize");
jint sizeImpl() const throw (std::out_of_range) {
return SWIG_MapSize(self->size());
}
bool containsImpl(const KeyType& key) {
return (self->count(key) > 0);
}
const ValueType& getImpl(const KeyType& key) throw (std::out_of_range) {
std::map<KeyType, ValueType, Comparator >::iterator itr = self->find(key);
if (itr != self->end()) {
return itr->second;
} else {
throw std::out_of_range("map::get() - key not found");
}
}
};
// Legacy macros (deprecated)
%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
%enddef
ValueType putImpl(const KeyType& key, const ValueType& value) {
std::map<KeyType, ValueType, Comparator >::iterator itr = self->find(key);
if (itr != self->end()) {
ValueType oldValue = itr->second;
itr->second = value;
return oldValue;
} else {
(*self)[key] = value;
throw std::out_of_range("map::put() - no existing value for key");
}
}
%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
%enddef
%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
%enddef
ValueType removeImpl(const KeyType& key) throw (std::out_of_range) {
std::map<KeyType, ValueType, Comparator >::iterator itr = self->find(key);
if (itr != self->end()) {
ValueType oldValue = itr->second;
self->erase(itr);
return oldValue;
} else {
throw std::out_of_range("map::remove() - key not found");
}
}
}
};
}