How to make some generic programming in fortran 90/95 working with intrinsic types

感情迁移 提交于 2019-11-29 11:18:29

You can use the C preprocessor (CPP) in all major Fortran compilers. Usually there is a flag for invoking it (-cpp in gfortran) or it is invoked automatically if the file suffix contains capital F (.F90, .F). The preprocessor allows more powerful inclusion of sources with the usage of macros.

module imod

  use data_type, only: ivalue 

#define T type(ivalue)
#include "template.f90"
#undef T

end module imod


module intmod

#define T integer
#include "template.f90"
#undef T

end module intmod

and template.f90

contains

subroutine printme(a)

  implicit none

  T :: a

  print *,a

end subroutine printme

This is not strict f90 / f95, but it uses a preprocessor, included in the compilers, which produces another (strict f95) source file and it automatically compiles it instead of the original source that contains the macros.

The compilation is then straightforward

gfortran -cpp main.f90

--Edit--

For non-believers, if you want to see some real code using this, check https://github.com/LadaF/fortran-list (disclaimer: my own code). You can use the parametric linked list there as:

list of len(20) character strings:

module str_list

#define TYPEPARAM character(20)

#include "list-inc-def.f90"
contains
#include "list-inc-proc.f90"
#undef TYPEPARAM
end module

list of integers

module int_list

#define TYPEPARAM integer

#include "list-inc-def.f90"
contains
#include "list-inc-proc.f90"
#undef TYPEPARAM
end module

list of some derived type

module new_type_list
  use, new_type_module, only: new_type

#define TYPEPARAM type(newtype)

#include "list-inc-def.f90"
contains
#include "list-inc-proc.f90"
#undef TYPEPARAM
end module

You can use implicit typing. Make sure you wash your hands though - as this opens the possibility for the usual errors associated with implicit typing.

Consider a replacement for your module imod.

module imod
  use data_type    ! oops - I forgot this.
  implicit type(itype) (q)
contains
  include 'template.f90'
end module imod

(I've moved the contains statement into the including module - as it then allows you to have more than one templated include file.)

and then a procedure in included file that looks like:

 ! Assume anything starting with q is the type to be templated.
 subroutine printme(q_arg)
   print *, q_arg
 end subroutine printme

If you wanted to template printme for an intrinsic type, then you just change the implicit statement in the parent module appropriately.


It's debatable, but there's also the view that you can use the module renaming facility to introduce new names for intrinsic types. If so, and if you have a F2008 compiler (so we aren't talking strict F95) then your current approach should still be able to work - using an intermediate module to allow renaming of the intrinsic integer type to have a name T.

But this confuses most (all?) compilers I've used in some way. Given that, plus the debatable legality, plus it requiring F2008, it's not a real solution.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!