From e11e1c4cb8fc9be7f46160ba52cdad8acc433ea7 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 19 May 2017 08:15:01 +0100 Subject: [PATCH] C# std::complex wrappers marshalling by value Change the wrapping to marshall directly to the .net System.Numerics.Complex type instead of using an intermediate std::complex .net type. --- Lib/csharp/std_complex.i | 57 ++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/Lib/csharp/std_complex.i b/Lib/csharp/std_complex.i index ac30e1692..0f5b6b921 100644 --- a/Lib/csharp/std_complex.i +++ b/Lib/csharp/std_complex.i @@ -2,54 +2,67 @@ #include %} +%fragment("SwigSystemNumericsComplex", "header") { +// Identical to the layout of System.Numerics.Complex, but does assume that it is +// LayoutKind.Sequential on the managed side +struct SwigSystemNumericsComplex { + double real; + double imag; + SwigSystemNumericsComplex(double r = 0.0, double i = 0.0) : real(r), imag(i) {} +}; +} + namespace std { %naturalvar complex; -// An extremely simplified subset of std::complex<> which contains just the -// methods we need. template class complex { public: complex(T re = T(), T im = T()); - - T real() const; - T imag() const; }; -} // namespace std +} %define swig_complex_typemaps(T) -%typemap(cstype) std::complex, const std::complex& "System.Numerics.Complex" +%typemap(ctype, fragment="SwigSystemNumericsComplex") std::complex, const std::complex & "SwigSystemNumericsComplex" +%typemap(imtype) std::complex, const std::complex & "System.Numerics.Complex" +%typemap(cstype) std::complex, const std::complex & "System.Numerics.Complex" -// The casts in "pre" are needed in order to allow creating std::complex -// from System.Numerics.Complex, which always uses doubles. It relies on the -// fact that the name of the C++ and C# float/double types are the same. -%typemap(csin, - pre=" var cpp$csinput = new Complex_" #T "((" #T ")$csinput.Real, (" #T ")$csinput.Imaginary);" - ) std::complex, const std::complex& "Complex_" #T ".getCPtr(cpp$csinput)" +%typemap(in) std::complex($*1_ltype temp), const std::complex &($*1_ltype temp) +%{temp = std::complex< double >($input.real, $input.imag); + $1 = &temp;%} -%typemap(csout, excode=SWIGEXCODE) std::complex, const std::complex& { - Complex_##T cppret = new Complex_##T($imcall, $owner);$excode - return new System.Numerics.Complex(cppret.real(), cppret.imag()); +%typemap(out) std::complex +%{$result = SwigSystemNumericsComplex($1.real(), $1.imag());%} + +%typemap(out) const std::complex & +%{$result = SwigSystemNumericsComplex($1->real(), $1->imag());%} + +%typemap(cstype) std::complex, const std::complex & "System.Numerics.Complex" + +%typemap(csin) std::complex, const std::complex & "$csinput" + +%typemap(csout, excode=SWIGEXCODE) std::complex, const std::complex & { + System.Numerics.Complex ret = $imcall;$excode + return ret; } -%typemap(csvarin, excode=SWIGEXCODE2) const std::complex& %{ +%typemap(csvarin, excode=SWIGEXCODE2) const std::complex & %{ set { - var cppvalue = new Complex_##T((T)value.Real, (T)value.Imaginary); $imcall;$excode } %} -%typemap(csvarout, excode=SWIGEXCODE2) const std::complex& %{ +%typemap(csvarout, excode=SWIGEXCODE2) const std::complex & %{ get { - var cppret = new Complex_##T($imcall, $owner);$excode - return new System.Numerics.Complex(cppret.real(), cppret.imag()); + System.Numerics.Complex ret = $imcall;$excode + return ret; } %} -%template(Complex_##T) std::complex; +%template() std::complex; %enddef // By default, typemaps for both std::complex and std::complex