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