045. Derived type definition, initialization, and operator overloading#
topic: Derived types
The following program demonstrates how to define a derived type, initialize it, access its components, convert it to a string, and define operators for it.
The derived type here represents a specific month in time (i.e., year is also specified).
module date_mod
implicit none
interface operator(+)
module procedure add
end interface
interface operator(>)
module procedure greater
end interface
type :: ym
integer :: year, month
end type ym
contains
elemental function str(date) result(text)
type(ym), intent(in) :: date
character(len=7) :: text
write (text, "(i4.4,'-',i2.2)") date%year, date%month
end function str
elemental function add(date, n) result(new_date)
type(ym), intent(in) :: date
integer, intent(in) :: n
type(ym) :: new_date
new_date = int_to_ym(int(date) + n)
end function add
elemental function int(date) result(idate)
type(ym), intent(in) :: date
integer :: idate
idate = date%year*12 + date%month
end function int
elemental function int_to_ym(idate) result(date)
integer, intent(in) :: idate
type(ym) :: date
date%year = idate/12
date%month = idate - date%year*12
if (date%month == 0) then
date%month = 12
date%year = date%year - 1
end if
end function int_to_ym
elemental function greater(date_1, date_2) result(tf)
type(ym), intent(in) :: date_1, date_2
logical :: tf
tf = int(date_1) > int(date_2)
end function greater
end module date_mod
program xdate
use date_mod, only: ym, str, operator(+), operator(>)
implicit none
type(ym), allocatable :: dates(:)
integer :: ta(3)
! Set array of type `ym`
dates = [ym(2021, 11), ym(2021, 12), ym(2022, 1)]
print "(a10,':',*(1x,a))", "dates", str(dates)
print "(a10,':',*(i8))", "months", dates%month
! Note usage of `+` and `>` operators in the following:
print "(a10,':',*(1x,a))", "dates+1", str(dates + 1)
print *, "dates > dates(2)", dates > dates(2)
! Current date using `idate`
print *
call idate(ta)
print "(i4.4,'-',i2.2,'-',i2.2)", ta(3:1:-1)
end program xdate
dates: 2021-11 2021-12 2022-01
months: 11 12 1
dates+1: 2021-12 2022-01 2022-02
dates > dates(2) F F T
2023-04-25
Note
idate
is getting highlighted in the module code above
because it is shadowing the
intrinsic idate
subroutine,
which we demonstrate at the end.
Some further references:
https://fortran-lang.org/learn/quickstart/derived_types.html
https://fortranwiki.org/fortran/show/Object-oriented+programming
How to define a derived type, initialize it, access its components, convert it to a string, and define operators for it. pic.twitter.com/jcai3Usy25
— FortranTip (@fortrantip) December 24, 2021
- 1
Compiled using
GNU Fortran (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
with no flags