Home | History | Annotate | Download | only in ruby
      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 	rb_ary_push(obj, swig::from<typename swig::noconst_traits<T >::noconst_type>(val.first));
    122 	rb_ary_push(obj, swig::from(val.second));
    123 	rb_define_singleton_method(obj, "second",
    124 				   VALUEFUNC(_wrap_pair_second), 0 );
    125 	rb_define_singleton_method(obj, "second=",
    126 				   VALUEFUNC(_wrap_pair_second_eq), 1 );
    127 	rb_obj_freeze(obj); // treat as immutable tuple
    128 	return obj;
    129       }
    130     };
    131 
    132   }
    133 }
    134 
    135 // Missing typemap
    136 %typemap(in) std::pair* (int res) {
    137   res = swig::asptr( $input, &$1 );
    138   if (!SWIG_IsOK(res))
    139     %argument_fail(res, "$1_type", $symname, $argnum);
    140 }
    141 
    142 
    143 %define %swig_pair_methods(pair...)
    144 
    145 %extend {
    146   VALUE inspect() const
    147     {
    148       VALUE tmp;
    149       const char *type_name = swig::type_name< pair >();
    150       VALUE str = rb_str_new2( type_name );
    151       str = rb_str_cat2( str, " (" );
    152       tmp = swig::from( $self->first );
    153       tmp = rb_obj_as_string( tmp );
    154       str = rb_str_buf_append( str, tmp );
    155       str = rb_str_cat2( str, "," );
    156       tmp = swig::from( $self->second );
    157       tmp = rb_obj_as_string( tmp );
    158       str = rb_str_buf_append( str, tmp );
    159       str = rb_str_cat2( str, ")" );
    160       return str;
    161     }
    162 
    163   VALUE to_s() const
    164     {
    165       VALUE tmp;
    166       VALUE str = rb_str_new2( "(" );
    167       tmp = swig::from( $self->first );
    168       tmp = rb_obj_as_string( tmp );
    169       str = rb_str_buf_append( str, tmp );
    170       str = rb_str_cat2( str, "," );
    171       tmp = swig::from( $self->second );
    172       tmp = rb_obj_as_string( tmp );
    173       str = rb_str_buf_append( str, tmp );
    174       str = rb_str_cat2( str, ")" );
    175       return str;
    176     }
    177 
    178   VALUE __getitem__( int index )
    179     {
    180       if (( index % 2 ) == 0 )
    181 	return swig::from( $self->first );
    182       else
    183 	return swig::from( $self->second );
    184     }
    185 
    186   VALUE __setitem__( int index, VALUE obj )
    187     {
    188       int res;
    189       if (( index % 2 ) == 0 )
    190 	{
    191 	  res = swig::asval( obj, &($self->first) );
    192 	}
    193       else
    194 	{
    195 	  res = swig::asval(obj, &($self->second) );
    196 	}
    197       if (!SWIG_IsOK(res))
    198 	rb_raise( rb_eArgError, "invalid item for " #pair );
    199       return obj;
    200     }
    201 
    202   } // extend
    203 
    204 %enddef
    205 
    206 %include <std/std_pair.i>
    207