The ``superclass'' set of m4 macros is used to automatically create a superclass module that will dynamically dispatch superclass calls to the correct subclass routine or function. This achieves run-time polymorphism, which is commonly considered to be too much effort in Fortran 90, in an easily implemented fashion.
To use the ``superclass'' set of m4 macros certain naming and coding conventions must be followed. Assuming that the superclass name is ``Matrix'', that three subclasses exist named ``One'', ``Two'', and ``Three'', and that the routine to be dynamically dispatched is named ``Solve'', the following names must be used:
superclass derived type: | Matrix_type |
subclass derived types: | One_type, Two_type, Three_type |
subclass module names: | One_Class, Two_Class, Three_Class |
superclass module name: | Matrix_Class |
superclass routine name: | Solve_Matrix |
superclass interface name: | Solve |
subclass routine names: | Solve_One, Solve_Two, Solve_Three |
subclass interface name: | Solve |
In addition, the superclass derived type must be:
type Matrix_type character (len=80) :: Subclass type(One_type) :: One type(Two_type) :: Two type(Three_type) :: Three end type Matrix_typeTo use the superclass macros in the CÆSAR Code Package,
Take the following code segment as an example:
define([SUPERCLASS],[Matrix]) define([SUBCLASSES],[One Two Three]) module SUPERCLASS[]_Class SUPERCLASS_USE_ASSOCIATIONS SUPERCLASS_TYPE contains SUPERCLASS_ROUTINE([Initialize], [type(real)], [a], [The a variable], [type(integer), intent(in)], [b], [The b variable]) SUPERCLASS_FUNCTION([Verify_State], [type(logical)], [type(real)], [b], [The b variable]) SUPERCLASS_ROUTINE([Finalize], [type(real)], [c], [The c variable], [type(real)], [d], [The d variable]) end module SUPERCLASS[]_Class
This code is expanded by Gnu m4 into the following valid F90 code:
module Matrix_Class use One_Class use Two_Class use Three_Class type Matrix_type character (len=80) :: Subclass type(One_type) :: One type(Two_type) :: Two type(Three_type) :: Three end type Matrix_type contains subroutine Initialize_Matrix (Matrix, a, b) type(Matrix_type) Matrix real (kind=KIND(1.0d0)) :: a ! The a variable integer (kind=KIND(1)), intent(in) :: b ! The b variable !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ select case (Matrix%Subclass) case ("One") call Initialize (Matrix%One, a, b) case ("Two") call Initialize (Matrix%Two, a, b) case ("Three") call Initialize (Matrix%Three, a, b) case default write (6,*) 'Error: no ', Matrix%Subclass, ' in Matrix_Class.' end select end subroutine Initialize_Matrix function Verify_State_Matrix (Matrix, b) type(Matrix_type) Matrix logical (kind=KIND(.true.)) :: Verify_State, Verify_State_Matrix real (kind=KIND(1.0d0)) :: b ! The b variable !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ select case (Matrix%Subclass) case ("One") Verify_State_Matrix = Verify_State (Matrix%One, b) case ("Two") Verify_State_Matrix = Verify_State (Matrix%Two, b) case ("Three") Verify_State_Matrix = Verify_State (Matrix%Three, b) case default write (6,*) 'Error: no ', Matrix%Subclass, ' in Matrix_Class.' end select end function Verify_State_Matrix subroutine Finalize_Matrix (Matrix, c, d) type(Matrix_type) Matrix real (kind=KIND(1.0d0)) :: c ! The c variable real (kind=KIND(1.0d0)) :: d ! The d variable !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ select case (Matrix%Subclass) case ("One") call Finalize (Matrix%One, c, d) case ("Two") call Finalize (Matrix%Two, c, d) case ("Three") call Finalize (Matrix%Three, c, d) case default write (6,*) 'Error: no ', Matrix%Subclass, ' in Matrix_Class.' end select end subroutine Finalize_Matrix end module Matrix_Class
Note that this set of m4 macros depends on the m4 commands in the settings.m4 file and on the SUPERCLASS and SUBCLASSES macro definitions.
m4 macros defined in the include/superclass.m4 file:
SUPERCLASS_ARGUMENTS | Used internally by the SUPERCLASS_ROUTINE and SUPERCLASS_FUNCTION macros. | ||
SUPERCLASS_DECLARATIONS | Used internally by the SUPERCLASS_ROUTINE and SUPERCLASS_FUNCTION macros. | ||
SUPERCLASS_FUNCTION | Expands into a complete function for the superclass. This function dynamically dispatches calls to the superclass to the correct subclass function. | ||
SUPERCLASS_ROUTINE | Expands into a complete subroutine for the superclass. This subroutine dynamically dispatches calls to the superclass to the correct subclass routine. | ||
SUPERCLASS_TYPE | Outputs a standard superclass type definition. | ||
SUPERCLASS_USE_ASSOCIATIONS | Outputs the correct use associations for the superclass. |
The Superclass m4 Macros code listing contains additional documentation.
Michael L. Hall