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