Reputation: 1816
My problem is that I have two generic procedures implemented each one in 'mod1.f08' and 'mod2.f08'.
! mod1.f08
MODULE mod1
INTERFACE func1
procedure :: foo_int, foo_real
...
! mod2.f08
MODULE mod2
INTERFACE func2
procedure :: bar_int, bar_real
...
But I want to join both as submodules of only one module, in this way:
! mod1.f08
MODULE (mainmodule) mod1
INTERFACE func1
procedure :: foo_int, foo_real
...
! mod2.f08
MODULE (mainmodule) mod2
INTERFACE func2
procedure :: bar_int, bar_real
...
! mainmodule.f08
MODULE mainmodule
INTERFACE
procedure :: func1
procedure :: func2
END INTERFACE
...
Is it possible to do something like this?
Upvotes: 1
Views: 1049
Reputation: 1845
Is this what you intend to achieve?
module Main_mod
interface
module subroutine foo(dummyReal)
real, intent(in) :: dummyReal
end subroutine foo
end interface
interface
module subroutine bar(dummyInt)
integer, intent(in) :: dummyInt
end subroutine bar
end interface
interface genericFunc
module procedure :: foo, bar
end interface genericFunc
end module Main_mod
submodule (Main_mod) SubMain1_smod
contains
module subroutine foo(dummyReal)
real, intent(in) :: dummyReal
write(*,"(*(g0,:,' '))") "This is from inside foo @SubMain1_smod: dummyReal = ", dummyReal
end subroutine foo
end submodule SubMain1_smod
submodule (Main_mod) SubMain2_smod
contains
module subroutine bar(dummyInt)
integer, intent(in) :: dummyInt
write(*,"(*(g0,:,' '))") "This is from inside bar @SubMain2_smod: dummyInt = ", dummyInt
end subroutine bar
end submodule SubMain2_smod
program hello
use Main_mod, only: genericFunc
call genericFunc(1.)
call genericFunc(1)
end program Hello
Here is a test output:
> ifort main.f90 -o run.exe
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.4.245 Build 20190417
Copyright (C) 1985-2019 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.22.27905.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:run.exe
-subsystem:console
main.obj
> run.exe
This is from inside foo @SubMain1_smod: dummyReal = 1.000000
This is from inside bar @SubMain2_smod: dummyInt = 1
The generic procedures have to have their interfaces in the main module and the implementation goes inside the submodules. If the procedure implementations are too large, I'd separate the submodules from the main module and put them in separate files. This will also avoid the compilation cascade by make
software if any changes only occur to the submodules and not the interfaces in the main module. (I do it in general for any submodule size). If the procedure interfaces are also too large (with too many dummy input/output arguments), you could also avoid duplicate interface for each of the procedures (once in the main module and the other inside the submodules in the implementation of the procedures) via the procedure
keyword in the submodules like the following,
module Main_mod
interface
module subroutine foo(dummyReal)
real, intent(in) :: dummyReal
end subroutine foo
end interface
interface
module subroutine bar(dummyInt)
integer, intent(in) :: dummyInt
end subroutine bar
end interface
interface genericFunc
module procedure :: foo, bar
end interface genericFunc
end module Main_mod
submodule (Main_mod) SubMain1_smod
contains
module procedure foo
write(*,"(*(g0,:,' '))") "This is from inside foo @SubMain1_smod: dummyReal = ", dummyReal
end procedure foo
end submodule SubMain1_smod
submodule (Main_mod) SubMain2_smod
contains
module procedure bar
write(*,"(*(g0,:,' '))") "This is from inside bar @SubMain2_smod: dummyInt = ", dummyInt
end procedure bar
end submodule SubMain2_smod
program hello
use Main_mod, only: genericFunc
call genericFunc(1.)
call genericFunc(1)
end program Hello
This will generate an identical binary, but the implementation is shorter. However, I personally do not like it, as it often requires you to look at the parent module (which is typically in a separate file) for any dummy argument information. I hope that I understood your question correctly.
Upvotes: 1