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