I have a question kind of like function overloading, kind of not exactly like so, and it not elemental function either. It is just that,
How to define a function to do job according to different size of input arrays?
For example, two functions AAA and BBB
function AAA(x)
real :: x(1), AAA
! something
end function AAA
function BBB(x)
real :: x(2), BBB
! something completely different from function AAA does.
end function BBB
Is it possible to define a function CCC which can automatically switch between AAA and BBB depending on the size of the input array x?
I mean I can do
function CCC(x)
real :: x(:), CCC
if (size(x)==1) CCC=AAA(x)
if (size(x)==2) CCC=BBB(x)
end function CCC
Or I can use select case instead of the if then else.
But is there better more high performance elegant way?
Overloading works on rank, type and kind of the arguments, so that won’t work in this case. If your functions AAA and BBB do more than a simple assignment, then worrying about the performance of whatever dispatching mechanism is futile: it will not be noticeable.
If you are looking for a different way to encode it, you might try this (sketch only):
function CCC(x)
real :: x(:)
type(function_pointer), dimension(:) :: pfunction ! Filled and defined elsewhere
CCC = pfunction(size(x))%function(x)
Missing bits and pieces: the definition of the derived type, filling the elements with pointers to AAA and BBB and possibly others, clipping the index into pfunction to valid values (min(size(x), size(pfunction)), say)
It is not likely to be faster than a simple chain of ifs or (I would prefer that) a select-case. But it is extendible without changing the implementation of CCC.
By using two derived types, the overloading will work:
module Vec
type :: Vec1_t
real :: x(1)
end type Vec1_t
type :: Vec2_t
real :: x(2)
end type Vec2_t
interface Vec
module interface AAA,BBB
end interface
contains
function AAA(Vec1)
type (vec1_t) :: Vec1
real :: AAA
! something
end function AAA
function BBB(Vec2)
type (vec1_t) :: Vec2
real :: BBB
! something completely different from function AAA does.
end function BBB
end module Vec
You can put the two derived types with the corresponding functions in two different modules.