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
This commit is contained in:
Gonzalo Garramuno 2007-04-30 06:36:55 +00:00
commit a0b74a907e
23 changed files with 1330 additions and 2739 deletions

108
Lib/ruby/rubyclasses.swg Normal file
View file

@ -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

View file

@ -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
// 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 __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 )
{
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

View file

@ -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 );
}

View file

@ -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;

View file

@ -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

View file

@ -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>

View file

@ -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)

View file

@ -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")

64
Lib/ruby/rubywstrings.swg Normal file
View file

@ -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;
}
}
}

1
Lib/ruby/std_alloc.i Normal file
View file

@ -0,0 +1 @@
%include <std/std_alloc.i>

View file

@ -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
%apply size_t { std::size_t };
// 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
%}
//
// 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);
}
VALUE SWIG_BOOL2RB(bool b) {
return b ? Qtrue : Qfalse;
}
double SWIG_NUM2DBL(VALUE x) {
return (FIXNUM_P(x) ? FIX2INT(x) : NUM2DBL(x));
}
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));
}
VALUE SWIG_STR2RB(const std::string& s) {
return rb_str_new(s.data(), s.size());
%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 { };
}
%}
/*
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; }
};
}
}
%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);
}
};
}
}
%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;
}
}
%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);

2
Lib/ruby/std_container.i Normal file
View file

@ -0,0 +1,2 @@
%include <rubycontainer.swg>
%include <std/std_container.i>

View file

@ -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>

3
Lib/ruby/std_ios.i Normal file
View file

@ -0,0 +1,3 @@
%rename(ios_base_in) std::ios_base::in;
%include <std/std_ios.i>

28
Lib/ruby/std_list.i Normal file
View file

@ -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>

File diff suppressed because it is too large Load diff

80
Lib/ruby/std_multimap.i Normal file
View file

@ -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>

44
Lib/ruby/std_multiset.i Normal file
View file

@ -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>

File diff suppressed because it is too large Load diff

60
Lib/ruby/std_set.i Normal file
View file

@ -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>

View file

@ -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));
}
}
}
};
#else
// specializations for built-ins
%mixin std::vector "Enumerable";
%rename("empty?") std::vector::empty;
%ignore std::vector::push_back;
%ignore std::vector::pop_back;
%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> &);
#endif
%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
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);
}
%include <std/std_vector.i>

45
Lib/ruby/std_vectora.i Normal file
View file

@ -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>

3
Lib/ruby/std_wstring.i Normal file
View file

@ -0,0 +1,3 @@
%include <rubywstrings.swg>
%include <typemaps/std_wstring.swg>