I'm in the following situation: I have an object that must be initialized (without hurry) with some input parameter x. Then it has a method do_work that has to run (fast). Now, depending on x the do_work can be either function f1 or f2. Of course I can choose among them when do_work is called, but, since I know the choice in advance, I was thinking to use a procedure pointer.
I produced the following MWE
module delegate_m
implicit none
private
type delegate
private
integer :: x
procedure(delegate_function), private, pointer :: fptr
contains
private
procedure:: f2
procedure :: f1
procedure, public :: do_work
end type delegate
interface delegate
module procedure :: init_delegate
end interface delegate
abstract interface
integer function delegate_function(self,y)
import :: delegate
class(delegate) :: self
integer :: y
end function delegate_function
end interface
public :: delegate
contains
type(delegate) function init_delegate(x)
implicit none
integer, intent(in) :: x
init_delegate%x = x
if (modulo(x, 2) == 0) then
init_delegate%fptr => f1
else
init_delegate%fptr => f2
end if
end function init_delegate
integer function f1(self,y)
implicit none
class(delegate) :: self
integer :: y
f1 = y * self%x
end function f1
integer function f2(self,y)
implicit none
class(delegate) :: self
integer :: y
f2 = (y ** 2) * self%x
end function f2
integer function do_work(self, x, y)
implicit none
class(delegate) :: self
integer:: x, y
do_work = self%fptr(x) - y
end function do_work
end module delegate_m
program test
use delegate_m
implicit none
type(delegate) :: d1, d2
d1 = delegate(45)
d2 = delegate(44)
write (*,*) d1%do_work(2, 3)
write (*,*) d2%do_work(2, 3)
end program test
It seems to work, but I'm rather new to (modern) Fortran and I would like to know whether I did something wrong/dangerous since I'm working with pointers. I'm also curios if that abstract interface introduces some virtual function table lookup (I do not see why it should, but I'm a newbie, as I said)