Skip to content

Commit a483b35

Browse files
committed
add poly type example
1 parent 167be77 commit a483b35

File tree

4 files changed

+161
-0
lines changed

4 files changed

+161
-0
lines changed

src/cxx/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ add_executable(cpp_opaque opaque_main.cxx)
1010
target_link_libraries(cpp_opaque PRIVATE opaque_fortran)
1111
add_test(NAME C++_Fortran_opaque COMMAND cpp_opaque)
1212

13+
add_executable(cpp_poly_type poly_type_main.cpp)
14+
target_link_libraries(cpp_poly_type PRIVATE poly_type_fortran)
15+
add_test(NAME C++_Fortran_poly_type COMMAND cpp_poly_type)
16+
1317
add_executable(cpp_poly_fcn poly_fcn_main.cpp)
1418
target_link_libraries(cpp_poly_fcn PRIVATE poly_fcn_fortran)
1519
add_test(NAME C++_Fortran_poly_fcn COMMAND cpp_poly_fcn)

src/cxx/poly_type_main.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <iostream>
2+
3+
extern "C" void init_type(int*, void**);
4+
extern "C" void add_one_C(int*, void**, int*, int*);
5+
6+
7+
int main(){
8+
9+
void* x3;
10+
void* x4;
11+
int xtype=3;
12+
int A, C;
13+
14+
xtype = 3;
15+
init_type(&xtype, &x3);
16+
17+
add_one_C(&xtype, &x3, &A, &C);
18+
if(A != 4) {
19+
std::cerr << "Error: " << A << " != 4" << std::endl;
20+
return EXIT_FAILURE;
21+
}
22+
std::cout << "C:3 = " << C << std::endl;
23+
add_one_C(&xtype, &x3, &A, &C);
24+
std::cout << "C:3 = " << C << std::endl;
25+
add_one_C(&xtype, &x3, &A, &C);
26+
std::cout << "C:3 = " << C << std::endl;
27+
28+
xtype = 4;
29+
init_type(&xtype, &x4);
30+
31+
add_one_C(&xtype, &x4, &A, &C);
32+
if(A != 5) {
33+
std::cerr << "Error: " << A << " != 5" << std::endl;
34+
return EXIT_FAILURE;
35+
}
36+
std::cout << "C:4 = " << C << std::endl;
37+
add_one_C(&xtype, &x4, &A, &C);
38+
std::cout << "C:4 = " << C << std::endl;
39+
add_one_C(&xtype, &x4, &A, &C);
40+
std::cout << "C:4 = " << C << std::endl;
41+
42+
std::cout << "OK: poly_type" << std::endl;
43+
44+
return EXIT_SUCCESS;
45+
}

src/fortran/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ add_library(error_fortran OBJECT error_lib.f90)
88

99
add_library(pointer_fortran OBJECT pointer_lib.f90)
1010

11+
add_library(poly_type_fortran OBJECT poly_type_lib.f90)
12+
1113
add_library(poly_fcn_fortran OBJECT poly_data_lib.f90 poly_fcn_lib.f90)
1214

1315
add_library(struct_fortran OBJECT struct_lib.f90)

src/fortran/poly_type_lib.f90

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
module poly_type
2+
3+
use, intrinsic :: iso_c_binding, only : C_PTR, c_loc, c_int, c_f_pointer
4+
5+
implicit none (type, external)
6+
7+
type, abstract :: base
8+
integer(c_int) :: A, C
9+
end type base
10+
11+
type, extends(base) :: vthree
12+
integer(c_int) :: B = 3
13+
end type vthree
14+
15+
type, extends(base) :: vfour
16+
integer(c_int) :: B = 4
17+
end type vfour
18+
19+
contains
20+
21+
22+
subroutine init_type(xtype, xC) bind(C)
23+
integer(c_int) :: xtype
24+
type(C_PTR), intent(inout) :: xC
25+
26+
class(base), pointer :: x
27+
type(vthree), pointer :: three
28+
type(vfour), pointer :: four
29+
30+
select case (xtype)
31+
case (3)
32+
allocate(three)
33+
xC = c_loc(three)
34+
x=>three
35+
case (4)
36+
allocate(four)
37+
xC = c_loc(four)
38+
x=>four
39+
case default
40+
error stop "unknown init type"
41+
end select
42+
43+
end subroutine init_type
44+
45+
46+
function assoc_type(xtype, xC) result(x)
47+
integer(c_int) :: xtype
48+
type(C_PTR), intent(inout) :: xC
49+
50+
class(base), pointer :: x
51+
type(vthree), pointer :: three
52+
type(vfour), pointer :: four
53+
54+
select case (xtype)
55+
case (3)
56+
call c_f_pointer(xC, three)
57+
x=>three
58+
case (4)
59+
call c_f_pointer(xC, four)
60+
x=>four
61+
case default
62+
error stop "unknown assoc type"
63+
end select
64+
65+
end function assoc_type
66+
67+
68+
subroutine add_one_C(xtype, xC, val, accum) bind(C, name='add_one_C')
69+
integer(c_int), intent(in) :: xtype
70+
type(C_PTR), intent(inout) :: xC
71+
integer(c_int), intent(out) :: val, accum
72+
73+
class(base), pointer :: x
74+
75+
76+
x => assoc_type(xtype, xC)
77+
78+
select type (x)
79+
type is (vthree)
80+
call add_one3(x)
81+
type is (vfour)
82+
call add_one4(x)
83+
class default
84+
error stop "unknown add type"
85+
end select
86+
87+
val = x%A
88+
accum = x%C
89+
90+
end subroutine add_one_C
91+
92+
93+
subroutine add_one3(x)
94+
class(vthree), intent(inout) :: x
95+
96+
x%A = x%B + 1
97+
98+
x%C = x%C + x%A
99+
end subroutine add_one3
100+
101+
subroutine add_one4(x)
102+
class(vfour), intent(inout) :: x
103+
104+
x%A = x%B + 1
105+
106+
x%C = x%C + x%A
107+
end subroutine add_one4
108+
109+
110+
end module poly_type

0 commit comments

Comments
 (0)