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 conversors, 4 the complex Constructor method, and the Real and Imag complex 5 accesor methods. 6 7 See the std_complex.i and ccomplex.i for concrete examples. 8*/ 9 10/* 11 Ruby does not have native complex numbers. They are an extension in the 12 STD library. 13*/ 14%{ 15 static VALUE swig_rb_cComplex = Qnil; 16 static ID swig_real_id = 0; 17 static ID swig_imag_id = 0; 18 19 int Ruby_Is_Complex( VALUE obj ) 20 { 21 return ( (rb_respond_to( obj, swig_real_id ) == Qtrue) && 22 (rb_respond_to( obj, swig_imag_id ) == Qtrue) ); 23 } 24%} 25 26%init { 27 rb_require("complex"); 28 swig_rb_cComplex = rb_const_get( rb_cObject, rb_intern("Complex") ); 29 if( swig_rb_cComplex == Qnil ) 30 rb_warn("Ruby's complex.so not found"); 31 swig_real_id = rb_intern("real"); 32 swig_imag_id = rb_intern("imag"); 33} 34 35/* the common from conversor */ 36%define %swig_fromcplx_conv(Type, Real, Imag) 37%fragment(SWIG_From_frag(Type),"header") 38{ 39SWIGINTERNINLINE VALUE 40SWIG_From(Type)(%ifcplusplus(const Type&, Type) c) 41{ 42 VALUE args[] = { 43 rb_float_new(Real(c)), 44 rb_float_new(Imag(c)) 45 }; 46 return rb_class_new_instance(2, args, swig_rb_cComplex); 47} 48} 49%enddef 50 51/* the double case */ 52%define %swig_cplxdbl_conv(Type, Constructor, Real, Imag) 53%fragment(SWIG_AsVal_frag(Type),"header", 54 fragment=SWIG_AsVal_frag(double)) 55{ 56SWIGINTERN int 57SWIG_AsVal(Type) (VALUE o, Type* val) 58{ 59 if ( Ruby_Is_Complex( o ) ) { 60 if (val) { 61 VALUE real = rb_funcall(o, swig_real_id, 0 ); 62 VALUE imag = rb_funcall(o, swig_imag_id, 0 ); 63 double re = 0; 64 SWIG_AsVal_double( real, &re ); 65 double im = 0; 66 SWIG_AsVal_double( imag, &im ); 67 *val = Constructor(re, im); 68 } 69 return SWIG_OK; 70 } else { 71 double d; 72 int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d)); 73 if (SWIG_IsOK(res)) { 74 if (val) *val = Constructor(d, 0.0); 75 return res; 76 } 77 } 78 return SWIG_TypeError; 79} 80} 81%swig_fromcplx_conv(Type, Real, Imag); 82%enddef 83 84/* the float case */ 85%define %swig_cplxflt_conv(Type, Constructor, Real, Imag) 86%fragment(SWIG_AsVal_frag(Type),"header", 87 fragment=SWIG_AsVal_frag(float), 88 fragment=SWIG_AsVal_frag(double)) { 89SWIGINTERN int 90SWIG_AsVal(Type)(VALUE o, Type *val) 91{ 92 if ( Ruby_Is_Complex( o ) ) { 93 VALUE real = rb_funcall(o, swig_real_id, 0 ); 94 VALUE imag = rb_funcall(o, swig_imag_id, 0 ); 95 double re = 0; 96 SWIG_AsVal_double( real, &re ); 97 double im = 0; 98 SWIG_AsVal_double( imag, &im ); 99 if ((-FLT_MAX <= re && re <= FLT_MAX) && 100 (-FLT_MAX <= im && im <= FLT_MAX)) { 101 if (val) *val = Constructor(%numeric_cast(re, float), 102 %numeric_cast(im, float)); 103 return SWIG_OK; 104 } else { 105 return SWIG_OverflowError; 106 } 107 } else { 108 float re; 109 int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re)); 110 if (SWIG_IsOK(res)) { 111 if (val) *val = Constructor(re, 0.0); 112 return res; 113 } 114 } 115 return SWIG_TypeError; 116} 117} 118 119%swig_fromcplx_conv(Type, Real, Imag); 120%enddef 121 122#define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \ 123%swig_cplxflt_conv(Type, Constructor, Real, Imag) 124 125 126#define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \ 127%swig_cplxdbl_conv(Type, Constructor, Real, Imag) 128 129 130