M_overload(3fm) - [M_overload] overloads of standard operators and intrinsic procedures (LICENSE:PD)
Synopsis
Description
Overloads
Examples
Author
License
overloads on LOGICAL values
logical==logical logical/=logicaloverloads on INTRINSICS to take strings, logicals, and metamorphic numeric intrinsic values
int(string) int(logical) int(class(*)) real(string) real(logical) real(class(*)) dble(string) dble(logical) dble(class(*))When sign(3f) is given a single value, call sign(1,value)
sign(value)Allow allocatable variables for strings
get_command(command,length,status) get_command_argument(number,value,length,status)
Operator and function overloads have a wide range of applications from allowing existing Fortran routines to be used with almost no source-code changes to produce versions using arbitrary precision or cumulative error bounds on floating-point calculations to adding intuitive syntax for standard Fortran operations.
The intrinsics allow an allocated allocatable variable but do not change its allocation so to force reallocation of an allocatable variable the new logical argument "realloc" is added to force reallocation.
==,/= Allow the syntax "L1 == L2" and "L1 /= L2" where L1 and L2 are type LOGICAL as an alternative to the standard expressions "L1 .EQV. L2" and "L1 .NEQV. L2". It should be pointed out that
L1 == L2 !! should be L1 .eqv. L2and
L1 /= L2 !! should be L1 .neqv. L2should NOT work by default; but often do (probably because the compiler silently converts LOGICAL to INTEGER when a LOGICAL appears where a numeric value is required). If your compiler supports this non-standard (but intuitive-looking) syntax you can use this module to allow the syntax in a portable manner with a standard method.
int(), real(), dble() allow strings to be converted to numeric values using the standard intrinsic names sign(value) call sign(1,value) get_command(command,length,status) allow "command" to be allocatable get_command_argument(number,value,length,status) allow "value" to be allocatable
Sample usage:
program demo_M_overloadcontainsuse, intrinsic :: iso_fortran_env, only : & & integer_kinds, int8, int16, int32, int64 use, intrinsic :: iso_fortran_env, only : & & real32, real64, real128 use M_compare_float_numbers, only : operator(.EqualTo.)
! allow strings to be converted to integers use M_overload, only : int ! allow strings to be converted to floating point use M_overload, only : real,dble ! use == like .eqv. use M_overload, only : operator(==) ! use /= like .neqv. use M_overload, only : operator(/=) ! take a single argument use M_overload, only : sign use M_overload, only : get_command implicit none character(len=:),allocatable :: cmd
if(int(1234) .eq.1234) & & write(*,*)int("STRING") works if(real(1234.56789) .EqualTo.1234.56789) & & write(*,*)real("STRING") works if(dble(1234.5678901234567).EqualTo.1234.5678901234567d0) & & write(*,*)dble("STRING") works
if (.true. == .true. ) & & write(*,*)== works like .eqv. for LOGICAL values if (.true. /= .false. ) & & write(*,*)/= works like .neqv. for LOGICAL values
write(*,*)int([111,222])+333 write(*,*)real([111.111,222.222])+333.333 write(*,*)dble([111.111d0,222.222d0])+333.333d0 write(*,*)dble([character(len=10) :: & & 111,222.222,333.333d0])+444.444d0
write(*,*) merge(sign works,sign fails,& & sign(10_int8).eq.1 & & .and. sign(-10_int8).eq.-1 ) write(*,*) merge(sign works,sign fails,& & sign(10_int16).eq.1 & & .and. sign(-10_int16).eq.-1 ) write(*,*) merge(sign works,sign fails,& & sign(10_int32).eq.1 & & .and. sign(-10_int32).eq.-1 ) write(*,*) merge(sign works,sign fails,& & sign(10_int64).eq.1 & & .and. sign(-10_int64).eq.-1 ) write(*,*) merge(sign works,sign fails,& & sign(10.0_real32).eq.1.0 & & .and. sign(-10.0_real32).eq.-1.0 ) write(*,*) merge(sign works,sign fails,& & sign(10.0_real64).eq.1.0 & & .and. sign(-10.0_real64).eq.-1.0 ) write(*,*) merge(sign works,sign fails,& & sign(10.0_real128).eq.1.0& & .and. sign(-10.0_real128).eq.-1.0 ) if(command_argument_count().eq.0)then call get_command(cmd,realloc=.true.) cmd=cmd// & & -x -y "hello there" xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx call execute_command_line(cmd) else call demo_get_command() call demo_get_command_argumentA() endif
subroutine demo_get_command() use M_overload, only : get_command implicit none character(len=:),allocatable :: command_line call get_command(command=command_line) write(*,(*(g0,1x)))len(command_line),command_line end subroutine demo_get_commandsubroutine demo_get_command_argumentA() ! alloctable and realloc=.true. use M_overload, only : get_command_argument implicit none character(len=:),allocatable :: argument integer :: istat, i do i=0, command_argument_count() call get_command_argument(i, argument,status=istat,& & realloc=.true.) write (*,(2(g0,1x),"[",a,"]")) i,istat,argument enddo end subroutine demo_get_command_argumentA
end program demo_M_overloadResults:
> int("STRING") works > real("STRING") works > dble("STRING") works > == works like .eqv. for LOGICAL values > /= works like .neqv. for LOGICAL values > 444 555 > 444.444000 555.554993 > 444.44400000000002 555.55500000000006 > 555.44399999999996 666.66600000000005 777.77700000000004 > sign works > sign works > sign works > sign works > sign works > sign works > sign works > int("STRING") works > real("STRING") works > dble("STRING") works > == works like .eqv. for LOGICAL values > /= works like .neqv. for LOGICAL values > 444 555 > 444.444000 555.554993 > 444.44400000000002 555.55500000000006 > 555.44399999999996 666.66600000000005 777.77700000000004 > sign works > sign works > sign works > sign works > sign works > sign works > sign works > 57 xx -x -y hello there xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx > 0 0 [xx] > 1 0 [-x] > 2 0 [-y] > 3 0 [hello there] > 4 0 [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] > 0 0 [xx ] > 1 0 [-x ] > 2 0 [-y ] > 3 -1 [hello ther] > 4 -1 [xxxxxxxxxx] > 0 0 [xx ] > 1 0 [-x ] > 2 0 [-y ] > 3 0 [hello there ] > 4 -1 [xxxxxxxxxxxxxxxxxxxx]
John S. Urban
Public Domain
M_overload (3) | October 17, 2020 |