|
module IntStack_wrappers_mod |
|
|
|
use, intrinsic :: iso_c_binding, only : c_int, c_ptr, c_null_ptr, c_associated |
|
|
|
implicit none |
|
|
|
private |
|
|
|
interface |
|
|
|
function GetObject( s_size ) result( optr )bind(C, name="GetObject") |
|
import :: c_int, c_ptr |
|
|
|
implicit none |
|
|
|
! Argument list |
|
integer(c_int), intent(in), value :: s_size |
|
! Function result |
|
type(c_ptr) :: optr |
|
end function GetObject |
|
|
|
subroutine IntStackPush( optr, i ) bind(C, name="IntStackPush") |
|
import :: c_int, c_ptr |
|
|
|
implicit none |
|
|
|
! Argument list |
|
type(c_ptr), intent(in), value :: optr |
|
integer(c_int), intent(in), value :: i |
|
end subroutine IntStackPush |
|
|
|
subroutine IntStackDisplay( optr ) bind(C, name="IntStackDisplay") |
|
import :: c_ptr |
|
|
|
implicit none |
|
|
|
! Argument list |
|
type(c_ptr), intent(in), value :: optr |
|
end subroutine IntStackDisplay |
|
|
|
subroutine DeleteObject( optr ) bind(C, name="DeleteObject") |
|
import :: c_ptr |
|
|
|
implicit none |
|
|
|
! Argument list |
|
type(c_ptr), intent(in), value :: optr |
|
end subroutine DeleteObject |
|
|
|
end interface |
|
|
|
public :: DeleteObject |
|
public :: IntStackPush |
|
public :: IntStackDisplay |
|
public :: GetObject |
|
|
|
end module IntStack_wrappers_mod |
|
|
|
|
|
module IntStack_mod |
|
|
|
use, intrinsic :: iso_c_binding, only : c_int, c_ptr, c_null_ptr, c_associated |
|
! The C functions |
|
use IntStack_wrappers_mod, only : IntStackPush, IntStackDisplay, GetObject, DeleteObject |
|
implicit none |
|
|
|
public IntStack |
|
|
|
private |
|
type IntStack |
|
type(c_ptr) :: optr |
|
|
|
contains |
|
final :: IntStack_destructor |
|
procedure, public :: display => stack_display |
|
procedure, public :: push => stack_push |
|
end type IntStack |
|
|
|
interface IntStack |
|
module procedure IntStack_constructor |
|
end interface IntStack |
|
|
|
contains |
|
|
|
function IntStack_constructor(prob_size) result(this) |
|
type(IntStack) :: this |
|
integer(c_int), intent(in) :: prob_size |
|
this%optr = GetObject( s_size=prob_size ) |
|
end function IntStack_constructor |
|
|
|
subroutine IntStack_destructor(this) |
|
type(IntStack) :: this |
|
print*, "Destroying IntStack" |
|
call DeleteObject(this%optr) |
|
this%optr = c_null_ptr |
|
end subroutine |
|
|
|
subroutine stack_display(this) |
|
class(IntStack), intent(inout) :: this |
|
call IntStackDisplay(this%optr) |
|
end subroutine stack_display |
|
|
|
subroutine stack_push(this, t) |
|
class(IntStack), intent(inout) :: this |
|
integer(c_int), intent(in) :: t |
|
call IntStackPush(this%optr, i=t) |
|
end subroutine stack_push |
|
end module IntStack_mod |
|
|
|
|
|
subroutine short_lifetime |
|
use IntStack_mod, only : IntStack |
|
|
|
type(IntStack) :: stack |
|
|
|
stack = IntStack(20) |
|
end subroutine |
|
|
|
|
|
|
|
program p |
|
use IntStack_mod, only : IntStack |
|
|
|
type(IntStack) :: stack |
|
|
|
stack = IntStack(10) |
|
call stack % display() |
|
|
|
call stack % push(2) |
|
call stack % push(15) |
|
call stack % display() |
|
|
|
! For a short-lifetime object, we should see the destructor get called. |
|
call short_lifetime() |
|
|
|
end program p |
|
|