I was trying to figure out a way to have a library that exports procedures with multiple real kinds (single, double, quad) that:
- doesn’t duplicate code
- is standard fortran (preprocessing also OK)
- doesn’t break IDEs, linters, syntax highlighters
fypp is out for the last two reasons.
#ifndef MOD_INCLUDE module quadpack_generic use iso_fortran_env, only: wp => real64 #endif ! put all routines here, Using wp real kind #ifndef MOD_INCLUDE end module quadpack_generic #endif
So, notice that if
MOD_INCLUDE is not defined, this is just a normal module that uses double precision reals. So, it works fine in an IDE and doesn’t break anything. But if
MOD_INCLUDE is defined, then it can be used as an include file to change the value of
To instantiate a single precision version of this module, we create a new file (quadpack_single.F90):
module quadpack_single use iso_fortran_env, only: wp => real32 #define MOD_INCLUDE=1 #include "quadpack_generic.F90" end module quadpack_single
Can do same for quad precision. So, you can use these modules as is, and we can also make a single module that exports all of them (quadpack.F90):
module quadpack use quadpack_single, only: qag => dqag, ... use quadpack_double use quadpack_quad, only: qqag => dqag, ... end module quadpack
Notice that I’m renaming them to match the old interface (so, for example the module exports
dqag (double() and
qqag (quad). We could also make an interface block.
What do you think of this approach? It seems OK, if a little clunky.