1 /* 2 Defines the As/From conversors for double/float complex, you need to 3 provide complex Type, the Name you want to use in the converters, 4 the complex Constructor method, and the Real and Imag complex 5 accessor methods. 6 7 See the std_complex.i and ccomplex.i for concrete examples. 8 */ 9 10 %fragment("rb_complex_new","header") 11 { 12 %#if !defined(T_COMPLEX) 13 /* Ruby versions prior to 1.9 did not have native complex numbers. They were an extension in the STD library. */ 14 SWIGINTERN VALUE rb_complex_new(VALUE x, VALUE y) { 15 static ID new_id = rb_intern("new"); 16 static VALUE cComplex = rb_const_get(rb_cObject, rb_intern("Complex")); 17 return rb_funcall(cComplex, new_id, 2, x, y); 18 } 19 %#endif 20 } 21 22 %fragment("SWIG_Complex_Numbers","header") 23 { 24 %#if !defined(T_COMPLEX) 25 SWIGINTERN int SWIG_Is_Complex( VALUE obj ) { 26 static ID real_id = rb_intern("real"); 27 static ID imag_id = rb_intern("imag"); 28 return ( (rb_respond_to( obj, real_id ) ) && 29 (rb_respond_to( obj, imag_id ) ) ); 30 } 31 %#else 32 SWIGINTERN int SWIG_Is_Complex( VALUE obj ) { 33 return TYPE(obj) == T_COMPLEX; 34 } 35 %#endif 36 37 SWIGINTERN VALUE SWIG_Complex_Real(VALUE obj) { 38 static ID real_id = rb_intern("real"); 39 return rb_funcall(obj, real_id, 0); 40 } 41 42 SWIGINTERN VALUE SWIG_Complex_Imaginary(VALUE obj) { 43 static ID imag_id = rb_intern("imag"); 44 return rb_funcall(obj, imag_id, 0); 45 } 46 } 47 48 %init { 49 %#if !defined(T_COMPLEX) 50 rb_require("complex"); 51 %#endif 52 } 53 54 /* the common from converter */ 55 %define %swig_fromcplx_conv(Type, Real, Imag) 56 %fragment(SWIG_From_frag(Type),"header",fragment="rb_complex_new") 57 { 58 SWIGINTERNINLINE VALUE 59 SWIG_From(Type)(%ifcplusplus(const Type&, Type) c) 60 { 61 VALUE re = rb_float_new(Real(c)); 62 VALUE im = rb_float_new(Imag(c)); 63 return rb_complex_new(re, im); 64 } 65 } 66 %enddef 67 68 /* the double case */ 69 %define %swig_cplxdbl_conv(Type, Constructor, Real, Imag) 70 %fragment(SWIG_AsVal_frag(Type),"header", 71 fragment=SWIG_AsVal_frag(double), 72 fragment="SWIG_Complex_Numbers") 73 { 74 SWIGINTERN int 75 SWIG_AsVal(Type) (VALUE o, Type* val) 76 { 77 if ( SWIG_Is_Complex( o ) ) { 78 if (val) { 79 VALUE real = SWIG_Complex_Real(o); 80 VALUE imag = SWIG_Complex_Imaginary(o); 81 double re = 0; 82 SWIG_AsVal_double( real, &re ); 83 double im = 0; 84 SWIG_AsVal_double( imag, &im ); 85 *val = Constructor(re, im); 86 } 87 return SWIG_OK; 88 } else { 89 double d; 90 int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d)); 91 if (SWIG_IsOK(res)) { 92 if (val) *val = Constructor(d, 0.0); 93 return res; 94 } 95 } 96 return SWIG_TypeError; 97 } 98 } 99 %swig_fromcplx_conv(Type, Real, Imag); 100 %enddef 101 102 /* the float case */ 103 %define %swig_cplxflt_conv(Type, Constructor, Real, Imag) 104 %fragment(SWIG_AsVal_frag(Type),"header", 105 fragment=SWIG_AsVal_frag(float), 106 fragment=SWIG_AsVal_frag(double), 107 fragment="SWIG_Complex_Numbers") { 108 SWIGINTERN int 109 SWIG_AsVal(Type)(VALUE o, Type *val) 110 { 111 if ( SWIG_Is_Complex( o ) ) { 112 VALUE real = SWIG_Complex_Real(o); 113 VALUE imag = SWIG_Complex_Imaginary(o); 114 double re = 0; 115 SWIG_AsVal_double( real, &re ); 116 double im = 0; 117 SWIG_AsVal_double( imag, &im ); 118 if ((-FLT_MAX <= re && re <= FLT_MAX) && 119 (-FLT_MAX <= im && im <= FLT_MAX)) { 120 if (val) *val = Constructor(%numeric_cast(re, float), 121 %numeric_cast(im, float)); 122 return SWIG_OK; 123 } else { 124 return SWIG_OverflowError; 125 } 126 } else { 127 float re; 128 int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re)); 129 if (SWIG_IsOK(res)) { 130 if (val) *val = Constructor(re, 0.0); 131 return res; 132 } 133 } 134 return SWIG_TypeError; 135 } 136 } 137 138 %swig_fromcplx_conv(Type, Real, Imag); 139 %enddef 140 141 #define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \ 142 %swig_cplxflt_conv(Type, Constructor, Real, Imag) 143 144 145 #define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \ 146 %swig_cplxdbl_conv(Type, Constructor, Real, Imag) 147 148 149