0

Is it possible to link different subroutines with procedures in derived types with the same structure?

I'm using derived types and my idea is to link different subroutines with the same structure so it can be passed as arguments.

I thought of subroutine overloading. However, it needs arguments with different types, which won't help.

The following code doesn't compile but it has the main idea.

module mod1
  
  implicit none
  
  type foo_data
    integer :: a, b
  contains
    procedure :: oper   !I know that this isn't allowed because some coding is missing
  end type foo_data

  type(foo_data) :: foo1
  type(foo_data) :: foo2

contains

  subroutine add(a,b,c)

    integer, intent(in)  :: a, b
    integer, intent(out) :: c

    c=a+b

  end subroutine add
  subroutine sub(a,b,c)

    integer, intent(in)  :: a, b
    integer, intent(out) :: c

    c=a-b

  end subroutine sub

end module mod1

program main

 use mod1

 implicit none

 Integer :: c, d

 !link add with foo1 using oper or another idea
 !link sub with foo2 using oper or another idea

 foo1%a=1
 foo1%b=2

 foo2%a=2
 foo2%b=1

 call compute(foo1,c)
 write(*,*) c

 call compute(foo2,d)
 write(*,*) d

contains

  subroutine compute(foo,r)
  
    type(foo_data) :: foo

    integer, intent(out) :: r

    call foo%oper(foo%a,foo%b,r)

  end subroutine compute

end program main
Nicholas
  • 623
  • 5
  • 4
  • 2
    I'm not quite sure what you want to do, but it looks like you possibly just want to have `oper` as a procedure pointer rather than a type-bound procedure? – francescalus Nov 04 '20 at 15:11
  • I'm not sure. Can you give an example using oper as procedure pointer? – Nicholas Nov 04 '20 at 15:16
  • 1
    For component `procedure(add), pointer :: oper`, then `foo1%oper=>add; foo2%oper=>sub`, etc. – francescalus Nov 04 '20 at 15:24
  • 3
    If I understand this correctly another way to go would be to have an abstract base type, and then two different extensions with the type bound procedure oper set to the appropriate value. Then allocate the variable to the appropriate type. – Ian Bush Nov 04 '20 at 16:00
  • 1
    I agree with @IanBush. This is the cleanest way to implement it. Note that your `compute` procedure needs to use a _polymorphic_ dummy argument, i.e. `class(foo_parent) :: foo`. Give us a heads up if you need a more specific example implementation. – jack Nov 04 '20 at 20:04
  • Well, it worked with @francescalus suggestion and some ideas from [link](https://stackoverflow.com/questions/36585868/fortran-procedure-pointer-to-subroutines-in-derived-type). The command was `procedure(sub_interface), pointer, nopass :: oper`, I created an interface `sub_interface`, and typed `foo1%oper=>add` and `foo2%oper=>sub` in the main program. I tried extending but I created another structure, e.g., `foo_data_child1` for `add` and `foo_data_child2` for `sub`. I wasn't able to work with the `compute` routine that way. Could you give a MWE to the cleanest way? – Nicholas Nov 06 '20 at 13:08
  • @jack, maybe something like exascale's edited answer:[link](https://stackoverflow.com/questions/27083060/fortran-passing-arbitrary-structures-to-a-module-subroutine?rq=1)? – Nicholas Nov 07 '20 at 18:16

0 Answers0