Several fixes to GC_VALUE, and map containers.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9724 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
7c4d3d8bd8
commit
6999e71c07
5 changed files with 78 additions and 18 deletions
|
|
@ -53,6 +53,11 @@
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
%include <rubyopers.swg>
|
%include <rubyopers.swg>
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------
|
||||||
|
* The Ruby classes, for C++
|
||||||
|
* ------------------------------------------------------------ */
|
||||||
|
%include <rubyclasses.swg>
|
||||||
|
|
||||||
/* ------------------------------------------------------------
|
/* ------------------------------------------------------------
|
||||||
* Warnings for Ruby keywords
|
* Warnings for Ruby keywords
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,9 @@ namespace swig {
|
||||||
%typemap(out,noblock=1) GC_VALUE const & {
|
%typemap(out,noblock=1) GC_VALUE const & {
|
||||||
$result = (VALUE )*$1;
|
$result = (VALUE )*$1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%ignore LANGUAGE_OBJ;
|
||||||
|
typedef GC_VALUE LANGUAGE_OBJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
|
@ -73,20 +75,21 @@ namespace swig {
|
||||||
|
|
||||||
GC_VALUE & operator=(const GC_VALUE& item)
|
GC_VALUE & operator=(const GC_VALUE& item)
|
||||||
{
|
{
|
||||||
|
GC_unregister();
|
||||||
_obj = item._obj;
|
_obj = item._obj;
|
||||||
_obj.GC_register();
|
GC_register();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GC_register()
|
void GC_register()
|
||||||
{
|
{
|
||||||
if ( obj != Qnil )
|
if ( _obj != Qnil )
|
||||||
rb_gc_register_address( &_obj );
|
rb_gc_register_address( &_obj );
|
||||||
}
|
}
|
||||||
|
|
||||||
void GC_unregister()
|
void GC_unregister()
|
||||||
{
|
{
|
||||||
if ( obj != Qnil )
|
if ( _obj != Qnil )
|
||||||
rb_gc_unregister_address( &_obj );
|
rb_gc_unregister_address( &_obj );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,36 @@
|
||||||
|
|
||||||
%include <std_except.i>
|
%include <std_except.i>
|
||||||
|
|
||||||
|
%fragment(SWIG_Traits_frag(swig::GC_VALUE),"header",fragment="StdTraits") {
|
||||||
|
namespace swig {
|
||||||
|
template <> struct traits<GC_VALUE > {
|
||||||
|
typedef value_category category;
|
||||||
|
static const char* type_name() { return "GC_VALUE"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct traits_from<GC_VALUE> {
|
||||||
|
typedef GC_VALUE value_type;
|
||||||
|
static VALUE from(const value_type& val) {
|
||||||
|
return static_cast<VALUE>(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct traits_check<GC_VALUE, value_category> {
|
||||||
|
static bool check(GC_VALUE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct traits_asval<GC_VALUE > {
|
||||||
|
typedef GC_VALUE value_type;
|
||||||
|
static int asval(VALUE obj, value_type *val) {
|
||||||
|
if (val) *val = obj;
|
||||||
|
return SWIG_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // swig
|
||||||
|
} // %fragment(traits for swig::GC_VALUE)
|
||||||
|
|
||||||
%fragment("RubySequence_Base","header")
|
%fragment("RubySequence_Base","header")
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
template <class K, class T>
|
template <class K, class T>
|
||||||
struct traits_asptr<std::map<K,T> > {
|
struct traits_asptr<std::map<K,T> > {
|
||||||
typedef std::map<K,T> map_type;
|
typedef std::map<K,T> map_type;
|
||||||
static int asptr(PyObject *obj, map_type **val) {
|
static int asptr(VALUE obj, map_type **val) {
|
||||||
int res = SWIG_ERROR;
|
int res = SWIG_ERROR;
|
||||||
if ( TYPE(obj) == T_HASH ) {
|
if ( TYPE(obj) == T_HASH ) {
|
||||||
static ID id_to_a = rb_intern("to_a");
|
static ID id_to_a = rb_intern("to_a");
|
||||||
|
|
@ -144,12 +144,15 @@
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __delitem__(const key_type& key) {
|
VALUE __delitem__(const key_type& key) {
|
||||||
Map::iterator i = self->find(key);
|
Map::iterator i = self->find(key);
|
||||||
if (i != self->end())
|
if (i != self->end()) {
|
||||||
self->erase(i);
|
self->erase(i);
|
||||||
else
|
return swig::from( key );
|
||||||
|
}
|
||||||
|
else {
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%rename("has_key?") has_key;
|
%rename("has_key?") has_key;
|
||||||
|
|
@ -169,8 +172,9 @@
|
||||||
}
|
}
|
||||||
VALUE ary = rb_ary_new2(rubysize);
|
VALUE ary = rb_ary_new2(rubysize);
|
||||||
Map::const_iterator i = self->begin();
|
Map::const_iterator i = self->begin();
|
||||||
for (int j = 0; j < rubysize; ++i, ++j) {
|
Map::const_iterator e = self->end();
|
||||||
rb_ary_aset(ary, j, swig::from(i->first));
|
for ( ; i != e; ++i ) {
|
||||||
|
rb_ary_push( ary, swig::from(i->first) );
|
||||||
}
|
}
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
@ -186,8 +190,9 @@
|
||||||
}
|
}
|
||||||
VALUE ary = rb_ary_new2(rubysize);
|
VALUE ary = rb_ary_new2(rubysize);
|
||||||
Map::const_iterator i = self->begin();
|
Map::const_iterator i = self->begin();
|
||||||
for (int j = 0; j < rubysize; ++i, ++j) {
|
Map::const_iterator e = self->end();
|
||||||
rb_ary_aset(ary, j, swig::from(i->second));
|
for ( ; i != e; ++i ) {
|
||||||
|
rb_ary_push( ary, swig::from(i->second) );
|
||||||
}
|
}
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
@ -203,8 +208,9 @@
|
||||||
}
|
}
|
||||||
VALUE ary = rb_ary_new2(rubysize);
|
VALUE ary = rb_ary_new2(rubysize);
|
||||||
Map::const_iterator i = self->begin();
|
Map::const_iterator i = self->begin();
|
||||||
for (int j = 0; j < rubysize; ++i, ++j) {
|
Map::const_iterator e = self->end();
|
||||||
rb_ary_aset(ary, j, swig::from(*i));
|
for ( ; i != e; ++i ) {
|
||||||
|
rb_ary_push( ary, swig::from(*i) );
|
||||||
}
|
}
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
template <class K, class T>
|
template <class K, class T>
|
||||||
struct traits_asptr<std::multimap<K,T> > {
|
struct traits_asptr<std::multimap<K,T> > {
|
||||||
typedef std::multimap<K,T> multimap_type;
|
typedef std::multimap<K,T> multimap_type;
|
||||||
static int asptr(PyObject *obj, std::multimap<K,T> **val) {
|
static int asptr(VALUE obj, std::multimap<K,T> **val) {
|
||||||
int res = SWIG_ERROR;
|
int res = SWIG_ERROR;
|
||||||
if ( TYPE(obj) == T_HASH ) {
|
if ( TYPE(obj) == T_HASH ) {
|
||||||
static ID id_to_a = rb_intern("to_a");
|
static ID id_to_a = rb_intern("to_a");
|
||||||
|
|
@ -58,7 +58,25 @@
|
||||||
for (const_iterator i= multimap.begin(); i!= multimap.end(); ++i) {
|
for (const_iterator i= multimap.begin(); i!= multimap.end(); ++i) {
|
||||||
VALUE key = swig::from(i->first);
|
VALUE key = swig::from(i->first);
|
||||||
VALUE val = swig::from(i->second);
|
VALUE val = swig::from(i->second);
|
||||||
rb_hash_aset(obj, key, val);
|
|
||||||
|
VALUE oldval = rb_hash_aref( obj, key );
|
||||||
|
if ( oldval == Qnil )
|
||||||
|
rb_hash_aset(obj, key, val);
|
||||||
|
else {
|
||||||
|
// Multiple values for this key, create array if needed
|
||||||
|
// and add a new element to it.
|
||||||
|
VALUE ary;
|
||||||
|
if ( TYPE(oldval) == T_ARRAY )
|
||||||
|
ary = oldval;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ary = rb_ary_new2(2);
|
||||||
|
rb_ary_push( ary, oldval );
|
||||||
|
rb_hash_aset( obj, key, ary );
|
||||||
|
}
|
||||||
|
rb_ary_push( ary, val );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue