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