diff options
author | Gonzalo Garramuno <ggarra@advancedsl.com.ar> | 2007-04-30 06:36:55 +0000 |
---|---|---|
committer | Gonzalo Garramuno <ggarra@advancedsl.com.ar> | 2007-04-30 06:36:55 +0000 |
commit | a0b74a907ed5c5ccce7eec38c1e9ff84cd758cef (patch) | |
tree | 423d088336f2ff3e8d819fddf75970b75546770f | |
parent | c1119d264a1fc3831f1252c5054311b3056aa0b8 (diff) | |
download | swig-a0b74a907ed5c5ccce7eec38c1e9ff84cd758cef.tar.gz |
Updated Ruby's STL to new framework.
Still need to add new tests for multimap,
multiset, list, etc.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9719 626c5289-ae23-0410-ae9c-e8d60b6d4f22
-rw-r--r-- | Lib/ruby/rubyclasses.swg | 108 | ||||
-rw-r--r-- | Lib/ruby/rubycontainer.swg | 127 | ||||
-rw-r--r-- | Lib/ruby/rubyerrors.swg | 9 | ||||
-rw-r--r-- | Lib/ruby/rubyiterators.swg | 5 | ||||
-rw-r--r-- | Lib/ruby/rubykw.swg | 17 | ||||
-rw-r--r-- | Lib/ruby/rubymacros.swg | 8 | ||||
-rw-r--r-- | Lib/ruby/rubystdcommon.swg | 3 | ||||
-rw-r--r-- | Lib/ruby/rubyuserdir.swg | 3 | ||||
-rw-r--r-- | Lib/ruby/rubywstrings.swg | 64 | ||||
-rw-r--r-- | Lib/ruby/std_alloc.i | 1 | ||||
-rw-r--r-- | Lib/ruby/std_common.i | 297 | ||||
-rw-r--r-- | Lib/ruby/std_container.i | 2 | ||||
-rw-r--r-- | Lib/ruby/std_deque.i | 31 | ||||
-rw-r--r-- | Lib/ruby/std_ios.i | 3 | ||||
-rw-r--r-- | Lib/ruby/std_list.i | 28 | ||||
-rw-r--r-- | Lib/ruby/std_map.i | 1480 | ||||
-rw-r--r-- | Lib/ruby/std_multimap.i | 80 | ||||
-rw-r--r-- | Lib/ruby/std_multiset.i | 44 | ||||
-rw-r--r-- | Lib/ruby/std_pair.i | 1142 | ||||
-rw-r--r-- | Lib/ruby/std_set.i | 60 | ||||
-rw-r--r-- | Lib/ruby/std_vector.i | 521 | ||||
-rw-r--r-- | Lib/ruby/std_vectora.i | 45 | ||||
-rw-r--r-- | Lib/ruby/std_wstring.i | 3 |
23 files changed, 1336 insertions, 2745 deletions
diff --git a/Lib/ruby/rubyclasses.swg b/Lib/ruby/rubyclasses.swg new file mode 100644 index 000000000..c5da8d648 --- /dev/null +++ b/Lib/ruby/rubyclasses.swg @@ -0,0 +1,108 @@ +#ifdef __cplusplus + +/* + GC_VALUE is used as a replacement of VALUE. + GC_VALUE automatically handles registering and unregistering + of the underlying ruby object with the GC. + + It can be used if you want to create STL containers of VALUEs, such as: + + std::vector< GC_VALUE >; + + or as a member variable: + + struct A { + GC_VALUE obj; + A(VALUE o) : _obj(o) { + } + }; + + or as a input/output value (not much use for this, thou): + + GC_VALUE func(GC_VALUE obj) { + GC_VALUE out = rb_obj_classname(obj); + return out; + } + + + GC_VALUE is 'visible' at the wrapped side, so you can do: + + %template(RubyVector) std::vector<swig::GC_VALUE>; + + and all the proper typemaps will be used. + +*/ + +namespace swig { + %ignore GC_VALUE; + struct GC_VALUE {}; + // %apply VALUE {GC_VALUE}; + // %apply VALUE const& {GC_VALUE const&}; + + /* For output */ + %typemap(out,noblock=1) GC_VALUE { + $result = (VALUE )$1; + } + + %typemap(out,noblock=1) GC_VALUE const & { + $result = (VALUE )*$1; + } + +} + +%{ +namespace swig { + class GC_VALUE { + protected: + VALUE _obj; + + public: + GC_VALUE() :_obj( Qnil ) + { + } + + GC_VALUE(const GC_VALUE& item) : _obj(item._obj) + { + GC_register(); + } + + GC_VALUE(VALUE obj) :_obj(obj) + { + GC_register(); + } + + GC_VALUE & operator=(const GC_VALUE& item) + { + _obj = item._obj; + _obj.GC_register(); + return *this; + } + + void GC_register() + { + if ( obj != Qnil ) + rb_gc_register_address( &_obj ); + } + + void GC_unregister() + { + if ( obj != Qnil ) + rb_gc_unregister_address( &_obj ); + } + + ~GC_VALUE() + { + GC_unregister(); + } + + operator VALUE() const + { + return _obj; + } + + }; +} +%} + + +#endif diff --git a/Lib/ruby/rubycontainer.swg b/Lib/ruby/rubycontainer.swg index a34ff8d9e..d4c9d7766 100644 --- a/Lib/ruby/rubycontainer.swg +++ b/Lib/ruby/rubycontainer.swg @@ -515,6 +515,20 @@ namespace swig return str; } + VALUE to_a() + { + Container::iterator i = $self->begin(); + Container::iterator e = $self->end(); + VALUE ary = rb_ary_new2( std::distance( i, e ) ); + VALUE tmp; + for ( ; i != e; ++i ) + { + tmp = swig::from<Container::value_type>( *i ); + rb_ary_push( ary, tmp ); + } + return ary; + } + VALUE to_s() { Container::iterator i = $self->begin(); @@ -543,8 +557,6 @@ namespace swig %extend { -#if defined(SWIG_RUBY_AUTORENAME) - VALUE pop() { if ($self->empty()) return Qnil; Sequence::value_type x = self->back(); @@ -552,27 +564,32 @@ namespace swig return swig::from< Sequence::value_type >( x ); } + %alias push "<<"; const value_type push( const value_type& e ) { $self->push_back( e ); return e; } -#endif - - -// VALUE __del__(const Sequence::value_type& e) { -// VALUE r = Qnil; -// std::size_t len = $self->size(); -// std::remove_if( $self->begin(), $self->end(), -// std::bind2nd( std::equal_to< Sequence::value_type >(), -// e ) ); -// if ( $self->size() != len ) -// r = swig::from< Sequence::value_type >( e ); -// return r; -// } - - VALUE slice( difference_type i, difference_type j ) - { + // Implementing delete requires semantics that go beyond the + // default requirements of STD containers. + // + // %rename("delete") __del__; + // VALUE __del__( Sequence::value_type e ) { + // VALUE r = Qnil; + // std::size_t len = $self->size(); + // std::remove_if( $self->begin(), $self->end(), + // std::bind2nd( std::equal_to< Sequence::value_type >(), + // e ) ); + // + // if ( $self->size() != len ) + // r = swig::from< Sequence::value_type >( e ); + // else if ( rb_block_given_p() ) + // r = rb_yield(Qnil); + // return r; + // } + + VALUE slice( difference_type i, difference_type j ) + { if ( j <= 0 ) return Qnil; std::size_t len = $self->size(); if ( i < 0 ) i = len - i; @@ -789,6 +806,80 @@ namespace swig %enddef +%define %swig_sequence_front_inserters( Sequence... ) +%extend { + + VALUE shift() + { + if ($self->empty()) return Qnil; + Sequence::value_type x = self->front(); + $self->erase( $self->begin() ); + return swig::from< Sequence::value_type >( x ); + } + + %typemap(in) (int argc, VALUE* argv) { + $1 = argc - 1; + $2 = argv + 1; + } + + Sequence* insert( difference_type idx, int argc, VALUE* argv, ... ) + { + std::size_t len = $self->size(); + std::size_t i = swig::check_index( idx, len, true ); + Sequence::value_type val; + Sequence::iterator start; + int res = swig::asval( argv[0], &val ); + if (!SWIG_IsOK(res)) + SWIG_exception_fail(SWIG_ArgError(res), + Ruby_Format_TypeError( "", + swig::type_name<Sequence::value_type>(), __FUNCTION__, 2, argv[0] )); + if ( i >= len ) { + $self->resize(i-1, val); + return $self; + } + start = $self->begin(); + std::advance( start, i ); + $self->insert( start++, val ); + for ( int idx = 1; idx < argc; ++idx ) + { + int res = swig::asval( argv[idx], &val ); + if (!SWIG_IsOK(res)) + SWIG_exception_fail(SWIG_ArgError(res), + Ruby_Format_TypeError( "", + swig::type_name<Sequence::value_type>(), __FUNCTION__, idx+2, argv[idx] )); + $self->insert( start++, val ); + } + + fail: + return $self; + } + + %typemap(in) (int argc, VALUE* argv) { + $1 = argc; + $2 = argv; + } + + Sequence* unshift( int argc, VALUE* argv, ... ) + { + Sequence::value_type val; + for ( int idx = argc-1; idx >= 0; --idx ) + { + int res = swig::asval( argv[idx], &val ); + if (!SWIG_IsOK(res)) + SWIG_exception_fail(SWIG_ArgError(res), + Ruby_Format_TypeError( "", + swig::type_name<Sequence::value_type>(), __FUNCTION__, idx+2, argv[idx] )); + Sequence::iterator start = $self->begin(); + $self->insert( start, val ); + } + + fail: + return $self; + } + +} +%enddef + // // Common fragments diff --git a/Lib/ruby/rubyerrors.swg b/Lib/ruby/rubyerrors.swg index cb4b4cbcb..dcbdc7a70 100644 --- a/Lib/ruby/rubyerrors.swg +++ b/Lib/ruby/rubyerrors.swg @@ -108,13 +108,13 @@ const char* Ruby_Format_TypeError( const char* msg, str = rb_str_cat2( str, "in method '" ); str = rb_str_cat2( str, name ); str = rb_str_cat2( str, "', argument " ); - sprintf( buf, "%d of type ", argn ); + sprintf( buf, "%d of type ", argn-1 ); str = rb_str_cat2( str, buf ); str = rb_str_cat2( str, type ); str = rb_str_cat2( str, ", but got " ); str = rb_str_cat2( str, rb_obj_classname(input) ); - str = rb_str_cat2( str, " (" ); - VALUE asStr = rb_obj_as_string(input); + str = rb_str_cat2( str, " " ); + VALUE asStr = rb_inspect(input); if ( RSTRING_LEN(asStr) > 30 ) { str = rb_str_cat( str, StringValuePtr(asStr), 30 ); @@ -122,9 +122,8 @@ const char* Ruby_Format_TypeError( const char* msg, } else { - str = rb_str_concat( str, asStr ); + str = rb_str_append( str, asStr ); } - str = rb_str_cat2( str, ")" ); return StringValuePtr( str ); } diff --git a/Lib/ruby/rubyiterators.swg b/Lib/ruby/rubyiterators.swg index 0ed8f1d31..eb9705778 100644 --- a/Lib/ruby/rubyiterators.swg +++ b/Lib/ruby/rubyiterators.swg @@ -4,7 +4,7 @@ * * rubyiterators.swg * - * Implement a ruby 'output' iterator for Ruby 2.2 or higher. + * Implement a ruby 'output' iterator for Ruby. * * Users can derive form the RubySwigIterator to implemet their * own iterators. As an example (real one since we use it for STL/STD @@ -366,9 +366,6 @@ namespace swig RubySwigIterator *advance(ptrdiff_t n); bool operator == (const RubySwigIterator& x) const; - bool operator != (const RubySwigIterator& x) const; - RubySwigIterator& operator += (ptrdiff_t n); - RubySwigIterator& operator -= (ptrdiff_t n); RubySwigIterator* operator + (ptrdiff_t n) const; RubySwigIterator* operator - (ptrdiff_t n) const; ptrdiff_t operator - (const RubySwigIterator& x) const; diff --git a/Lib/ruby/rubykw.swg b/Lib/ruby/rubykw.swg index de59b577a..43abf1dee 100644 --- a/Lib/ruby/rubykw.swg +++ b/Lib/ruby/rubykw.swg @@ -26,6 +26,7 @@ RUBYKW(elsif); RUBYKW(end); RUBYKW(ensure); RUBYKW(false); +RUBYKW(fatal); RUBYKW(for); RUBYKW(if); RUBYKW(in); @@ -49,6 +50,22 @@ RUBYKW(when); RUBYKW(while); RUBYKW(yield); +RUBYKW(FalseClass); +RUBYKW(TrueClass); +RUBYKW(Numeric); +RUBYKW(Integer); +RUBYKW(Fixnum); +RUBYKW(Float); +RUBYKW(Range); +RUBYKW(Array); +RUBYKW(String); +RUBYKW(IO); +RUBYKW(File); +RUBYKW(FileUtils); +RUBYKW(Find); +RUBYKW(Struct); +RUBYKW(OpenStruct); +RUBYKW(Regexp); #undef RUBYKW diff --git a/Lib/ruby/rubymacros.swg b/Lib/ruby/rubymacros.swg index 54959c202..8af6822df 100644 --- a/Lib/ruby/rubymacros.swg +++ b/Lib/ruby/rubymacros.swg @@ -1,11 +1,9 @@ // Redefine these macros so argument index for ruby is done properly, -// ignoring self. -#define %argfail_fmt(_type,_name,_argn) \ - Ruby_Format_TypeError( "", _type, #_name, _argn ) +// ignoring self and we get some more info about the input. +#define %argfail_fmt(_type,_name,_argn) Ruby_Format_TypeError( "", _type, #_name, _argn, $input ) -#define %argnullref_fmt(_type,_name,_argn) \ - Ruby_Format_TypeError(%nullref_fmt(), _type, #_name, _argn) +#define %argnullref_fmt(_type,_name,_argn) Ruby_Format_TypeError(%nullref_fmt(), _type, #_name, _argn, $input) %include <typemaps/swigmacros.swg> diff --git a/Lib/ruby/rubystdcommon.swg b/Lib/ruby/rubystdcommon.swg index e47475e71..d47b4a760 100644 --- a/Lib/ruby/rubystdcommon.swg +++ b/Lib/ruby/rubystdcommon.swg @@ -1,5 +1,6 @@ %fragment("StdTraits","header",fragment="StdTraitsCommon") { + namespace swig { /* Traits that provides the from method @@ -228,6 +229,8 @@ namespace swig { %} %enddef +#define SWIG_RUBY_THREAD_BEGIN_BLOCK +#define SWIG_RUBY_THREAD_END_BLOCK #define specialize_std_vector(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) #define specialize_std_list(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) diff --git a/Lib/ruby/rubyuserdir.swg b/Lib/ruby/rubyuserdir.swg index 2a20c4252..2f67c9ec6 100644 --- a/Lib/ruby/rubyuserdir.swg +++ b/Lib/ruby/rubyuserdir.swg @@ -5,3 +5,6 @@ #define %predicate %feature("predicate", "1") #define %bang %feature("bang", "1") #define %trackobjects %feature("trackobjects") +#define %nooutput %feature("outputs","0") +#define %initstack %feature("initstack", "1") +#define %ignorestack %feature("initstack", "0") diff --git a/Lib/ruby/rubywstrings.swg b/Lib/ruby/rubywstrings.swg new file mode 100644 index 000000000..69404a34e --- /dev/null +++ b/Lib/ruby/rubywstrings.swg @@ -0,0 +1,64 @@ +/* ------------------------------------------------------------ + * utility methods for wchar_t strings + * ------------------------------------------------------------ */ + +%fragment("SWIG_AsWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor") { +SWIGINTERN int +SWIG_AsWCharPtrAndSize(VALUE obj, wchar_t **cptr, size_t *psize, int *alloc) +{ + VALUE tmp = 0; + bool ok = false; + if ( TYPE(obj) == T_STRING ) { + if (cptr) { +// obj = tmp = PyUnicode_FromObject(obj); + rb_notimplement(); + ok = true; + } + } + if (ok) { +// int len = PyUnicode_GetSize(obj); + rb_notimplement(); + if (cptr) { + *cptr = %new_array(len + 1, wchar_t); +// PyUnicode_AsWideChar((PyUnicodeObject *)obj, *cptr, len); + rb_notimplement(); + (*cptr)[len] = 0; + } + if (psize) *psize = (size_t) len + 1; + if (alloc) *alloc = cptr ? SWIG_NEWOBJ : 0; + return SWIG_OK; + } else { + swig_type_info* pwchar_descriptor = SWIG_pwchar_descriptor(); + if (pwchar_descriptor) { + void * vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pwchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (wchar_t *)vptr; + if (psize) *psize = vptr ? (wcslen((wchar_t *)vptr) + 1) : 0; + return SWIG_OK; + } + } + } + return SWIG_TypeError; +} +} + +%fragment("SWIG_FromWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor") { +SWIGINTERNINLINE VALUE +SWIG_FromWCharPtrAndSize(const wchar_t * carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + swig_type_info* pwchar_descriptor = SWIG_pwchar_descriptor(); + return pwchar_descriptor ? + SWIG_NewPointerObj(%const_cast(carray,wchar_t *), pwchar_descriptor, 0) : Qnil; + } else { + rb_notimplement(); + // return PyUnicode_FromWideChar(carray, %numeric_cast(size,int)); + } + } else { + return Qnil; + } +} +} + + diff --git a/Lib/ruby/std_alloc.i b/Lib/ruby/std_alloc.i new file mode 100644 index 000000000..35dc051be --- /dev/null +++ b/Lib/ruby/std_alloc.i @@ -0,0 +1 @@ +%include <std/std_alloc.i> diff --git a/Lib/ruby/std_common.i b/Lib/ruby/std_common.i index 956bfc37d..c9aae945f 100644 --- a/Lib/ruby/std_common.i +++ b/Lib/ruby/std_common.i @@ -1,41 +1,282 @@ -/* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * - * std_common.i - * - * SWIG typemaps for STL - common utilities - * ----------------------------------------------------------------------------- */ - %include <std/std_except.i> +%include <rubystdcommon.swg> +// +// Use the following macro with modern STL implementations +// +//#define SWIG_STD_MODERN_STL +// +// Use this to deactive the previous definition, when using gcc-2.95 +// or similar old compilers. +// +//#define SWIG_STD_NOMODERN_STL + +// Here, we identify compilers we now have problems with STL. +%{ + +#if defined(__SUNPRO_CC) && defined(_RWSTD_VER) +# define SWIG_STD_NOASSIGN_STL +# define SWIG_STD_NOINSERT_TEMPLATE_STL +# define SWIG_STD_NOITERATOR_TRAITS_STL +#endif + +#if defined(__GNUC__) +# if __GNUC__ == 2 && __GNUC_MINOR <= 96 +# define SWIG_STD_NOMODERN_STL +# endif +#endif + + +%} -%apply size_t { std::size_t }; +// +// Common code for supporting the STD C++ namespace +// %{ #include <string> +#include <stdexcept> +%} -#define SWIG_FLOAT_P(x) ((TYPE(x) == T_FLOAT) || FIXNUM_P(x)) -bool SWIG_BOOL_P(VALUE) { - // dummy test, RTEST should take care of everything - return true; -} -bool SWIG_RB2BOOL(VALUE x) { - return RTEST(x); +%fragment("StdIteratorTraits","header") %{ +#if !defined(SWIG_STD_NOITERATOR_TRAITS_STL) +#include <iterator> +#else +namespace std { + template <class Iterator> + struct iterator_traits { + typedef ptrdiff_t difference_type; + typedef typename Iterator::value_type value_type; + }; + +#if defined(__SUNPRO_CC) && defined(_RWSTD_VER) + template <class Iterator, class Category,class T, class Reference, class Pointer, class Distance> + struct iterator_traits<__reverse_bi_iterator<Iterator,Category,T,Reference,Pointer,Distance> > { + typedef Distance difference_type; + typedef T value_type; + }; +#endif + + template <class T> + struct iterator_traits<T*> { + typedef T value_type; + typedef ptrdiff_t difference_type; + }; + + template<typename _InputIterator> + inline typename iterator_traits<_InputIterator>::difference_type + distance(_InputIterator __first, _InputIterator __last) + { + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) { + ++__first; ++__n; + } + return __n; + } + +} +#endif +%} + +%fragment("StdTraitsCommon","header") %{ +namespace swig { + template <class Type> + struct noconst_traits { + typedef Type noconst_type; + }; + + template <class Type> + struct noconst_traits<const Type> { + typedef Type noconst_type; + }; + + /* + type categories + */ + struct pointer_category { }; + struct value_category { }; + + /* + General traits that provides type_name and type_info + */ + template <class Type> struct traits { }; + + template <class Type> + inline const char* type_name() { + return traits<typename noconst_traits<Type >::noconst_type >::type_name(); + } + + template <class Type> + struct traits_info { + static swig_type_info *type_query(std::string name) { + name += " *"; + return SWIG_TypeQuery(name.c_str()); + } + static swig_type_info *type_info() { + static swig_type_info *info = type_query(type_name<Type>()); + return info; + } + }; + + template <class Type> + inline swig_type_info *type_info() { + return traits_info<Type>::type_info(); + } + + /* + Partial specialization for pointers + */ + template <class Type> struct traits <Type *> { + typedef pointer_category category; + static std::string make_ptr_name(const char* name) { + std::string ptrname = name; + ptrname += " *"; + return ptrname; + } + static const char* type_name() { + static std::string name = make_ptr_name(swig::type_name<Type>()); + return name.c_str(); + } + }; + + template <class Type, class Category> + struct traits_as { }; + + template <class Type, class Category> + struct traits_check { }; + } -VALUE SWIG_BOOL2RB(bool b) { - return b ? Qtrue : Qfalse; +%} + +/* + Generate the traits for a swigtype +*/ + +%define %traits_swigtype(Type...) +%fragment(SWIG_Traits_frag(Type),"header",fragment="StdTraits") { + namespace swig { + template <> struct traits<Type > { + typedef pointer_category category; + static const char* type_name() { return #Type; } + }; + } } -double SWIG_NUM2DBL(VALUE x) { - return (FIXNUM_P(x) ? FIX2INT(x) : NUM2DBL(x)); +%enddef + + +/* + Generate the traits for a 'primitive' type, such as 'double', + for which the SWIG_AsVal and SWIG_From methods are already defined. +*/ + +%define %traits_ptypen(Type...) + %fragment(SWIG_Traits_frag(Type),"header", + fragment=SWIG_AsVal_frag(Type), + fragment=SWIG_From_frag(Type), + fragment="StdTraits") { +namespace swig { + template <> struct traits<Type > { + typedef value_category category; + static const char* type_name() { return #Type; } + }; + template <> struct traits_asval<Type > { + typedef Type value_type; + static int asval(VALUE obj, value_type *val) { + return SWIG_AsVal(Type)(obj, val); + } + }; + template <> struct traits_from<Type > { + typedef Type value_type; + static VALUE from(const value_type& val) { + return SWIG_From(Type)(val); + } + }; } -bool SWIG_STRING_P(VALUE x) { - return TYPE(x) == T_STRING; } -std::string SWIG_RB2STR(VALUE x) { - return std::string(RSTRING_PTR(x), RSTRING_LEN(x)); +%enddef + +/* + Generate the typemaps for a class that has 'value' traits +*/ + +%define %typemap_traits(Code,Type...) + %typemaps_asvalfrom(%arg(Code), + %arg(swig::asval<Type >), + %arg(swig::from), + %arg(SWIG_Traits_frag(Type)), + %arg(SWIG_Traits_frag(Type)), + Type); +%enddef + +/* + Generate the typemaps for a class that behaves more like a 'pointer' or + plain wrapped Swigtype. +*/ + +%define %typemap_traits_ptr(Code,Type...) + %typemaps_asptrfrom(%arg(Code), + %arg(swig::asptr), + %arg(swig::from), + %arg(SWIG_Traits_frag(Type)), + %arg(SWIG_Traits_frag(Type)), + Type); +%enddef + + +/* + Equality methods +*/ +%define %std_equal_methods(Type...) +%extend Type { + bool operator == (const Type& v) { + return *self == v; + } + + bool operator != (const Type& v) { + return *self != v; + } } -VALUE SWIG_STR2RB(const std::string& s) { - return rb_str_new(s.data(), s.size()); + +%enddef + +/* + Order methods +*/ + +%define %std_order_methods(Type...) +%extend Type { + bool operator > (const Type& v) { + return *self > v; + } + + bool operator < (const Type& v) { + return *self < v; + } + + bool operator >= (const Type& v) { + return *self >= v; + } + + bool operator <= (const Type& v) { + return *self <= v; + } } -%} +%enddef + +/* + Comparison methods +*/ + +%define %std_comp_methods(Type...) +%std_equal_methods(Type ) +%std_order_methods(Type ) +%enddef + + + +// +// Generates the traits for all the known primitive +// C++ types (int, double, ...) +// +%apply_cpptypes(%traits_ptypen); + diff --git a/Lib/ruby/std_container.i b/Lib/ruby/std_container.i new file mode 100644 index 000000000..85379505c --- /dev/null +++ b/Lib/ruby/std_container.i @@ -0,0 +1,2 @@ +%include <rubycontainer.swg> +%include <std/std_container.i> diff --git a/Lib/ruby/std_deque.i b/Lib/ruby/std_deque.i index c1ee13758..17e78efe9 100644 --- a/Lib/ruby/std_deque.i +++ b/Lib/ruby/std_deque.i @@ -1,12 +1,27 @@ -/* Default std_deque wrapper */ -%module std_deque +/* + Deques +*/ -%rename(__getitem__) std::deque::getitem; -%rename(__setitem__) std::deque::setitem; +%fragment("StdDequeTraits","header",fragment="StdSequenceTraits") +%{ + namespace swig { + template <class T> + struct traits_asptr<std::deque<T> > { + static int asptr(VALUE obj, std::deque<T> **vec) { + return traits_asptr_stdseq<std::deque<T> >::asptr(obj, vec); + } + }; -%predicate std::deque::empty; + template <class T> + struct traits_from<std::deque<T> > { + static VALUE from(const std::deque<T> & vec) { + return traits_from_stdseq<std::deque<T> >::from(vec); + } + }; + } +%} -%alias std::deque::push_back "<<"; -%alias std::deque::size "length"; +#define %swig_deque_methods(Type...) %swig_sequence_methods(Type) +#define %swig_deque_methods_val(Type...) %swig_sequence_methods_val(Type); -%include <std/_std_deque.i> +%include <std/std_deque.i> diff --git a/Lib/ruby/std_ios.i b/Lib/ruby/std_ios.i new file mode 100644 index 000000000..aa6f0994d --- /dev/null +++ b/Lib/ruby/std_ios.i @@ -0,0 +1,3 @@ +%rename(ios_base_in) std::ios_base::in; + +%include <std/std_ios.i> diff --git a/Lib/ruby/std_list.i b/Lib/ruby/std_list.i new file mode 100644 index 000000000..adc7d6f49 --- /dev/null +++ b/Lib/ruby/std_list.i @@ -0,0 +1,28 @@ +/* + Lists +*/ + +%fragment("StdListTraits","header",fragment="StdSequenceTraits") +%{ + namespace swig { + template <class T > + struct traits_asptr<std::list<T> > { + static int asptr(VALUE obj, std::list<T> **lis) { + return traits_asptr_stdseq<std::list<T> >::asptr(obj, lis); + } + }; + + template <class T> + struct traits_from<std::list<T> > { + static VALUE from(const std::list<T> & vec) { + return traits_from_stdseq<std::list<T> >::from(vec); + } + }; + } +%} + +#define %swig_list_methods(Type...) %swig_sequence_methods(Type) +#define %swig_list_methods_val(Type...) %swig_sequence_methods_val(Type); + +%include <std/std_list.i> + diff --git a/Lib/ruby/std_map.i b/Lib/ruby/std_map.i index 63b8d91fd..a30de684a 100644 --- a/Lib/ruby/std_map.i +++ b/Lib/ruby/std_map.i @@ -1,1266 +1,240 @@ -/* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * - * std_map.i - * - * SWIG typemaps for std::map - * ----------------------------------------------------------------------------- */ - -%include <std_common.i> - -// ------------------------------------------------------------------------ -// std::map // -// The aim of all that follows would be to integrate std::map with -// Ruby as much as possible, namely, to allow the user to pass and -// be returned Ruby hash maps. -// const declarations are used to guess the intent of the function being -// exported; therefore, the following rationale is applied: +// Maps // -// -- f(std::map<T>), f(const std::map<T>&), f(const std::map<T>*): -// the parameter being read-only, either a Ruby hash or a -// previously wrapped std::map<T> can be passed. -// -- f(std::map<T>&), f(std::map<T>*): -// the parameter must be modified; therefore, only a wrapped std::map -// can be passed. -// -- std::map<T> f(): -// the map is returned by copy; therefore, a Ruby hash -// is returned which is most easily used in other Ruby functions -// -- std::map<T>& f(), std::map<T>* f(), const std::map<T>& f(), -// const std::map<T>* f(): -// the map is returned by reference; therefore, a wrapped std::map -// is returned -// ------------------------------------------------------------------------ - -%{ -#include <map> -#include <algorithm> -#include <stdexcept> -%} - -// exported class - -namespace std { - - %mixin map "Enumerable"; - - template<class K, class T> class map { - %typemap(in) map<K,T> (std::map<K,T>* m) { - if (rb_obj_is_kind_of($input,rb_cHash)) { - $1 = std::map<K,T >(); - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - for (unsigned int i=0; i<size; i++) { - K* k; - T* x; - VALUE key = RARRAY_PTR(keys)[i]; - VALUE val = rb_hash_aref($input,key); - SWIG_ConvertPtr(key, (void **) &k, $descriptor(K *), 1); - SWIG_ConvertPtr(val, (void **) &x, $descriptor(T *), 1); - (($1_type &)$1)[*k] = *x; - } - } else { - SWIG_ConvertPtr($input, (void **) &m, $&1_descriptor, 1); - $1 = *m; - } - } - %typemap(in) const map<K,T>& (std::map<K,T> temp, - std::map<K,T>* m), - const map<K,T>* (std::map<K,T> temp, - std::map<K,T>* m) { - if (rb_obj_is_kind_of($input,rb_cHash)) { - temp = std::map<K,T >(); - $1 = &temp; - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - for (unsigned int i=0; i<size; i++) { - K* k; - T* x; - VALUE key = RARRAY_PTR(keys)[i]; - VALUE val = rb_hash_aref($input,key); - SWIG_ConvertPtr(key, (void **) &k, $descriptor(K *), 1); - SWIG_ConvertPtr(val, (void **) &x, $descriptor(T *), 1); - temp[*k] = *x; - } - } else { - SWIG_ConvertPtr($input, (void **) &m, $1_descriptor, 1); - $1 = m; - } - } - %typemap(out) map<K,T> { - $result = rb_hash_new(); - for (std::map<K,T >::iterator i=$1.begin(); i!=$1.end(); ++i) { - K* key = new K(i->first); - T* val = new T(i->second); - rb_hash_aset($result, - SWIG_NewPointerObj((void *) key, - $descriptor(K *), 1), - SWIG_NewPointerObj((void *) val, - $descriptor(T *), 1)); - } - } - %typecheck(SWIG_TYPECHECK_MAP) map<K,T> { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cHash)) { - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - if (size == 0) { - /* an empty dictionary can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - K* k; - T* x; - VALUE key = RARRAY_PTR(keys)[0]; - VALUE val = rb_hash_aref($input,key); - if (SWIG_ConvertPtr(key,(void **) &k, - $descriptor(K *),0) != -1 && - SWIG_ConvertPtr(val,(void **) &x, - $descriptor(T *),0) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped map? */ - std::map<K,T >* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_MAP) const map<K,T>&, - const map<K,T>* { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cHash)) { - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - if (size == 0) { - /* an empty dictionary can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - K* k; - T* x; - VALUE key = RARRAY_PTR(keys)[0]; - VALUE val = rb_hash_aref($input,key); - if (SWIG_ConvertPtr(key,(void **) &k, - $descriptor(K *),0) != -1 && - SWIG_ConvertPtr(val,(void **) &x, - $descriptor(T *),0) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped map? */ - std::map<K,T >* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %rename(__len__) size; - %rename("empty?") empty; - %rename("delete") __delitem__; - %rename("has_key?") has_key; - public: - map(); - map(const map<K,T> &); - - unsigned int size() const; - bool empty() const; - void clear(); - %extend { - T& __getitem__(const K& key) throw (std::out_of_range) { - std::map<K,T >::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void __setitem__(const K& key, const T& x) { - (*self)[key] = x; - } - T __delitem__(const K& key) throw (std::out_of_range) { - std::map<K,T >::iterator i = self->find(key); - if (i != self->end()) { - T x = i->second; - self->erase(i); - return x; - } else - throw std::out_of_range("key not found"); - } - bool has_key(const K& key) { - std::map<K,T >::iterator i = self->find(key); - return i != self->end(); - } - VALUE keys() { - VALUE keyList = rb_ary_new2(self->size()); - std::map<K,T >::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - K* ptr = new K(i->first); - rb_ary_store(keyList,j, - SWIG_NewPointerObj((void *) ptr, - $descriptor(K *),1)); - } - return keyList; - } - VALUE values() { - VALUE valueList = rb_ary_new2(self->size()); - std::map<K,T >::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - T* ptr = new T(i->second); - rb_ary_store(valueList,j, - SWIG_NewPointerObj((void *) ptr, - $descriptor(T *),1)); - } - return valueList; - } - void each() { - std::map<K,T >::iterator i; - for (i=self->begin(); i!=self->end(); ++i) { - K* key = new K(i->first); - T* val = &(i->second); - VALUE entry = rb_ary_new2(2); - VALUE k = SWIG_NewPointerObj((void *) key, - $descriptor(K *),1); - VALUE x = SWIG_NewPointerObj((void *) val, - $descriptor(T *),0); - rb_ary_store(entry,0,k); - rb_ary_store(entry,1,x); - rb_yield(entry); - } - } - } +%fragment("StdMapTraits","header",fragment="StdSequenceTraits") +{ + namespace swig { + template <class RubySeq, class K, class T > + inline void + assign(const RubySeq& rubyseq, std::map<K,T > *map) { + typedef typename std::map<K,T>::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + map->insert(value_type(it->first, it->second)); + } + } + + template <class K, class T> + struct traits_asptr<std::map<K,T> > { + typedef std::map<K,T> map_type; + static int asptr(PyObject *obj, map_type **val) { + int res = SWIG_ERROR; + if ( TYPE(obj) == T_HASH ) { + static ID id_to_a = rb_intern("to_a"); + VALUE items = rb_funcall(obj, id_to_a, 0); + res = traits_asptr_stdseq<std::map<K,T>, std::pair<K, T> >::asptr(items, val); + } else { + map_type *p; + res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info<map_type>(),0); + if (SWIG_IsOK(res) && val) *val = p; + } + return res; + } }; - - - // specializations for built-ins - - %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) - - %mixin map<K,T> "Enumerable"; - - template<class T> class map<K,T> { - %typemap(in) map<K,T> (std::map<K,T>* m) { - if (rb_obj_is_kind_of($input,rb_cHash)) { - $1 = std::map<K,T >(); - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - for (unsigned int i=0; i<size; i++) { - T* x; - VALUE key = RARRAY_PTR(keys)[i]; - VALUE val = rb_hash_aref($input,key); - if (!CHECK(key)) - rb_raise(rb_eTypeError, - "wrong argument type" - " (expected map<" #K "," #T ">)"); - SWIG_ConvertPtr(val,(void **) &x, - $descriptor(T *),1); - (($1_type &)$1)[CONVERT_FROM(key)] = *x; - } - } else { - SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,1); - $1 = *m; - } - } - %typemap(in) const map<K,T>& (std::map<K,T> temp, - std::map<K,T>* m), - const map<K,T>* (std::map<K,T> temp, - std::map<K,T>* m) { - if (rb_obj_is_kind_of($input,rb_cHash)) { - temp = std::map<K,T >(); - $1 = &temp; - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - for (unsigned int i=0; i<size; i++) { - T* x; - VALUE key = RARRAY_PTR(keys)[i]; - VALUE val = rb_hash_aref($input,key); - if (!CHECK(key)) - rb_raise(rb_eTypeError, - "wrong argument type" - " (expected map<" #K "," #T ">)"); - SWIG_ConvertPtr(val,(void **) &x, - $descriptor(T *),1); - temp[CONVERT_FROM(key)] = *x; - } - } else { - SWIG_ConvertPtr($input,(void **) &m,$1_descriptor,1); - $1 = m; - } - } - %typemap(out) map<K,T> { - $result = rb_hash_new(); - for (std::map<K,T >::iterator i=$1.begin(); i!=$1.end(); ++i) { - T* obj = new T(i->second); - rb_hash_aset($result, - CONVERT_TO(i->first), - SWIG_NewPointerObj((void *) obj, - $descriptor(T *), 1)); - } - } - %typecheck(SWIG_TYPECHECK_MAP) map<K,T> { - // native sequence? - if (rb_obj_is_kind_of($input,rb_cHash)) { - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - if (size == 0) { - // an empty dictionary can be of any type - $1 = 1; - } else { - // check the first element only - T* x; - VALUE key = RARRAY_PTR(keys)[0]; - VALUE val = rb_hash_aref($input,key); - if (CHECK(key) && - SWIG_ConvertPtr(val,(void **) &x, - $descriptor(T *),0) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - // wrapped map? - std::map<K,T >* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_MAP) const map<K,T>&, - const map<K,T>* { - // native sequence? - if (rb_obj_is_kind_of($input,rb_cHash)) { - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - if (size == 0) { - // an empty dictionary can be of any type - $1 = 1; - } else { - // check the first element only - T* x; - VALUE key = RARRAY_PTR(keys)[0]; - VALUE val = rb_hash_aref($input,key); - if (CHECK(key) && - SWIG_ConvertPtr(val,(void **) &x, - $descriptor(T *),0) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - // wrapped map? - std::map<K,T >* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %rename(__len__) size; - %rename("empty?") empty; - %rename("delete") __delitem__; - %rename("has_key?") has_key; - public: - map(); - map(const map<K,T> &); - - unsigned int size() const; - bool empty() const; - void clear(); - %extend { - T& __getitem__(K key) throw (std::out_of_range) { - std::map<K,T >::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void __setitem__(K key, const T& x) { - (*self)[key] = x; - } - T __delitem__(K key) throw (std::out_of_range) { - std::map<K,T >::iterator i = self->find(key); - if (i != self->end()) { - T x = i->second; - self->erase(i); - return x; - } else - throw std::out_of_range("key not found"); - } - bool has_key(K key) { - std::map<K,T >::iterator i = self->find(key); - return i != self->end(); - } - VALUE keys() { - VALUE keyList = rb_ary_new2(self->size()); - std::map<K,T >::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - rb_ary_store(keyList,j, - CONVERT_TO(i->first)); - } - return keyList; - } - VALUE values() { - VALUE valueList = rb_ary_new2(self->size()); - std::map<K,T >::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - T* ptr = new T(i->second); - rb_ary_store(valueList,j, - SWIG_NewPointerObj((void *) ptr, - $descriptor(T *),1)); - } - return valueList; - } - void each() { - std::map<K,T >::iterator i; - for (i=self->begin(); i!=self->end(); ++i) { - T* val = &(i->second); - VALUE entry = rb_ary_new2(2); - VALUE k = CONVERT_TO(i->first); - VALUE x = SWIG_NewPointerObj((void *) val, - $descriptor(T *),0); - rb_ary_store(entry,0,k); - rb_ary_store(entry,1,x); - rb_yield(entry); - } - } - } + + template <class K, class T > + struct traits_from<std::map<K,T> > { + typedef std::map<K,T> map_type; + typedef typename map_type::const_iterator const_iterator; + typedef typename map_type::size_type size_type; + + static VALUE from(const map_type& map) { + swig_type_info *desc = swig::type_info<map_type>(); + if (desc && desc->clientdata) { + return SWIG_NewPointerObj(new map_type(map), desc, SWIG_POINTER_OWN); + } else { + size_type size = map.size(); + int rubysize = (size <= (size_type) INT_MAX) ? (int) size : -1; + if (rubysize < 0) { + SWIG_RUBY_THREAD_BEGIN_BLOCK; + rb_raise( rb_eRuntimeError, "map size not valid in Ruby"); + SWIG_RUBY_THREAD_END_BLOCK; + return Qnil; + } + VALUE obj = rb_hash_new(); + for (const_iterator i= map.begin(); i!= map.end(); ++i) { + VALUE key = swig::from(i->first); + VALUE val = swig::from(i->second); + rb_hash_aset(obj, key, val); + } + return obj; + } + } }; - %enddef - - %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) - %mixin map<K,T> "Enumerable"; - - template<class K> class map<K,T> { - %typemap(in) map<K,T> (std::map<K,T>* m) { - if (rb_obj_is_kind_of($input,rb_cHash)) { - $1 = std::map<K,T >(); - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - for (unsigned int i=0; i<size; i++) { - K* k; - VALUE key = RARRAY_PTR(keys)[i]; - VALUE val = rb_hash_aref($input,key); - if (!CHECK(val)) - rb_raise(rb_eTypeError, - "wrong argument type" - " (expected map<" #K "," #T ">)"); - SWIG_ConvertPtr(key,(void **) &k, - $descriptor(K *),1); - (($1_type &)$1)[*k] = CONVERT_FROM(val); - } - } else { - SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,1); - $1 = *m; - } - } - %typemap(in) const map<K,T>& (std::map<K,T> temp, - std::map<K,T>* m), - const map<K,T>* (std::map<K,T> temp, - std::map<K,T>* m) { - if (rb_obj_is_kind_of($input,rb_cHash)) { - temp = std::map<K,T >(); - $1 = &temp; - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - for (unsigned int i=0; i<size; i++) { - K* k; - VALUE key = RARRAY_PTR(keys)[i]; - VALUE val = rb_hash_aref($input,key); - if (!CHECK(val)) - rb_raise(rb_eTypeError, - "wrong argument type" - " (expected map<" #K "," #T ">)"); - SWIG_ConvertPtr(key,(void **) &k, - $descriptor(K *),1); - temp[*k] = CONVERT_FROM(val); - } - } else { - SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,1); - $1 = m; - } - } - %typemap(out) map<K,T> { - $result = rb_hash_new(); - for (std::map<K,T >::iterator i=$1.begin(); i!=$1.end(); ++i) { - K* key = new K(i->first); - rb_hash_aset($result, - SWIG_NewPointerObj((void *) key, - $descriptor(K *), 1), - CONVERT_TO(i->second)); - } - } - %typecheck(SWIG_TYPECHECK_MAP) map<K,T> { - // native sequence? - if (rb_obj_is_kind_of($input,rb_cHash)) { - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - if (size == 0) { - // an empty dictionary can be of any type - $1 = 1; - } else { - // check the first element only - K* k; - VALUE key = RARRAY_PTR(keys)[0]; - VALUE val = rb_hash_aref($input,key); - if (SWIG_ConvertPtr(val,(void **) &k, - $descriptor(K *),0) != -1 && - CHECK(val)) - $1 = 1; - else - $1 = 0; - } - } else { - // wrapped map? - std::map<K,T >* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_MAP) const map<K,T>&, - const map<K,T>* { - // native sequence? - if (rb_obj_is_kind_of($input,rb_cHash)) { - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - if (size == 0) { - // an empty dictionary can be of any type - $1 = 1; - } else { - // check the first element only - K* k; - VALUE key = RARRAY_PTR(keys)[0]; - VALUE val = rb_hash_aref($input,key); - if (SWIG_ConvertPtr(val,(void **) &k, - $descriptor(K *),0) != -1 && - CHECK(val)) - $1 = 1; - else - $1 = 0; - } - } else { - // wrapped map? - std::map<K,T >* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %rename(__len__) size; - %rename("empty?") empty; - %rename("delete") __delitem__; - %rename("has_key?") has_key; - public: - map(); - map(const map<K,T> &); - - unsigned int size() const; - bool empty() const; - void clear(); - %extend { - T __getitem__(const K& key) throw (std::out_of_range) { - std::map<K,T >::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void __setitem__(const K& key, T x) { - (*self)[key] = x; - } - T __delitem__(const K& key) throw (std::out_of_range) { - std::map<K,T >::iterator i = self->find(key); - if (i != self->end()) { - T x = i->second; - self->erase(i); - return x; - } else - throw std::out_of_range("key not found"); - } - bool has_key(const K& key) { - std::map<K,T >::iterator i = self->find(key); - return i != self->end(); - } - VALUE keys() { - VALUE keyList = rb_ary_new2(self->size()); - std::map<K,T >::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - K* ptr = new K(i->first); - rb_ary_store(keyList,j, - SWIG_NewPointerObj((void *) ptr, - $descriptor(K *),1)); - } - return keyList; - } - VALUE values() { - VALUE valueList = rb_ary_new2(self->size()); - std::map<K,T >::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - rb_ary_store(valueList,j, - CONVERT_TO(i->second)); - } - return valueList; - } - void each() { - std::map<K,T >::iterator i; - for (i=self->begin(); i!=self->end(); ++i) { - K* key = new K(i->first); - VALUE entry = rb_ary_new2(2); - VALUE k = SWIG_NewPointerObj((void *) key, - $descriptor(K *),1); - VALUE x = CONVERT_TO(i->second); - rb_ary_store(entry,0,k); - rb_ary_store(entry,1,x); - rb_yield(entry); - } - } - } + template <class ValueType> + struct from_key_oper + { + typedef const ValueType& argument_type; + typedef VALUE result_type; + result_type operator()(argument_type v) const + { + return swig::from(v.first); + } }; - %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) - %mixin map<K,T> "Enumerable"; - template<> class map<K,T> { - %typemap(in) map<K,T> (std::map<K,T>* m) { - if (rb_obj_is_kind_of($input,rb_cHash)) { - $1 = std::map<K,T >(); - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - for (unsigned int i=0; i<size; i++) { - VALUE key = RARRAY_PTR(keys)[i]; - VALUE val = rb_hash_aref($input,key); - if (!(CHECK_K(key) && CHECK_T(val))) - rb_raise(rb_eTypeError, - "wrong argument type" - " (expected map<" #K "," #T ">)"); - (($1_type &)$1)[CONVERT_K_FROM(key)] = - CONVERT_T_FROM(val); - } - } else { - SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,1); - $1 = *m; - } - } - %typemap(in) const map<K,T>& (std::map<K,T> temp, - std::map<K,T>* m), - const map<K,T>* (std::map<K,T> temp, - std::map<K,T>* m) { - if (rb_obj_is_kind_of($input,rb_cHash)) { - temp = std::map<K,T >(); - $1 = &temp; - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - for (unsigned int i=0; i<size; i++) { - VALUE key = RARRAY_PTR(keys)[i]; - VALUE val = rb_hash_aref($input,key); - if (!(CHECK_K(key) && CHECK_T(val))) - rb_raise(rb_eTypeError, - "wrong argument type" - " (expected map<" #K "," #T ">)"); - temp[CONVERT_K_FROM(key)] = CONVERT_T_FROM(val); - } - } else { - SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,1); - $1 = m; - } - } - %typemap(out) map<K,T> { - $result = rb_hash_new(); - for (std::map<K,T >::iterator i=$1.begin(); i!=$1.end(); ++i) { - rb_hash_aset($result, - CONVERT_K_TO(i->first), - CONVERT_T_TO(i->second)); - } - } - %typecheck(SWIG_TYPECHECK_MAP) map<K,T> { - // native sequence? - if (rb_obj_is_kind_of($input,rb_cHash)) { - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - if (size == 0) { - // an empty dictionary can be of any type - $1 = 1; - } else { - // check the first element only - VALUE key = RARRAY_PTR(keys)[0]; - VALUE val = rb_hash_aref($input,key); - if (CHECK_K(key) && CHECK_T(val)) - $1 = 1; - else - $1 = 0; - } - } else { - // wrapped map? - std::map<K,T >* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_MAP) const map<K,T>&, - const map<K,T>* { - // native sequence? - if (rb_obj_is_kind_of($input,rb_cHash)) { - VALUE keys = rb_funcall($input,rb_intern("keys"),0); - unsigned int size = RARRAY_LEN(keys); - if (size == 0) { - // an empty dictionary can be of any type - $1 = 1; - } else { - // check the first element only - VALUE key = RARRAY_PTR(keys)[0]; - VALUE val = rb_hash_aref($input,key); - if (CHECK_K(key) && CHECK_T(val)) - $1 = 1; - else - $1 = 0; - } - } else { - // wrapped map? - std::map<K,T >* m; - if (SWIG_ConvertPtr($input,(void **) &m, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %rename(__len__) size; - %rename("empty?") empty; - %rename("delete") __delitem__; - %rename("has_key?") has_key; - public: - map(); - map(const map<K,T> &); - - unsigned int size() const; - bool empty() const; - void clear(); - %extend { - T __getitem__(K key) throw (std::out_of_range) { - std::map<K,T >::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void __setitem__(K key, T x) { - (*self)[key] = x; - } - T __delitem__(K key) throw (std::out_of_range) { - std::map<K,T >::iterator i = self->find(key); - if (i != self->end()) { - T x = i->second; - self->erase(i); - return x; - } else - throw std::out_of_range("key not found"); - } - bool has_key(K key) { - std::map<K,T >::iterator i = self->find(key); - return i != self->end(); - } - VALUE keys() { - VALUE keyList = rb_ary_new2(self->size()); - std::map<K,T >::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - rb_ary_store(keyList,j, - CONVERT_K_TO(i->first)); - } - return keyList; - } - VALUE values() { - VALUE valueList = rb_ary_new2(self->size()); - std::map<K,T >::iterator i; - unsigned int j; - for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { - rb_ary_store(valueList,j, - CONVERT_T_TO(i->second)); - } - return valueList; - } - void each() { - std::map<K,T >::iterator i; - for (i=self->begin(); i!=self->end(); ++i) { - VALUE entry = rb_ary_new2(2); - rb_ary_store(entry,0,CONVERT_K_TO(i->first)); - rb_ary_store(entry,1,CONVERT_T_TO(i->second)); - rb_yield(entry); - } - } - } + template <class ValueType> + struct from_value_oper + { + typedef const ValueType& argument_type; + typedef VALUE result_type; + result_type operator()(argument_type v) const + { + return swig::from(v.second); + } }; - %enddef + template<class OutIterator, class FromOper, class ValueType = typename OutIterator::value_type> + struct RubyMapIterator_T : RubySwigIteratorClosed_T<OutIterator, ValueType, FromOper> + { + RubyMapIterator_T(OutIterator curr, OutIterator first, OutIterator last, VALUE seq) + : RubySwigIteratorClosed_T<OutIterator,ValueType,FromOper>(curr, first, last, seq) + { + } + }; - specialize_std_map_on_key(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_key(int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_key(short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_key(long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_key(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_key(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_key(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_key(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_key(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_key(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_map_on_value(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_value(int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_value(short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_value(long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_value(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_value(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_value(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_value(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_value(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_value(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); + template<class OutIterator, + class FromOper = from_key_oper<typename OutIterator::value_type> > + struct RubyMapKeyIterator_T : RubyMapIterator_T<OutIterator, FromOper> + { + RubyMapKeyIterator_T(OutIterator curr, OutIterator first, OutIterator last, VALUE seq) + : RubyMapIterator_T<OutIterator, FromOper>(curr, first, last, seq) + { + } + }; - specialize_std_map_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_map_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_map_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_map_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_map_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_map_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_map_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_map_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_map_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_map_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_map_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_map_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_map_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); + template<typename OutIter> + inline RubySwigIterator* + make_output_key_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, VALUE seq = 0) + { + return new RubyMapKeyIterator_T<OutIter>(current, begin, end, seq); + } + + template<class OutIterator, + class FromOper = from_value_oper<typename OutIterator::value_type> > + struct RubyMapValueIterator_T : RubyMapIterator_T<OutIterator, FromOper> + { + RubyMapValueIterator_T(OutIterator curr, OutIterator first, OutIterator last, VALUE seq) + : RubyMapIterator_T<OutIterator, FromOper>(curr, first, last, seq) + { + } + }; + + + template<typename OutIter> + inline RubySwigIterator* + make_output_value_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, VALUE seq = 0) + { + return new RubyMapValueIterator_T<OutIter>(current, begin, end, seq); + } + } } + +%define %swig_map_common(Map...) + %swig_sequence_iterator(Map); + %swig_container_methods(Map) + + %extend { + VALUE __getitem__(const key_type& key) const { + Map::const_iterator i = self->find(key); + if ( i != self->end() ) + return swig::from( i->second ); + else + return Qnil; + } + + void __delitem__(const key_type& key) { + Map::iterator i = self->find(key); + if (i != self->end()) + self->erase(i); + else + return Qnil; + } + + %rename("has_key?") has_key; + bool has_key(const key_type& key) const { + Map::const_iterator i = self->find(key); + return i != self->end(); + } + + VALUE keys() { + Map::size_type size = self->size(); + int rubysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1; + if (rubysize < 0) { + SWIG_RUBY_THREAD_BEGIN_BLOCK; + rb_raise(rb_eRuntimeError, "map size not valid in Ruby"); + SWIG_RUBY_THREAD_END_BLOCK; + return Qnil; + } + VALUE ary = rb_ary_new2(rubysize); + Map::const_iterator i = self->begin(); + for (int j = 0; j < rubysize; ++i, ++j) { + rb_ary_aset(ary, j, swig::from(i->first)); + } + return ary; + } + + VALUE values() { + Map::size_type size = self->size(); + int rubysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1; + if (rubysize < 0) { + SWIG_RUBY_THREAD_BEGIN_BLOCK; + rb_raise(rb_eRuntimeError, "map size not valid in Ruby"); + SWIG_RUBY_THREAD_END_BLOCK; + return Qnil; + } + VALUE ary = rb_ary_new2(rubysize); + Map::const_iterator i = self->begin(); + for (int j = 0; j < rubysize; ++i, ++j) { + rb_ary_aset(ary, j, swig::from(i->second)); + } + return ary; + } + + VALUE entries() { + Map::size_type size = self->size(); + int rubysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1; + if (rubysize < 0) { + SWIG_RUBY_THREAD_BEGIN_BLOCK; + rb_raise(rb_eRuntimeError, "map size not valid in Ruby"); + SWIG_RUBY_THREAD_END_BLOCK; + return Qnil; + } + VALUE ary = rb_ary_new2(rubysize); + Map::const_iterator i = self->begin(); + for (int j = 0; j < rubysize; ++i, ++j) { + rb_ary_aset(ary, j, swig::from(*i)); + } + return ary; + } + + %rename("include?") __contains__; + bool __contains__(const key_type& key) { + return self->find(key) != self->end(); + } + + %newobject key_iterator(VALUE *RUBY_SELF); + swig::RubySwigIterator* key_iterator(VALUE *RUBY_SELF) { + return swig::make_output_key_iterator(self->begin(), self->begin(), self->end(), *RUBY_SELF); + } + + %newobject value_iterator(VALUE *RUBY_SELF); + swig::RubySwigIterator* value_iterator(VALUE *RUBY_SELF) { + return swig::make_output_value_iterator(self->begin(), self->begin(), self->end(), *RUBY_SELF); + } + + } +%enddef + +%define %swig_map_methods(Map...) + %swig_map_common(Map) + %extend { + void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) { + (*self)[key] = x; + } + } +%enddef + + +%include <std/std_map.i> diff --git a/Lib/ruby/std_multimap.i b/Lib/ruby/std_multimap.i new file mode 100644 index 000000000..05413316e --- /dev/null +++ b/Lib/ruby/std_multimap.i @@ -0,0 +1,80 @@ +/* + Multimaps +*/ +%include <std_map.i> + +%fragment("StdMultimapTraits","header",fragment="StdSequenceTraits") +{ + namespace swig { + template <class RubySeq, class K, class T > + inline void + assign(const RubySeq& rubyseq, std::multimap<K,T > *multimap) { + typedef typename std::multimap<K,T>::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + multimap->insert(value_type(it->first, it->second)); + } + } + + template <class K, class T> + struct traits_asptr<std::multimap<K,T> > { + typedef std::multimap<K,T> multimap_type; + static int asptr(PyObject *obj, std::multimap<K,T> **val) { + int res = SWIG_ERROR; + if ( TYPE(obj) == T_HASH ) { + static ID id_to_a = rb_intern("to_a"); + VALUE items = rb_funcall(obj, id_to_a, 0); + return traits_asptr_stdseq<std::multimap<K,T>, std::pair<K, T> >::asptr(items, val); + } else { + multimap_type *p; + res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info<multimap_type>(),0); + if (SWIG_IsOK(res) && val) *val = p; + } + return res; + } + }; + + template <class K, class T > + struct traits_from<std::multimap<K,T> > { + typedef std::multimap<K,T> multimap_type; + typedef typename multimap_type::const_iterator const_iterator; + typedef typename multimap_type::size_type size_type; + + static VALUE from(const multimap_type& multimap) { + swig_type_info *desc = swig::type_info<multimap_type>(); + if (desc && desc->clientdata) { + return SWIG_NewPointerObj(new multimap_type(multimap), desc, SWIG_POINTER_OWN); + } else { + size_type size = multimap.size(); + int rubysize = (size <= (size_type) INT_MAX) ? (int) size : -1; + if (rubysize < 0) { + SWIG_RUBY_THREAD_BEGIN_BLOCK; + rb_raise(rb_eRuntimeError, + "multimap size not valid in Ruby"); + SWIG_RUBY_THREAD_END_BLOCK; + return Qnil; + } + VALUE obj = rb_hash_new(); + for (const_iterator i= multimap.begin(); i!= multimap.end(); ++i) { + VALUE key = swig::from(i->first); + VALUE val = swig::from(i->second); + rb_hash_aset(obj, key, val); + } + return obj; + } + } + }; + } +} + +%define %swig_multimap_methods(Type...) + %swig_map_common(Type); + %extend { + void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) { + self->insert(Type::value_type(key,x)); + } + } +%enddef + +%include <std/std_multimap.i> + diff --git a/Lib/ruby/std_multiset.i b/Lib/ruby/std_multiset.i new file mode 100644 index 000000000..c65b2208c --- /dev/null +++ b/Lib/ruby/std_multiset.i @@ -0,0 +1,44 @@ +/* + Multisets +*/ + +%include <std_set.i> + +%fragment("StdMultisetTraits","header",fragment="StdSequenceTraits") +%{ + namespace swig { + template <class RubySeq, class T> + inline void + assign(const RubySeq& rubyseq, std::multiset<T>* seq) { +#ifdef SWIG_STD_NOINSERT_TEMPLATE_STL + typedef typename RubySeq::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + seq->insert(seq->end(),(value_type)(*it)); + } +#else + seq->insert(rubyseq.begin(), rubyseq.end()); +#endif + } + + template <class T> + struct traits_asptr<std::multiset<T> > { + static int asptr(VALUE obj, std::multiset<T> **m) { + return traits_asptr_stdseq<std::multiset<T> >::asptr(obj, m); + } + }; + + template <class T> + struct traits_from<std::multiset<T> > { + static VALUE from(const std::multiset<T>& vec) { + return traits_from_stdseq<std::multiset<T> >::from(vec); + } + }; + } +%} + +#define %swig_multiset_methods(Set...) %swig_set_methods(Set) + + + +%include <std/std_multiset.i> diff --git a/Lib/ruby/std_pair.i b/Lib/ruby/std_pair.i index 626a6c3c8..03f1a18da 100644 --- a/Lib/ruby/std_pair.i +++ b/Lib/ruby/std_pair.i @@ -1,951 +1,209 @@ -/* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * - * std_pair.i - * - * SWIG typemaps for std::pair - * ----------------------------------------------------------------------------- */ - -%include <std_common.i> -%include <exception.i> - -// ------------------------------------------------------------------------ -// std::pair -// -// See std_vector.i for the rationale of typemap application -// ------------------------------------------------------------------------ - -%{ -#include <utility> -%} - -// exported class - -namespace std { - - template<class T, class U> struct pair { - %typemap(in) pair<T,U> (std::pair<T,U>* p) { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - T* x; - U* y; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - SWIG_ConvertPtr(first, (void **) &x, $descriptor(T *), 1); - SWIG_ConvertPtr(second, (void **) &y, $descriptor(U *), 1); - $1 = std::make_pair(*x,*y); - } else { - SWIG_ConvertPtr($input, (void **) &p, $&1_descriptor, 1); - $1 = *p; - } - } - %typemap(in) const pair<T,U>& (std::pair<T,U> temp, - std::pair<T,U>* p), - const pair<T,U>* (std::pair<T,U> temp, - std::pair<T,U>* p) { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - T* x; - U* y; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - SWIG_ConvertPtr(first, (void **) &x, $descriptor(T *), 1); - SWIG_ConvertPtr(second, (void **) &y, $descriptor(U *), 1); - temp = std::make_pair(*x,*y); - $1 = &temp; - } else { - SWIG_ConvertPtr($input, (void **) &p, $1_descriptor, 1); - $1 = p; - } - } - %typemap(out) pair<T,U> { - $result = rb_ary_new2(2); - T* x = new T($1.first); - U* y = new U($1.second); - rb_ary_store($result,0, - SWIG_NewPointerObj((void *) x, - $descriptor(T *), 1)); - rb_ary_store($result,1, - SWIG_NewPointerObj((void *) y, - $descriptor(U *), 1)); - } - %typecheck(SWIG_TYPECHECK_PAIR) pair<T,U> { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - /* not a pair */ - $1 = 0; - } else { - T* x; - U* y; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped pair? */ - std::pair<T,U >* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_PAIR) const pair<T,U>&, - const pair<T,U>* { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cHash)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - /* not a pair */ - $1 = 0; - } else { - T* x; - U* y; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped map? */ - std::pair<T,U >* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - pair(); - pair(T first, U second); - pair(const pair& p); - - template <class U1, class U2> pair(const pair<U1, U2> &p); - - T first; - U second; +/* + Pairs +*/ +%include <rubystdcommon.swg> + +//#define SWIG_STD_PAIR_ASVAL + +%fragment("StdPairTraits","header",fragment="StdTraits") { + namespace swig { +#ifdef SWIG_STD_PAIR_ASVAL + template <class T, class U > + struct traits_asval<std::pair<T,U> > { + typedef std::pair<T,U> value_type; + + static int get_pair(VALUE first, VALUE second, + std::pair<T,U> *val) + { + if (val) { + T *pfirst = &(val->first); + int res1 = swig::asval((VALUE)first, pfirst); + if (!SWIG_IsOK(res1)) return res1; + U *psecond = &(val->second); + int res2 = swig::asval((VALUE)second, psecond); + if (!SWIG_IsOK(res2)) return res2; + return res1 > res2 ? res1 : res2; + } else { + T *pfirst = 0; + int res1 = swig::asval((VALUE)first, 0); + if (!SWIG_IsOK(res1)) return res1; + U *psecond = 0; + int res2 = swig::asval((VALUE)second, psecond); + if (!SWIG_IsOK(res2)) return res2; + return res1 > res2 ? res1 : res2; + } + } + + static int asval(VALUE obj, std::pair<T,U> *val) { + int res = SWIG_ERROR; + if ( TYPE(obj) == T_ARRAY ) { + if (RARRAY_LEN(obj) == 2) { + VALUE first = rb_ary_entry(obj,0); + VALUE second = rb_ary_entry(obj,1); + res = get_pair(first, second, val); + } + } else { + value_type *p; + res = SWIG_ConvertPtr(obj,(void**)&p, + swig::type_info<value_type>(),0); + if (SWIG_IsOK(res) && val) *val = *p; + } + return res; + } }; - - // specializations for built-ins - - %define specialize_std_pair_on_first(T,CHECK,CONVERT_FROM,CONVERT_TO) - - template<class U> struct pair<T,U> { - %typemap(in) pair<T,U> (std::pair<T,U>* p) { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - U* y; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (!CHECK(first)) - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - SWIG_ConvertPtr(second, (void **) &y, $descriptor(U *), 1); - $1 = std::make_pair(CONVERT_FROM(first),*y); - } else { - SWIG_ConvertPtr($input, (void **) &p, $&1_descriptor, 1); - $1 = *p; - } - } - %typemap(in) const pair<T,U>& (std::pair<T,U> temp, - std::pair<T,U>* p), - const pair<T,U>* (std::pair<T,U> temp, - std::pair<T,U>* p) { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - U* y; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (!CHECK(first)) - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - SWIG_ConvertPtr(second, (void **) &y, $descriptor(U *), 1); - temp = std::make_pair(CONVERT_FROM(first),*y); - $1 = &temp; - } else { - SWIG_ConvertPtr($input, (void **) &p, $1_descriptor, 1); - $1 = p; - } - } - %typemap(out) pair<T,U> { - $result = rb_ary_new2(2); - U* y = new U($1.second); - rb_ary_store($result,0,CONVERT_TO($1.first)); - rb_ary_store($result,1, - SWIG_NewPointerObj((void *) y, - $descriptor(U *), 1)); - } - %typecheck(SWIG_TYPECHECK_MAP) pair<T,U> { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - /* not a pair */ - $1 = 0; - } else { - U* y; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (CHECK(first) && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped pair? */ - std::pair<T,U >* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_MAP) const pair<T,U>&, - const pair<T,U>* { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cHash)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - /* not a pair */ - $1 = 0; - } else { - U* y; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (CHECK(first) && - SWIG_ConvertPtr(second,(void **) &y, - $descriptor(U *),0) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped map? */ - std::pair<T,U >* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - pair(); - pair(T first, U second); - pair(const pair& p); - - template <class U1, class U2> pair(const pair<U1, U2> &p); - T first; - U second; +#else + template <class T, class U > + struct traits_asptr<std::pair<T,U> > { + typedef std::pair<T,U> value_type; + + static int get_pair(VALUE first, VALUE second, + std::pair<T,U> **val) + { + if (val) { + value_type *vp = %new_instance(std::pair<T,U>); + T *pfirst = &(vp->first); + int res1 = swig::asval((VALUE)first, pfirst); + if (!SWIG_IsOK(res1)) return res1; + U *psecond = &(vp->second); + int res2 = swig::asval((VALUE)second, psecond); + if (!SWIG_IsOK(res2)) return res2; + *val = vp; + return SWIG_AddNewMask(res1 > res2 ? res1 : res2); + } else { + T *pfirst = 0; + int res1 = swig::asval((VALUE)first, pfirst); + if (!SWIG_IsOK(res1)) return res1; + U *psecond = 0; + int res2 = swig::asval((VALUE)second, psecond); + if (!SWIG_IsOK(res2)) return res2; + return res1 > res2 ? res1 : res2; + } + } + + static int asptr(VALUE obj, std::pair<T,U> **val) { + int res = SWIG_ERROR; + if ( TYPE(obj) == T_ARRAY ) { + if ( RARRAY_LEN(obj) == 2) { + VALUE first = rb_ary_entry(obj,0); + VALUE second = rb_ary_entry(obj,1); + res = get_pair(first, second, val); + } + } else { + value_type *p; + res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info<value_type>(),0); + if (SWIG_IsOK(res) && val) *val = p; + } + return res; + } }; - %enddef - %define specialize_std_pair_on_second(U,CHECK,CONVERT_FROM,CONVERT_TO) - - template<class T> struct pair<T,U> { - %typemap(in) pair<T,U> (std::pair<T,U>* p) { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - T* x; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - SWIG_ConvertPtr(first, (void **) &x, $descriptor(T *), 1); - if (!CHECK(second)) - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - $1 = std::make_pair(*x,CONVERT_FROM(second)); - } else { - SWIG_ConvertPtr($input, (void **) &p, $&1_descriptor, 1); - $1 = *p; - } - } - %typemap(in) const pair<T,U>& (std::pair<T,U> temp, - std::pair<T,U>* p), - const pair<T,U>* (std::pair<T,U> temp, - std::pair<T,U>* p) { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - T* x; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - SWIG_ConvertPtr(first, (void **) &x, $descriptor(T *), 1); - if (!CHECK(second)) - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - temp = std::make_pair(*x,CONVERT_FROM(second)); - $1 = &temp; - } else { - SWIG_ConvertPtr($input, (void **) &p, $1_descriptor, 1); - $1 = p; - } - } - %typemap(out) pair<T,U> { - $result = rb_ary_new2(2); - T* x = new T($1.first); - rb_ary_store($result,0, - SWIG_NewPointerObj((void *) x, - $descriptor(T *), 1)); - rb_ary_store($result,1,CONVERT_TO($1.second)); - } - %typecheck(SWIG_TYPECHECK_PAIR) pair<T,U> { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - /* not a pair */ - $1 = 0; - } else { - T* x; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - CHECK(second)) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped pair? */ - std::pair<T,U >* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_PAIR) const pair<T,U>&, - const pair<T,U>* { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cHash)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - /* not a pair */ - $1 = 0; - } else { - T* x; - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (SWIG_ConvertPtr(first,(void **) &x, - $descriptor(T *),0) != -1 && - CHECK(second)) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped map? */ - std::pair<T,U >* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - pair(); - pair(T first, U second); - pair(const pair& p); - - template <class U1, class U2> pair(const pair<U1, U2> &p); - - T first; - U second; - }; - %enddef - - %define specialize_std_pair_on_both(T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO, - U,CHECK_U,CONVERT_U_FROM,CONVERT_U_TO) - template<> struct pair<T,U> { - %typemap(in) pair<T,U> (std::pair<T,U>* p) { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (!CHECK_T(first) || !CHECK_U(second)) - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - $1 = std::make_pair(CONVERT_T_FROM(first), - CONVERT_U_FROM(second)); - } else { - SWIG_ConvertPtr($input, (void **) &p, $&1_descriptor, 1); - $1 = *p; - } - } - %typemap(in) const pair<T,U>& (std::pair<T,U> temp, - std::pair<T,U>* p), - const pair<T,U>* (std::pair<T,U> temp, - std::pair<T,U>* p) { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - } - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (!CHECK_T(first) || !CHECK_U(second)) - SWIG_exception(SWIG_TypeError, - "pair<" #T "," #U "> expected"); - temp = std::make_pair(CONVERT_T_FROM(first), - CONVERT_U_FROM(second)); - $1 = &temp; - } else { - SWIG_ConvertPtr($input, (void **) &p, $1_descriptor, 1); - $1 = p; - } - } - %typemap(out) pair<T,U> { - $result = rb_ary_new2(2); - rb_ary_store($result,0,CONVERT_T_TO($1.first)); - rb_ary_store($result,1,CONVERT_U_TO($1.second)); - } - %typecheck(SWIG_TYPECHECK_PAIR) pair<T,U> { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - /* not a pair */ - $1 = 0; - } else { - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (CHECK_T(first) && CHECK_U(second)) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped pair? */ - std::pair<T,U >* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_PAIR) const pair<T,U>&, - const pair<T,U>* { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cHash)) { - unsigned int size = RARRAY_LEN($input); - if (size != 2) { - /* not a pair */ - $1 = 0; - } else { - VALUE first = RARRAY_PTR($input)[0]; - VALUE second = RARRAY_PTR($input)[1]; - if (CHECK_T(first) && CHECK_U(second)) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped map? */ - std::pair<T,U >* p; - if (SWIG_ConvertPtr($input,(void **) &p, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - pair(); - pair(T first, U second); - pair(const pair& p); - - template <class U1, class U2> pair(const pair<U1, U2> &p); - - T first; - U second; +#endif + + + template <class T, class U > + struct traits_from<std::pair<T,U> > { + static VALUE _wrap_pair_second( VALUE self ) + { + std::pair<T,U>* p = NULL; + swig::asptr( self, &p ); + return swig::from( p->second ); + fail: + return Qnil; + } + + static VALUE _wrap_pair_second_eq( VALUE self, VALUE arg ) + { + std::pair<T,U>* p = NULL; + swig::asptr( self, &p ); + return swig::from( p->second ); + fail: + return Qnil; + } + + static VALUE from(const std::pair<T,U>& val) { + VALUE obj = rb_ary_new2(2); + RARRAY_PTR(obj)[0] = swig::from(val.first); + RARRAY_PTR(obj)[1] = swig::from(val.second); + RARRAY_LEN(obj) = 2; + rb_define_singleton_method(obj, "second", + VALUEFUNC(_wrap_pair_second), 0 ); + rb_define_singleton_method(obj, "second=", + VALUEFUNC(_wrap_pair_second_eq), 1 ); + return obj; + } }; - %enddef + } +} - specialize_std_pair_on_first(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_first(int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_first(short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_first(long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_first(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_first(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_first(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_first(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_first(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_first(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); +// Missing typemap +%typemap(in) std::pair* (int res) { + res = swig::asptr( $input, &$1 ); + if (!SWIG_IsOK(res)) + %argument_fail(res, "$1_type", $symname, $argnum); +} - specialize_std_pair_on_second(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_second(int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_second(short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_second(long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_second(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_second(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_second(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_second(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_second(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_second(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_pair_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_pair_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(int,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_pair_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(short,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_pair_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(long,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_pair_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(unsigned int,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_pair_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(unsigned short,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_pair_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(unsigned long,FIXNUM_P, - FIX2INT,INT2NUM, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_pair_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_pair_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); - specialize_std_pair_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - bool,SWIG_BOOL_P, - SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_pair_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - unsigned int,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - unsigned short,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - unsigned long,FIXNUM_P, - FIX2INT,INT2NUM); - specialize_std_pair_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - double,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - float,SWIG_FLOAT_P, - SWIG_NUM2DBL,rb_float_new); - specialize_std_pair_on_both(std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB, - std::string,SWIG_STRING_P, - SWIG_RB2STR,SWIG_STR2RB); -} +%define %swig_pair_methods(pair...) +%extend { + VALUE inspect() + { + VALUE tmp; + VALUE str = rb_str_new2( swig::type_name< pair >() ); + str = rb_str_cat2( str, " (" ); + tmp = swig::from( $self->first ); + tmp = rb_obj_as_string( tmp ); + str = rb_str_buf_append( str, tmp ); + str = rb_str_cat2( str, "," ); + tmp = swig::from( $self->second ); + tmp = rb_obj_as_string( tmp ); + str = rb_str_buf_append( str, tmp ); + str = rb_str_cat2( str, ")" ); + return str; + } + + VALUE to_s() + { + VALUE tmp; + VALUE str = rb_str_new2( "(" ); + tmp = swig::from( $self->first ); + tmp = rb_obj_as_string( tmp ); + str = rb_str_buf_append( str, tmp ); + str = rb_str_cat2( str, "," ); + tmp = swig::from( $self->second ); + tmp = rb_obj_as_string( tmp ); + str = rb_str_buf_append( str, tmp ); + str = rb_str_cat2( str, ")" ); + return str; + } + + VALUE __getitem__( int index ) + { + if (( index % 2 ) == 0 ) + return swig::from( $self->first ); + else + return swig::from( $self->second ); + } + + VALUE __setitem__( int index, VALUE obj ) + { + int res; + if (( index % 2 ) == 0 ) + { + res = swig::asval( obj, &($self->first) ); + } + else + { + res = swig::asval(obj, &($self->second) ); + } + if (!SWIG_IsOK(res)) + rb_raise( rb_eArgError, "invalid item for " #pair ); + return obj; + } + + } // extend + +%enddef + +%include <std/std_pair.i> diff --git a/Lib/ruby/std_set.i b/Lib/ruby/std_set.i new file mode 100644 index 000000000..d0c3c992c --- /dev/null +++ b/Lib/ruby/std_set.i @@ -0,0 +1,60 @@ +/* + Sets +*/ + +%fragment("StdSetTraits","header",fragment="StdSequenceTraits") +%{ + namespace swig { + template <class RubySeq, class T> + inline void + assign(const RubySeq& rubyseq, std::set<T>* seq) { +#ifdef SWIG_STD_NOINSERT_TEMPLATE_STL + typedef typename RubySeq::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + seq->insert(seq->end(),(value_type)(*it)); + } +#else + seq->insert(rubyseq.begin(), rubyseq.end()); +#endif + } + + template <class T> + struct traits_asptr<std::set<T> > { + static int asptr(VALUE obj, std::set<T> **s) { + return traits_asptr_stdseq<std::set<T> >::asptr(obj, s); + } + }; + + template <class T> + struct traits_from<std::set<T> > { + static VALUE from(const std::set<T>& vec) { + return traits_from_stdseq<std::set<T> >::from(vec); + } + }; + } +%} + +%define %swig_set_methods(set...) + %swig_sequence_iterator(set); + %swig_container_methods(set); + + %extend { + const value_type& push(value_type x) { + self->insert(x); + return x; + } + + %rename("include?") __contains__; + bool __contains__(value_type x) { + return self->find(x) != self->end(); + } + + value_type __getitem__(difference_type i) const throw (std::out_of_range) { + return *(swig::cgetpos(self, i)); + } + + }; +%enddef + +%include <std/std_set.i> diff --git a/Lib/ruby/std_vector.i b/Lib/ruby/std_vector.i index 666e5f74f..a5072351c 100644 --- a/Lib/ruby/std_vector.i +++ b/Lib/ruby/std_vector.i @@ -1,497 +1,54 @@ -/* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * - * std_vector.i - * - * SWIG typemaps for std::vector - * ----------------------------------------------------------------------------- */ - -%include <std_common.i> - -// ------------------------------------------------------------------------ -// std::vector -// -// The aim of all that follows would be to integrate std::vector with -// Ruby as much as possible, namely, to allow the user to pass and -// be returned Ruby arrays -// const declarations are used to guess the intent of the function being -// exported; therefore, the following rationale is applied: -// -// -- f(std::vector<T>), f(const std::vector<T>&), f(const std::vector<T>*): -// the parameter being read-only, either a Ruby array or a -// previously wrapped std::vector<T> can be passed. -// -- f(std::vector<T>&), f(std::vector<T>*): -// the parameter must be modified; therefore, only a wrapped std::vector -// can be passed. -// -- std::vector<T> f(): -// the vector is returned by copy; therefore, a Ruby array of T:s -// is returned which is most easily used in other Ruby functions -// -- std::vector<T>& f(), std::vector<T>* f(), const std::vector<T>& f(), -// const std::vector<T>* f(): -// the vector is returned by reference; therefore, a wrapped std::vector -// is returned -// ------------------------------------------------------------------------ +/* + Vectors +*/ +%fragment("StdVectorTraits","header",fragment="StdSequenceTraits") %{ -#include <vector> -#include <algorithm> -#include <stdexcept> + namespace swig { + template <class T> + struct traits_asptr<std::vector<T> > { + static int asptr(VALUE obj, std::vector<T> **vec) { + return traits_asptr_stdseq<std::vector<T> >::asptr(obj, vec); + } + }; + + template <class T> + struct traits_from<std::vector<T> > { + static VALUE from(const std::vector<T>& vec) { + return traits_from_stdseq<std::vector<T> >::from(vec); + } + }; + } %} -// exported class -namespace std { - %mixin vector "Enumerable"; +%define %swig_vector_methods(Type...) + %swig_sequence_methods(Type) + %swig_sequence_front_inserters(Type); +%enddef - template<class T> class vector { - %typemap(in) vector<T> { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - $1; - for (unsigned int i=0; i<size; i++) { - VALUE o = RARRAY_PTR($input)[i]; - T* x; - SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1); - $1.push_back(*x); - } - } else { - void *ptr; - SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 1); - $1 = *(($&1_type) ptr); - } - } - %typemap(in) const vector<T>& (std::vector<T> temp), - const vector<T>* (std::vector<T> temp) { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - $1 = &temp; - for (unsigned int i=0; i<size; i++) { - VALUE o = RARRAY_PTR($input)[i]; - T* x; - SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1); - temp.push_back(*x); - } - } else { - SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1); - } - } - %typemap(out) vector<T> { - $result = rb_ary_new2($1.size()); - for (unsigned int i=0; i<$1.size(); i++) { - T* x = new T((($1_type &)$1)[i]); - rb_ary_store($result,i, - SWIG_NewPointerObj((void *) x, - $descriptor(T *), 1)); - } - } - %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size == 0) { - /* an empty sequence can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - T* x; - VALUE o = RARRAY_PTR($input)[0]; - if ((SWIG_ConvertPtr(o,(void **) &x, - $descriptor(T *),0)) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped vector? */ - std::vector<T >* v; - if (SWIG_ConvertPtr($input,(void **) &v, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&, - const vector<T>* { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size == 0) { - /* an empty sequence can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - T* x; - VALUE o = RARRAY_PTR($input)[0]; - if ((SWIG_ConvertPtr(o,(void **) &x, - $descriptor(T *),0)) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped vector? */ - std::vector<T >* v; - if (SWIG_ConvertPtr($input,(void **) &v, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - public: - vector(); - vector(unsigned int size); - vector(unsigned int size, const T& value); - vector(const vector<T> &); +%define %swig_vector_methods_val(Type...) + %swig_sequence_methods_val(Type); + %swig_sequence_front_inserters(Type); +%enddef - %rename(__len__) size; - unsigned int size() const; - %rename("empty?") empty; - bool empty() const; - void clear(); - %rename(push) push_back; - void push_back(const T& x); - %extend { - T pop() throw (std::out_of_range) { - if (self->size() == 0) - throw std::out_of_range("pop from empty vector"); - T x = self->back(); - self->pop_back(); - return x; - } - T& __getitem__(int i) throw (std::out_of_range) { - int size = int(self->size()); - if (i<0) i += size; - if (i>=0 && i<size) - return (*self)[i]; - else - throw std::out_of_range("vector index out of range"); - } - void __setitem__(int i, const T& x) throw (std::out_of_range) { - int size = int(self->size()); - if (i<0) i+= size; - if (i>=0 && i<size) - (*self)[i] = x; - else - throw std::out_of_range("vector index out of range"); - } - void each() { - for (unsigned int i=0; i<self->size(); i++) { - T* x = &((*self)[i]); - rb_yield(SWIG_NewPointerObj((void *) x, - $descriptor(T *), 0)); - } - } - } - }; - // Partial specialization for vectors of pointers. [ beazley ] +#if defined(SWIG_RUBY_AUTORENAME) - %mixin vector<T*> "Enumerable"; - template<class T> class vector<T*> { - %typemap(in) vector<T*> { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - $1 = std::vector<T* >(size); - for (unsigned int i=0; i<size; i++) { - VALUE o = RARRAY_PTR($input)[i]; - T* x; - SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1); - (($1_type &)$1)[i] = x; - } - } else { - void *ptr; - SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 1); - $1 = *(($&1_type) ptr); - } - } - %typemap(in) const vector<T*>& (std::vector<T*> temp), - const vector<T*>* (std::vector<T*> temp) { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - temp = std::vector<T* >(size); - $1 = &temp; - for (unsigned int i=0; i<size; i++) { - VALUE o = RARRAY_PTR($input)[i]; - T* x; - SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1); - temp[i] = x; - } - } else { - SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1); - } - } - %typemap(out) vector<T*> { - $result = rb_ary_new2($1.size()); - for (unsigned int i=0; i<$1.size(); i++) { - T* x = (($1_type &)$1)[i]; - rb_ary_store($result,i, - SWIG_NewPointerObj((void *) x, - $descriptor(T *), 0)); - } - } - %typecheck(SWIG_TYPECHECK_VECTOR) vector<T*> { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size == 0) { - /* an empty sequence can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - T* x; - VALUE o = RARRAY_PTR($input)[0]; - if ((SWIG_ConvertPtr(o,(void **) &x, - $descriptor(T *),0)) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped vector? */ - std::vector<T* >* v; - if (SWIG_ConvertPtr($input,(void **) &v, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T*>&, - const vector<T*>* { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size == 0) { - /* an empty sequence can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - T* x; - VALUE o = RARRAY_PTR($input)[0]; - if ((SWIG_ConvertPtr(o,(void **) &x, - $descriptor(T *),0)) != -1) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped vector? */ - std::vector<T* >* v; - if (SWIG_ConvertPtr($input,(void **) &v, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - public: - vector(); - vector(unsigned int size); - vector(unsigned int size, T * &value); - vector(const vector<T*> &); + %mixin std::vector "Enumerable"; + %rename("empty?") std::vector::empty; + %ignore std::vector::push_back; + %ignore std::vector::pop_back; - %rename(__len__) size; - unsigned int size() const; - %rename("empty?") empty; - bool empty() const; - void clear(); - %rename(push) push_back; - void push_back(T* x); - %extend { - T* pop() throw (std::out_of_range) { - if (self->size() == 0) - throw std::out_of_range("pop from empty vector"); - T* x = self->back(); - self->pop_back(); - return x; - } - T* __getitem__(int i) throw (std::out_of_range) { - int size = int(self->size()); - if (i<0) i += size; - if (i>=0 && i<size) - return (*self)[i]; - else - throw std::out_of_range("vector index out of range"); - } - void __setitem__(int i, T* x) throw (std::out_of_range) { - int size = int(self->size()); - if (i<0) i+= size; - if (i>=0 && i<size) - (*self)[i] = x; - else - throw std::out_of_range("vector index out of range"); - } - void each() { - for (unsigned int i=0; i<self->size(); i++) { - T* x = (*self)[i]; - rb_yield(SWIG_NewPointerObj((void *) x, - $descriptor(T *), 0)); - } - } - } - }; - - - // specializations for built-ins +#else - %define specialize_std_vector(T,CHECK,CONVERT_FROM,CONVERT_TO) - %mixin vector<T> "Enumerable"; - template<> class vector<T> { - %typemap(in) vector<T> { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - $1 = std::vector<T >(size); - for (unsigned int i=0; i<size; i++) { - VALUE o = RARRAY_PTR($input)[i]; - if (CHECK(o)) - (($1_type &)$1)[i] = (T)(CONVERT_FROM(o)); - else - rb_raise(rb_eTypeError, - "wrong argument type" - " (expected vector<" #T ">)"); - } - } else { - void *ptr; - SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 1); - $1 = *(($&1_type) ptr); - } - } - %typemap(in) const vector<T>& (std::vector<T> temp), - const vector<T>* (std::vector<T> temp) { - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - temp = std::vector<T >(size); - $1 = &temp; - for (unsigned int i=0; i<size; i++) { - VALUE o = RARRAY_PTR($input)[i]; - if (CHECK(o)) - temp[i] = (T)(CONVERT_FROM(o)); - else - rb_raise(rb_eTypeError, - "wrong argument type" - " (expected vector<" #T ">)"); - } - } else { - SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1); - } - } - %typemap(out) vector<T> { - $result = rb_ary_new2($1.size()); - for (unsigned int i=0; i<$1.size(); i++) - rb_ary_store($result,i,CONVERT_TO((($1_type &)$1)[i])); - } - %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size == 0) { - /* an empty sequence can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - VALUE o = RARRAY_PTR($input)[0]; - if (CHECK(o)) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped vector? */ - std::vector<T >* v; - if (SWIG_ConvertPtr($input,(void **) &v, - $&1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&, - const vector<T>* { - /* native sequence? */ - if (rb_obj_is_kind_of($input,rb_cArray)) { - unsigned int size = RARRAY_LEN($input); - if (size == 0) { - /* an empty sequence can be of any type */ - $1 = 1; - } else { - /* check the first element only */ - VALUE o = RARRAY_PTR($input)[0]; - if (CHECK(o)) - $1 = 1; - else - $1 = 0; - } - } else { - /* wrapped vector? */ - std::vector<T >* v; - if (SWIG_ConvertPtr($input,(void **) &v, - $1_descriptor,0) != -1) - $1 = 1; - else - $1 = 0; - } - } - public: - vector(); - vector(unsigned int size); - vector(unsigned int size, const T& value); - vector(const vector<T> &); - - %rename(__len__) size; - unsigned int size() const; - %rename("empty?") empty; - bool empty() const; - void clear(); - %rename(push) push_back; - void push_back(T x); - %extend { - T pop() throw (std::out_of_range) { - if (self->size() == 0) - throw std::out_of_range("pop from empty vector"); - T x = self->back(); - self->pop_back(); - return x; - } - T __getitem__(int i) throw (std::out_of_range) { - int size = int(self->size()); - if (i<0) i += size; - if (i>=0 && i<size) - return (*self)[i]; - else - throw std::out_of_range("vector index out of range"); - } - void __setitem__(int i, T x) throw (std::out_of_range) { - int size = int(self->size()); - if (i<0) i+= size; - if (i>=0 && i<size) - (*self)[i] = x; - else - throw std::out_of_range("vector index out of range"); - } - void each() { - for (unsigned int i=0; i<self->size(); i++) - rb_yield(CONVERT_TO((*self)[i])); - } - } - }; - %enddef + %mixin std::vector "Enumerable"; + %rename("empty?") std::vector::empty; + %ignore std::vector::push_back; + %ignore std::vector::pop_back; - specialize_std_vector(bool,SWIG_BOOL_P,SWIG_RB2BOOL,SWIG_BOOL2RB); - specialize_std_vector(char,FIXNUM_P,FIX2INT,INT2NUM); - specialize_std_vector(int,FIXNUM_P,FIX2INT,INT2NUM); - specialize_std_vector(short,FIXNUM_P,FIX2INT,INT2NUM); - specialize_std_vector(long,FIXNUM_P,FIX2INT,INT2NUM); - specialize_std_vector(unsigned char,FIXNUM_P,FIX2INT,INT2NUM); - specialize_std_vector(unsigned int,FIXNUM_P,FIX2INT,INT2NUM); - specialize_std_vector(unsigned short,FIXNUM_P,FIX2INT,INT2NUM); - specialize_std_vector(unsigned long,FIXNUM_P,FIX2INT,INT2NUM); - specialize_std_vector(double,SWIG_FLOAT_P,SWIG_NUM2DBL,rb_float_new); - specialize_std_vector(float,SWIG_FLOAT_P,SWIG_NUM2DBL,rb_float_new); - specialize_std_vector(std::string,SWIG_STRING_P,SWIG_RB2STR,SWIG_STR2RB); +#endif -} +%include <std/std_vector.i> diff --git a/Lib/ruby/std_vectora.i b/Lib/ruby/std_vectora.i new file mode 100644 index 000000000..5c8e0ee3f --- /dev/null +++ b/Lib/ruby/std_vectora.i @@ -0,0 +1,45 @@ +/* + Vectors + allocators +*/ + +%fragment("StdVectorATraits","header",fragment="StdSequenceTraits") +%{ + namespace swig { + template <class T, class A> + struct traits_asptr<std::vector<T,A> > { + typedef std::vector<T,A> vector_type; + typedef T value_type; + static int asptr(VALUE obj, vector_type **vec) { + return traits_asptr_stdseq<vector_type>::asptr(obj, vec); + } + }; + + template <class T, class A> + struct traits_from<std::vector<T,A> > { + typedef std::vector<T,A> vector_type; + static VALUE from(const vector_type& vec) { + return traits_from_stdseq<vector_type>::from(vec); + } + }; + } +%} + + +#define %swig_vector_methods(Type...) %swig_sequence_methods(Type) +#define %swig_vector_methods_val(Type...) %swig_sequence_methods_val(Type); + +#if defined(SWIG_RUBY_AUTORENAME) + + %rename("empty?") std::vector::empty; + %ignore std::vector::push_back; + %ignore std::vector::pop_back; + %alias std::vector::push "<<"; + +#else + %rename("empty?") std::vector::empty; + %ignore std::vector::push_back; + %ignore std::vector::pop_back; + %alias std::vector::push "<<"; +#endif + +%include <std/std_vectora.i> diff --git a/Lib/ruby/std_wstring.i b/Lib/ruby/std_wstring.i new file mode 100644 index 000000000..5ca77c0c8 --- /dev/null +++ b/Lib/ruby/std_wstring.i @@ -0,0 +1,3 @@ +%include <rubywstrings.swg> +%include <typemaps/std_wstring.swg> + |