Merge branch 'vadz-csharp-complex'
* vadz-csharp-complex:
Add header to std_complex.i
Fix linkage problems in C# std::complex wrappers
C# std::complex wrappers marshalling by value
C# std::complex wrappers SwigValueWrapper fix
Use %naturalvar for C# std::complex wrappers
Allow avoiding generation of unwanted std::complex<T> typemaps
Also apply csvar{in,out} typemaps to std::complex references
Add std_complex.i for C# too
Extend C# complex support to member variables of this type
Add support for std::complex<> to C#
Use new unified Mono mcs compiler if available under Unix
This commit is contained in:
commit
2ec156fb7f
8 changed files with 150 additions and 3 deletions
|
|
@ -42,6 +42,9 @@ Version 4.0.0 (in progress)
|
||||||
[Ruby] Fix #939 - Wrapping std::vector<bool> fix due to incorrect null checks
|
[Ruby] Fix #939 - Wrapping std::vector<bool> fix due to incorrect null checks
|
||||||
on VALUE obj.
|
on VALUE obj.
|
||||||
|
|
||||||
|
2017-03-17: vadz
|
||||||
|
[C#] Add support for std::complex<T>
|
||||||
|
|
||||||
2017-03-17: wsfulton
|
2017-03-17: wsfulton
|
||||||
[Go] Fix handling of typedef'd function pointers and typedef'd member function pointers
|
[Go] Fix handling of typedef'd function pointers and typedef'd member function pointers
|
||||||
such as:
|
such as:
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,11 @@
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct ComplexPair
|
||||||
|
{
|
||||||
|
std::complex<double> z1, z2;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ top_srcdir = ../@top_srcdir@
|
||||||
top_builddir = ../@top_builddir@
|
top_builddir = ../@top_builddir@
|
||||||
|
|
||||||
CPP_TEST_CASES = \
|
CPP_TEST_CASES = \
|
||||||
|
complextest \
|
||||||
csharp_attributes \
|
csharp_attributes \
|
||||||
csharp_swig2_compatibility \
|
csharp_swig2_compatibility \
|
||||||
csharp_exceptions \
|
csharp_exceptions \
|
||||||
|
|
@ -40,6 +41,7 @@ CSHARPFLAGSSPECIAL =
|
||||||
|
|
||||||
# Custom tests - tests with additional commandline options
|
# Custom tests - tests with additional commandline options
|
||||||
intermediary_classname.cpptest: SWIGOPT += -dllimport intermediary_classname
|
intermediary_classname.cpptest: SWIGOPT += -dllimport intermediary_classname
|
||||||
|
complextest.cpptest: CSHARPFLAGSSPECIAL = -r:System.Numerics.dll
|
||||||
csharp_lib_arrays.cpptest: CSHARPFLAGSSPECIAL = -unsafe
|
csharp_lib_arrays.cpptest: CSHARPFLAGSSPECIAL = -unsafe
|
||||||
csharp_swig2_compatibility.cpptest: SWIGOPT += -DSWIG2_CSHARP
|
csharp_swig2_compatibility.cpptest: SWIGOPT += -DSWIG2_CSHARP
|
||||||
|
|
||||||
|
|
|
||||||
34
Examples/test-suite/csharp/complextest_runme.cs
Normal file
34
Examples/test-suite/csharp/complextest_runme.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
// This is the complex runtime testcase. It checks that the C++ std::complex type works.
|
||||||
|
// It requires .NET 4.0 as the previous versions didn't have System.Numerics.Complex type.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
using complextestNamespace;
|
||||||
|
|
||||||
|
public class complextest_runme {
|
||||||
|
|
||||||
|
public static void Main() {
|
||||||
|
var a = new Complex(-1, 2);
|
||||||
|
if ( complextest.Conj(a) != Complex.Conjugate(a) )
|
||||||
|
throw new Exception("std::complex<double> test failed");
|
||||||
|
|
||||||
|
if ( complextest.Conjf(a) != Complex.Conjugate(a) )
|
||||||
|
throw new Exception("std::complex<float> test failed");
|
||||||
|
|
||||||
|
var vec = new VectorStdCplx();
|
||||||
|
vec.Add(new Complex(1, 2));
|
||||||
|
vec.Add(new Complex(2, 3));
|
||||||
|
vec.Add(new Complex(4, 3));
|
||||||
|
vec.Add(new Complex(1, 0));
|
||||||
|
|
||||||
|
if ( complextest.Copy_h(vec).Count != 2 )
|
||||||
|
throw new Exception("vector<complex> test failed");
|
||||||
|
|
||||||
|
var p = new ComplexPair();
|
||||||
|
p.z1 = new Complex(0, 1);
|
||||||
|
p.z2 = new Complex(0, -1);
|
||||||
|
if ( Complex.Conjugate(p.z2) != p.z1 )
|
||||||
|
throw new Exception("vector<complex> test failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,3 +15,9 @@ try:
|
||||||
complextest.Copy_h(v)
|
complextest.Copy_h(v)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
p = complextest.ComplexPair()
|
||||||
|
p.z1 = complex(0, 1)
|
||||||
|
p.z2 = complex(0, -1)
|
||||||
|
if complextest.Conj(p.z2) != p.z1:
|
||||||
|
raise RuntimeError, "bad complex mapping"
|
||||||
|
|
|
||||||
5
Lib/csharp/complex.i
Normal file
5
Lib/csharp/complex.i
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
%include <std_complex.i>
|
||||||
|
#else
|
||||||
|
#error C# module only supports complex in C++ mode.
|
||||||
|
#endif
|
||||||
92
Lib/csharp/std_complex.i
Normal file
92
Lib/csharp/std_complex.i
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* std_complex.i
|
||||||
|
*
|
||||||
|
* Typemaps for handling std::complex<float> and std::complex<double> as a .NET
|
||||||
|
* System.Numerics.Complex type. Requires .NET 4 minimum.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <complex>
|
||||||
|
%}
|
||||||
|
|
||||||
|
%fragment("SwigSystemNumericsComplex", "header") {
|
||||||
|
extern "C" {
|
||||||
|
// 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIGINTERN SwigSystemNumericsComplex SwigCreateSystemNumericsComplex(double real, double imag) {
|
||||||
|
SwigSystemNumericsComplex cpx;
|
||||||
|
cpx.real = real;
|
||||||
|
cpx.imag = imag;
|
||||||
|
return cpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
%naturalvar complex;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class complex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
complex(T re = T(), T im = T());
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
%define SWIG_COMPLEX_TYPEMAPS(T)
|
||||||
|
%typemap(ctype, fragment="SwigSystemNumericsComplex") std::complex<T>, const std::complex<T> & "SwigSystemNumericsComplex"
|
||||||
|
%typemap(imtype) std::complex<T>, const std::complex<T> & "System.Numerics.Complex"
|
||||||
|
%typemap(cstype) std::complex<T>, const std::complex<T> & "System.Numerics.Complex"
|
||||||
|
|
||||||
|
%typemap(in) std::complex<T>($*1_ltype temp), const std::complex<T> &($*1_ltype temp)
|
||||||
|
%{temp = std::complex< double >($input.real, $input.imag);
|
||||||
|
$1 = &temp;%}
|
||||||
|
|
||||||
|
%typemap(out, null="SwigCreateSystemNumericsComplex(0.0, 0.0)") std::complex<T>
|
||||||
|
%{$result = SwigCreateSystemNumericsComplex($1.real(), $1.imag());%}
|
||||||
|
|
||||||
|
%typemap(out, null="SwigCreateSystemNumericsComplex(0.0, 0.0)") const std::complex<T> &
|
||||||
|
%{$result = SwigCreateSystemNumericsComplex($1->real(), $1->imag());%}
|
||||||
|
|
||||||
|
%typemap(cstype) std::complex<T>, const std::complex<T> & "System.Numerics.Complex"
|
||||||
|
|
||||||
|
%typemap(csin) std::complex<T>, const std::complex<T> & "$csinput"
|
||||||
|
|
||||||
|
%typemap(csout, excode=SWIGEXCODE) std::complex<T>, const std::complex<T> & {
|
||||||
|
System.Numerics.Complex ret = $imcall;$excode
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
%typemap(csvarin, excode=SWIGEXCODE2) const std::complex<T> & %{
|
||||||
|
set {
|
||||||
|
$imcall;$excode
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
%typemap(csvarout, excode=SWIGEXCODE2) const std::complex<T> & %{
|
||||||
|
get {
|
||||||
|
System.Numerics.Complex ret = $imcall;$excode
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
%template() std::complex<T>;
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
// By default, typemaps for both std::complex<double> and std::complex<float>
|
||||||
|
// are defined, but one of them can be disabled by predefining the
|
||||||
|
// corresponding symbol before including this file.
|
||||||
|
#ifndef SWIG_NO_STD_COMPLEX_DOUBLE
|
||||||
|
SWIG_COMPLEX_TYPEMAPS(double)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SWIG_NO_STD_COMPLEX_FLOAT
|
||||||
|
SWIG_COMPLEX_TYPEMAPS(float)
|
||||||
|
#endif
|
||||||
|
|
@ -2267,14 +2267,14 @@ else
|
||||||
if test -z "$CSHARPCOMPILERBIN" ; then
|
if test -z "$CSHARPCOMPILERBIN" ; then
|
||||||
case $host in
|
case $host in
|
||||||
*-*-cygwin* | *-*-mingw*)
|
*-*-cygwin* | *-*-mingw*)
|
||||||
# prefer Mono gmcs (.NET 2.0) over mcs (.NET 1.1) - note mcs-1.2.3 has major pinvoke bug
|
# prefer unified Mono mcs compiler (not to be confused with the ancient .NET 1 mcs) over older/alternative names.
|
||||||
AC_CHECK_PROGS(CSHARPCOMPILER, csc mono-csc gmcs mcs cscc)
|
AC_CHECK_PROGS(CSHARPCOMPILER, csc mcs mono-csc gmcs cscc)
|
||||||
if test -n "$CSHARPCOMPILER" && test "$CSHARPCOMPILER" = "csc" ; then
|
if test -n "$CSHARPCOMPILER" && test "$CSHARPCOMPILER" = "csc" ; then
|
||||||
AC_MSG_CHECKING(whether csc is the Microsoft CSharp compiler)
|
AC_MSG_CHECKING(whether csc is the Microsoft CSharp compiler)
|
||||||
csc 2>/dev/null | grep "C#" > /dev/null || CSHARPCOMPILER=""
|
csc 2>/dev/null | grep "C#" > /dev/null || CSHARPCOMPILER=""
|
||||||
if test -z "$CSHARPCOMPILER" ; then
|
if test -z "$CSHARPCOMPILER" ; then
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
AC_CHECK_PROGS(CSHARPCOMPILER, mono-csc gmcs mcs cscc)
|
AC_CHECK_PROGS(CSHARPCOMPILER, mcs mono-csc gmcs cscc)
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue