Skip to content

Commit 83632bc

Browse files
committed
Sloppy but working std::complex implementation
Only a few other languages implement it, and none of them tests the C implementation.
1 parent a6aeeef commit 83632bc

File tree

6 files changed

+127
-6
lines changed

6 files changed

+127
-6
lines changed

Examples/test-suite/fortran/Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ CPP_TEST_CASES = \
2828
fortran_overloads \
2929
fortran_subroutine \
3030
li_std_set \
31+
complextest \
3132

3233
C_TEST_CASES = \
3334
fortran_array_typemap \
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
! File : complextest_runme.F90
2+
3+
#include "fassert.h"
4+
5+
program complextest_runme
6+
use complextest
7+
use ISO_C_BINDING
8+
implicit none
9+
complex(C_FLOAT_COMPLEX) :: cflt
10+
complex(C_DOUBLE_COMPLEX) :: cdbl
11+
type(VectorStdCplx) :: vec
12+
13+
cflt = (1, 3) ! 1 + 3i
14+
cflt = Conjf(cflt)
15+
ASSERT(cflt == (1, -3))
16+
cdbl = (4.0000000001d0, 1d0)
17+
ASSERT(Conj(cdbl) == (4.0000000001d0, -1d0))
18+
19+
cdbl = (4, 5)
20+
cdbl = Conj2(cdbl)
21+
ASSERT(cdbl == (4d0, -5d0))
22+
23+
vec = VectorStdCplx(10)
24+
call vec%set(5, cmplx(4, -5, kind=C_DOUBLE_COMPLEX))
25+
ASSERT(vec%get(5) == cdbl)
26+
end program
27+
28+

Lib/fortran/ccomplex.i

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* -------------------------------------------------------------------------
2+
* ccomplex.i
3+
* ------------------------------------------------------------------------- */
4+
5+
%{
6+
#include <complex.h>
7+
8+
#define SWIG_ccomplex_construct(REAL, IMAG) ((REAL) + I * (IMAG))
9+
%}
10+
11+
%define %fortran_typemap_ccomplex(CPLX_TYPE, CTYPE, FKIND)
12+
%fortran_typemap_complex(CPLX_TYPE, SWIG_ccomplex_construct, CTYPE, FKIND)
13+
%enddef
14+
15+
#error "C complex numbers are not currently supported"

Lib/fortran/complex.i

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
%define %fortran_typemap_complex(CPPTYPE, CONSTRUCT_CPPTYPE, CTYPE, FKIND)
2+
3+
%fragment("SWIG_complex_"{CTYPE}, "header", noblock=1) {
4+
extern "C" {
5+
typedef struct {
6+
CTYPE real;
7+
CTYPE imag;
8+
} SwigComplex_ ## CTYPE;
9+
}
10+
11+
SWIGINTERN SwigComplex_ ## CTYPE SWIG_create_complex_ ## CTYPE(CTYPE real, CTYPE imag) {
12+
SwigComplex_ ## CTYPE result;
13+
result.real = real;
14+
result.imag = imag;
15+
return result;
16+
}
17+
}
18+
19+
struct SwigComplex_ ## CTYPE;
20+
21+
%naturalvar CPPTYPE;
22+
23+
%fortran_intrinsic(SwigComplex_ ## CTYPE, complex, FKIND)
24+
%fortran_apply_typemaps(SwigComplex_ ## CTYPE, CPPTYPE)
25+
26+
%apply SwigComplex_ ## CTYPE& { CPPTYPE*, CPPTYPE[], CPPTYPE[ANY] };
27+
28+
%apply SwigComplex_ ## CTYPE { CPPTYPE };
29+
30+
%typemap(ctype, in={SwigComplex_ ## CTYPE*}, null={SWIG_create_complex_ ## CTYPE(0, 0)}, fragment="SWIG_complex_"{CTYPE}, noblock=1) CPPTYPE {
31+
SwigComplex_ ## CTYPE
32+
}
33+
%typemap(in, noblock=1) CPPTYPE {
34+
$1 = CONSTRUCT_CPPTYPE($input->real, $input->imag);
35+
}
36+
%typemap(out, fragment="SWIG_complex_"{CTYPE}, noblock=1) CPPTYPE
37+
{$result = SWIG_create_complex_ ## CTYPE($1.real(), $1.imag());}
38+
39+
%typemap(out, noblock=1) CPPTYPE&
40+
{$result = (SwigComplex_ ## CTYPE*)($1);}
41+
42+
%apply CPPTYPE { const CPPTYPE& };
43+
%typemap(in, noblock=1) const CPPTYPE& ($*1_ltype temp) {
44+
temp = CONSTRUCT_CPPTYPE($input->real, $input->imag);
45+
$1 = &temp;
46+
}
47+
%typemap(out, noblock=1) const CPPTYPE&
48+
{$result = SWIG_create_complex_ ## CTYPE($1->real(), $1->imag());}
49+
50+
%enddef // %fortran_typemap_complex
51+
52+
#ifdef __cplusplus
53+
%include <std_complex.i>
54+
#else
55+
%{
56+
#ifdef __STDC_NO_COMPLEX__
57+
#error "This generated file requires C complex number support"
58+
#endif
59+
%}
60+
%include <ccomplex.i>
61+
#endif
62+

Lib/fortran/fundamental.swg

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,7 @@ subroutine %fortrantm(fout, bool)(imout, fout)
4444
use, intrinsic :: ISO_C_BINDING
4545
integer(kind=C_INT), intent(in) :: imout
4646
logical, intent(out) :: fout
47-
! TODO: fout = (imout /= 0) ???
48-
if (imout /= 0) then
49-
fout = .true.
50-
else
51-
fout = .false.
52-
end if
47+
fout = (imout /= 0)
5348
end subroutine
5449
}
5550

Lib/fortran/std_complex.i

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* -------------------------------------------------------------------------
2+
* std_complex.i
3+
* ------------------------------------------------------------------------- */
4+
5+
%{
6+
#include <complex>
7+
%}
8+
9+
namespace std {
10+
%naturalvar complex;
11+
template<typename T> class complex;
12+
}
13+
14+
%define %fortran_typemap_std_complex(CTYPE, FKIND)
15+
%template() std::complex<CTYPE>;
16+
%fortran_typemap_complex(std::complex<CTYPE>, std::complex<CTYPE>, CTYPE, FKIND)
17+
%enddef
18+
19+
%fortran_typemap_std_complex(float, C_FLOAT_COMPLEX)
20+
%fortran_typemap_std_complex(double, C_DOUBLE_COMPLEX)

0 commit comments

Comments
 (0)