I want to write a module overloading a swap
routine, which takes an array and two indices and swaps the two elements around.
This routine should work for a wide range of arrays, so I wanted to overload it:
module mod_swap
use iso_fortran_env
implicit none
interface swap
module procedure swap_int64, swap_int32, swap_int16, &
swap_real64, swap_real32
end interface swap
public :: swap
private :: swap_int64, swap_int32, swap_int16, &
swap_real64, swap_real32
contains
#define VAR_TYPE real
#define TYPE_KIND real64
#include "swap.inc"
#undef TYPE_KIND
#define TYPE_KIND real32
#include "swap.inc"
#undef TYPE_KIND
#undef VAR_TYPE
#define VAR_TYPE integer
#define TYPE_KIND int64
#include "swap.inc"
#undef TYPE_KIND
#define TYPE_KIND int32
#include "swap.inc"
#undef TYPE_KIND
#define TYPE_KIND int16
#include "swap.inc"
#undef TYPE_KIND
#undef VAR_TYPE
end module mod_swap
with swap.inc
being:
#define PASTER(x,y) x ## _ ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define SWAP EVALUATOR(swap, TYPE_KIND)
subroutine SWAP(a, i, j)
implicit none
VAR_TYPE(kind=TYPE_KIND), intent(inout) :: a(:)
integer, intent(in) :: i, j
VAR_TYPE(kind=TYPE_KIND) t
t = a(i)
a(i) = a(j)
a(j) = t
end subroutine SWAP
When I run gfortran -o test.o -c -cpp test.F90
it fails, and when I run gfortran -E -cpp test.F90
I find out why: the SWAP
macro has been expanded to swap ## _ ## int16
, not swap_int16
as expected.
However, cpp
directly works:
$ cpp test.F90 > test.f90
$ gfortran -c -o test.o test.f90
After browsing this forum and Google in general, I have deduced that the issue is this:
The preprocessor is run in traditional mode.
And indeed, cpp --traditional
exhibits the same behaviour as gfortran -E -cpp
So here are my questions:
Is there a better way to implement this routine so that I don't have to repeat the same instructions just because the array type has changed. (Note that the variable
t
needs to have the same type asa
).Is there a way to make
gfortran
use the non-traditional preprocessor?If not, how would I do what I want to do with the traditional preprocessor?