Last active
September 17, 2019 19:26
-
-
Save drikosev/6fa28d8c9ba771d4e59b97f8f3bb4f89 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module types | |
implicit none | |
type, public, abstract :: base_t | |
real*4 :: c(4) | |
contains | |
procedure :: className => baseClassName | |
procedure :: print => basePrint | |
procedure :: init => baseInit | |
end type base_t | |
interface assignment(=) | |
procedure :: assign_base_t !allocatable lhs | |
end interface assignment(=) | |
public :: assign_base_t | |
! Without this median based_t type, a sub-type | |
! can't access methods of the base_t type. Such | |
! a median type isn't required by PGI Fortran but | |
! other Fortran compilers agree that is required. | |
type, extends(base_t) :: based_t | |
end type based_t | |
private ::based_t | |
type, extends(based_t) :: p_t | |
contains | |
procedure :: className => pClassName | |
procedure :: init => pInit | |
end type p_t | |
interface p_t | |
module procedure :: new_p ! constructor of type(p_t) | |
end interface p_t | |
private :: p_t | |
PUBLIC :: new_p ! This constructor is public. | |
type, extends(based_t) :: v_t | |
contains | |
procedure :: className => vClassName | |
procedure :: init => vInit | |
end type v_t | |
interface v_t | |
module procedure :: new_v ! constructor of type(v_t) | |
end interface v_t | |
private v_t | |
PUBLIC :: new_v ! This constructor is public. | |
contains | |
type(p_t) function new_p() | |
new_p%c = [ 0.0 , 0.0, 0.0, 0.0 ] | |
call new_p%init() !Further initializations? | |
end function new_p | |
type(v_t) function new_v() | |
new_v%c = [ 0.0 , 0.0, 0.0, 1.0 ] | |
call new_v%init() !Further initializations? | |
end function new_v | |
subroutine baseInit(this) | |
class(base_t) , intent(inout) :: this | |
!print *, "(baseInit) ", this%className() | |
end subroutine baseInit | |
subroutine basePrint(this) | |
class(base_t) , intent(inout) :: this | |
print *, "(", this%className(), ") % c = ", this%c | |
end subroutine basePrint | |
! each class implements the className. | |
function baseClassName(this) | |
class(base_t) , intent(in) :: this | |
character(kind=1,len=:),allocatable :: baseClassName | |
baseClassName="base_t" | |
end function baseClassName | |
function vClassName(this) | |
class(v_t) , intent(in) :: this | |
character(kind=1,len=:),allocatable :: vClassName | |
vClassName="v_t" | |
end function vClassName | |
subroutine vInit(this) | |
class(v_t) , intent(inout) :: this | |
!call this%based_t%init() | |
!print *, "(vInit) ", this%className() | |
end subroutine vInit | |
function pClassName(this) | |
class(p_t) , intent(in) :: this | |
character(kind=1,len=:),allocatable :: pClassName | |
pClassName="p_t" | |
end function pClassName | |
subroutine pInit(this) | |
class(p_t) , intent(inout) :: this | |
!call this%based_t%init() | |
!print *, "(pInit) ", this%className() | |
end subroutine pInit | |
subroutine assign_base_t(to, from) | |
class(base_t), allocatable, intent(inout) :: to | |
class(base_t), intent(in) :: from | |
allocate(to,source=from) !copying is a weak point here | |
end subroutine | |
end module types |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
program init | |
use types | |
use, intrinsic :: iso_fortran_env, only : compiler_version | |
class(base_t), allocatable :: p,v | |
p=new_p() | |
v=new_v() | |
print *, "Compiler version: ", compiler_version() | |
call p % print() | |
call v % print() | |
end program init | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ gfortran types-module.f90 types.driver.f90 -o ginit4 && ./ginit4 | |
Compiler version: GCC version 4.8.5 | |
(p_t) % c = 0.00000000 0.00000000 0.00000000 0.00000000 | |
(v_t) % c = 0.00000000 0.00000000 0.00000000 1.00000000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sep 16, 2019 | |
Ev. Drikos | |
The program in this gist demonstrates how one can achieve | |
default initialization on Fortran derived types, since the | |
language does not inherently support such a functionality. | |
In Specific, Fortran allows the instantiation of an object | |
that hasn't been initialized by any constructor. This code | |
attempts to force the instantiation of allocatable objects | |
that require references from our derived type constructors. | |
Profiling this program with Instruments (Version 9.3) does | |
not give me the impression that there are any memory leaks | |
other than those expected, ie from the WRITE REAL function, | |
usually reported when one loads a dynamic library (shlib). | |
Whatsover, these leaks are unrelated to object allocations. | |
Revisions | |
1. Uploaded to github. | |
2. PGI Fortran prefers a "private" specification statement, | |
instead of an access specification attribute in a derived | |
type definition statement, which should be equivalent. | |
3. Adjust the comment of the 2nd revision. | |
4. Move the module to a separate file and create this file | |
along with a printout with the program results. | |
Also, add an intermediate type that allows subclasses to | |
call specific methods of the abstract base type. | |
5. Delete the original file "init.f90" | |
6. Update the file "Types.Readme.txt" on github. | |
Files | |
1. The file "types-module.f90" contains the module "types". | |
2. The file "types.driver.f90" contains a main program that | |
uses the module "types". | |
3. The file "types.output.txt" contains the printout created | |
when I run this program on macOS 10.13 and the program had | |
been compiled by GNU Fortran version "4.8.5~36" for macOS, | |
built as documented at: https://github.com/drikosev/pc | |
4. The file "Types.Readme.txt" is the one you're reading now. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment