1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/* -----------------------------------------------------------------------------
* rubycontainer_extended.swg
*
* This file contains additional functions that make containers
* behave closer to ruby primitive types.
* However, some of these functions place some restrictions on
* the underlying object inside of the container and the iterator
* (that it has to have an == comparison function, that it has to have
* an = assignment operator, etc).
* ----------------------------------------------------------------------------- */
/**
* Macro used to add extend functions that require operator== in object.
*
* @param Container STL container
* @param Type class inside container
*
*/
%define %swig_container_with_equal_operator( Container, Type )
VALUE __delete__( const Type& val ) {
VALUE r = Qnil;
Container<Type >::iterator e = $self->end();
Container<Type >::iterator i = std::remove( $self->begin(), e, val );
// remove dangling elements now
$self->erase( i, e );
if ( i != e )
r = swig::from< Type >( val );
else if ( rb_block_given_p() )
r = rb_yield(Qnil);
return r;
}
%enddef // end of %swig_container_with_equal_operator
/**
* Macro used to add extend functions that require the assignment
* operator (ie. = ) of contained class
*
* @param Container STL container
* @param Type class inside container
*
*/
%define %swig_container_with_assignment( Container, Type )
//
// map! -- the equivalent of std::transform
//
Container< Type >* map_bang() {
if ( !rb_block_given_p() )
rb_raise( rb_eArgError, "No block given" );
VALUE r = Qnil;
Container< Type >::iterator i = $self->begin();
Container< Type >::iterator e = $self->end();
try {
for ( ; i != e; ++i )
{
r = swig::from< Type >( *i );
r = rb_yield( r );
*i = swig::as< Type >( r );
}
}
catch ( const std::invalid_argument& )
{
rb_raise(rb_eTypeError,
"Yield block did not return a valid element for " "Container");
}
return $self;
}
%enddef // end of %swig_container_with_assignment
/**
* Macro used to add all extended functions to a container
*
* @param Container STL container
* @param Type class inside container
*
*/
%define %swig_container_extend( Container, Type )
%extend Container< Type > {
%swig_container_with_assignment( %arg(Container), Type );
%swig_container_with_equal_operator( %arg(Container), Type );
}
%enddef
/**
* Private macro used to add all extended functions to C/C++
* primitive types
*
* @param Container an STL container, like std::vector (with no class template)
*
*/
%define %__swig_container_extend_primtypes( Container )
%swig_container_extend( %arg( Container ), bool );
%swig_container_extend( %arg( Container ), char );
%swig_container_extend( %arg( Container ), short );
%swig_container_extend( %arg( Container ), int );
%swig_container_extend( %arg( Container ), unsigned short );
%swig_container_extend( %arg( Container ), unsigned int );
%swig_container_extend( %arg( Container ), float );
%swig_container_extend( %arg( Container ), double );
%swig_container_extend( %arg( Container ), std::complex );
%swig_container_extend( %arg( Container ), std::string );
%swig_container_extend( %arg( Container ), swig::GC_VALUE );
%enddef
%__swig_container_extend_primtypes( std::vector );
%__swig_container_extend_primtypes( std::deque );
%__swig_container_extend_primtypes( std::list );
|