Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type-bound function overloading in Fortran 2003

Tags:

fortran

I have a Fortran derived type T that contains data arrays of (many) different ranks and types. These arrays are hidden inside a complicated data structure and I would like to have a getter function of that does the following:

a => T%get(data_id)

where "a" is an array pointer of given type, and data_id is an integer that is used to find the data inside the data structure. I do that by overloading many "get_thistype()" functions under a generic name.

TYPE T
   PROCEDURE :: get_real
   PROCEDURE :: get_integer
   GENERIC   :: get => get_real,get_integer
END TYPE

This works if the get_thistype() routines are subroutines, but not if they are written as functions. This means my code looks like:

CALL T%get(a,data_id)

which I find much less readable. Is there a way to overload functions that have the same argument list but different return types? or do I have to use subroutines for that?

like image 686
calys Avatar asked Mar 12 '12 17:03

calys


2 Answers

When a (pointer) assignment statement gets executed in fortran, the right hand side always gets evaluated fully before the assignment takes place. This happens independently of the left hand side, so there is absolutely no way that the LHS can influence the outcome of the evaluation of the RHS. It's just the way the language is designed.

like image 103
eriktous Avatar answered Oct 13 '22 10:10

eriktous


I just came across this post, so for the benefit of anyone see this in the future:

If I understand the question correctly, you can accomplish this by overloading the assignment operator. Example:

file X.f90:

MODULE XModule

TYPE :: X
   INTEGER, DIMENSION(:), POINTER :: IntArray
   REAL,    DIMENSION(:), POINTER :: RealArray
END TYPE

INTERFACE ASSIGNMENT (=)
   MODULE PROCEDURE PointToInt
   MODULE PROCEDURE PointToReal
END INTERFACE

CONTAINS

SUBROUTINE PointToInt(Ip, V)
   INTEGER, POINTER, DIMENSION(:), INTENT(OUT) :: Ip
   TYPE(X), INTENT(IN) :: V
   Ip => V%IntArray
END SUBROUTINE PointToInt

SUBROUTINE PointToReal(Rp, V)
   REAL, POINTER, DIMENSION(:), INTENT(OUT) :: Rp
   TYPE(X), INTENT(IN) :: V
   Rp => V%RealArray
END SUBROUTINE PointToReal

END MODULE

test driver file Driver.f90:

PROGRAM Driver
USE XModule
TYPE(X) :: Var
INTEGER, DIMENSION(:), POINTER :: I
REAL, DIMENSION(:), POINTER :: R

ALLOCATE(Var%IntArray(2))
ALLOCATE(Var%RealArray(3))

Var%IntArray = [1, 2]
Var%RealArray = [1., 2., 3.]

I = Var
PRINT*, I

R = Var
PRINT*, R

END PROGRAM

Output:

           1           2
   1.000000       2.000000       3.000000    

Hope this helps.

like image 34
blburel Avatar answered Oct 13 '22 12:10

blburel