summaryrefslogtreecommitdiff
path: root/share/swig/2.0.11/ruby/rubycontainer_extended.swg
blob: 7514ba2c8c3713bc93e5b27d599ec70e7d4a28ce (plain)
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 );