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