1/*
2  Pairs
3*/
4%include <rubystdcommon.swg>
5
6//#define SWIG_STD_PAIR_ASVAL
7
8%fragment("StdPairTraits","header",fragment="StdTraits") {
9  namespace swig {
10
11    template <class T, class U >
12    struct traits_asval<std::pair<T,U> >  {
13      typedef std::pair<T,U> value_type;
14
15      static int get_pair(VALUE first, VALUE second,
16			  std::pair<T,U> *val)
17      {
18	if (val) {
19	  T *pfirst = &(val->first);
20	  int res1 = swig::asval((VALUE)first, pfirst);
21	  if (!SWIG_IsOK(res1)) return res1;
22	  U *psecond = &(val->second);
23	  int res2 = swig::asval((VALUE)second, psecond);
24	  if (!SWIG_IsOK(res2)) return res2;
25	  return res1 > res2 ? res1 : res2;
26	} else {
27	  T *pfirst = 0;
28	  int res1 = swig::asval((VALUE)first, pfirst);
29	  if (!SWIG_IsOK(res1)) return res1;
30	  U *psecond = 0;
31	  int res2 = swig::asval((VALUE)second, psecond);
32	  if (!SWIG_IsOK(res2)) return res2;
33	  return res1 > res2 ? res1 : res2;
34	}
35      }
36
37      static int asval(VALUE obj, std::pair<T,U> *val) {
38	int res = SWIG_ERROR;
39	if ( TYPE(obj) == T_ARRAY ) {
40	  if (RARRAY_LEN(obj) == 2) {
41	    VALUE first = rb_ary_entry(obj,0);
42	    VALUE second = rb_ary_entry(obj,1);
43	    res = get_pair(first, second, val);
44	  }
45	} else {
46	  value_type *p;
47	  res = SWIG_ConvertPtr(obj,(void**)&p,
48				swig::type_info<value_type>(),0);
49	  if (SWIG_IsOK(res) && val)  *val = *p;
50	}
51	return res;
52      }
53    };
54
55    template <class T, class U >
56    struct traits_asptr<std::pair<T,U> >  {
57      typedef std::pair<T,U> value_type;
58
59      static int get_pair(VALUE first, VALUE second,
60			  std::pair<T,U> **val)
61      {
62	if (val) {
63	  value_type *vp = %new_instance(std::pair<T,U>);
64	  T *pfirst = &(vp->first);
65	  int res1 = swig::asval((VALUE)first, pfirst);
66	  if (!SWIG_IsOK(res1)) return res1;
67	  U *psecond = &(vp->second);
68	  int res2 = swig::asval((VALUE)second, psecond);
69	  if (!SWIG_IsOK(res2)) return res2;
70	  *val = vp;
71	  return SWIG_AddNewMask(res1 > res2 ? res1 : res2);
72	} else {
73	  T *pfirst = 0;
74	  int res1 = swig::asval((VALUE)first, pfirst);
75	  if (!SWIG_IsOK(res1)) return res1;
76	  U *psecond = 0;
77	  int res2 = swig::asval((VALUE)second, psecond);
78	  if (!SWIG_IsOK(res2)) return res2;
79	  return res1 > res2 ? res1 : res2;
80	}
81      }
82
83      static int asptr(VALUE obj, std::pair<T,U> **val) {
84	int res = SWIG_ERROR;
85	if ( TYPE(obj) == T_ARRAY ) {
86	  if ( RARRAY_LEN(obj) == 2) {
87	    VALUE first = rb_ary_entry(obj,0);
88	    VALUE second = rb_ary_entry(obj,1);
89	    res = get_pair(first, second, val);
90	  }
91	} else {
92	  value_type *p;
93	  res = SWIG_ConvertPtr(obj,(void**)&p,
94				swig::type_info<value_type>(),0);
95	  if (SWIG_IsOK(res) && val)  *val = p;
96	}
97	return res;
98      }
99    };
100
101
102
103    template <class T, class U >
104    struct traits_from<std::pair<T,U> >   {
105      static VALUE _wrap_pair_second( VALUE self )
106      {
107	std::pair< typename swig::noconst_traits<T >::noconst_type,U>* p = NULL;
108	swig::asptr( self, &p );
109	return swig::from( p->second );
110      }
111
112      static VALUE _wrap_pair_second_eq( VALUE self, VALUE arg )
113      {
114	std::pair< typename swig::noconst_traits<T >::noconst_type,U>* p = NULL;
115	swig::asptr( self, &p );
116	return swig::from( p->second );
117      }
118
119      static VALUE from(const std::pair<T,U>& val) {
120	VALUE obj = rb_ary_new2(2);
121	RARRAY_PTR(obj)[0] = swig::from<
122	  typename swig::noconst_traits<T >::noconst_type>(val.first);
123	RARRAY_PTR(obj)[1] = swig::from(val.second);
124	RARRAY_LEN(obj) = 2;
125	rb_define_singleton_method(obj, "second",
126				   VALUEFUNC(_wrap_pair_second), 0 );
127	rb_define_singleton_method(obj, "second=",
128				   VALUEFUNC(_wrap_pair_second_eq), 1 );
129	rb_obj_freeze(obj); // treat as immutable tuple
130	return obj;
131      }
132    };
133
134  }
135}
136
137// Missing typemap
138%typemap(in) std::pair* (int res) {
139  res = swig::asptr( $input, &$1 );
140  if (!SWIG_IsOK(res))
141    %argument_fail(res, "$1_type", $symname, $argnum);
142}
143
144
145%define %swig_pair_methods(pair...)
146
147%extend {
148  VALUE inspect() const
149    {
150      VALUE tmp;
151      VALUE str = rb_str_new2( swig::type_name< pair >() );
152      str = rb_str_cat2( str, " (" );
153      tmp = swig::from( $self->first );
154      tmp = rb_obj_as_string( tmp );
155      str = rb_str_buf_append( str, tmp );
156      str = rb_str_cat2( str, "," );
157      tmp = swig::from( $self->second );
158      tmp = rb_obj_as_string( tmp );
159      str = rb_str_buf_append( str, tmp );
160      str = rb_str_cat2( str, ")" );
161      return str;
162    }
163
164  VALUE to_s() const
165    {
166      VALUE tmp;
167      VALUE str = rb_str_new2( "(" );
168      tmp = swig::from( $self->first );
169      tmp = rb_obj_as_string( tmp );
170      str = rb_str_buf_append( str, tmp );
171      str = rb_str_cat2( str, "," );
172      tmp = swig::from( $self->second );
173      tmp = rb_obj_as_string( tmp );
174      str = rb_str_buf_append( str, tmp );
175      str = rb_str_cat2( str, ")" );
176      return str;
177    }
178
179  VALUE __getitem__( int index )
180    {
181      if (( index % 2 ) == 0 )
182	return swig::from( $self->first );
183      else
184	return swig::from( $self->second );
185    }
186
187  VALUE __setitem__( int index, VALUE obj )
188    {
189      int res;
190      if (( index % 2 ) == 0 )
191	{
192	  res = swig::asval( obj, &($self->first) );
193	}
194      else
195	{
196	  res = swig::asval(obj, &($self->second) );
197	}
198      if (!SWIG_IsOK(res))
199	rb_raise( rb_eArgError, "invalid item for " #pair );
200      return obj;
201    }
202
203  } // extend
204
205%enddef
206
207%include <std/std_pair.i>
208