NAME
M_overload(3fm) - [M_overload::INTRO] overloads of standard operators and intrinsic procedures
(LICENSE:PD)
SYNOPSIS
overloads on operators
use M_overload, only : operator(==), operator(/=)
! use == like .eqv.; ie. logical==logical
! use /= like .neqv.; ie. logical/=logical
use M_overload, only : operator(//)
! convert intrinsics to strings and contatenate
overloads on INTRINSICS to take strings, logicals, and metamorphic numeric intrinsic values
use M_overload, only : int, real, dble
! int('string') int(logical) int(class(*))
! real('string') real(logical) real(class(*))
! dble('string') dble(logical) dble(class(*))
use M_overload, only : sign
! When sign(3f) is given a single value, call sign(1,value); ie. sign(value)
use M_overload, only : merge
! Allow strings of different length in MERGE
other operators
! convert an intrinsic value to a CHARACTER variable
Related functions
! logical functions that return integer values
use M_overload, only : oz, zo, lt, le, eq, ne, gt, ge
DESCRIPTION
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.
OVERLOADS
// overloads // to concatenate any two intrinsic types into a string
==,/= 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. L2
and
L1 /= L2 !! should be L1 .neqv. L2
should 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)
str=merge('little','big',a.eq.10) allows for strings of different lengths
EXAMPLES
Sample usage:
program demo_M_overload
use, intrinsic :: iso_fortran_env, only : &
& integer_kinds, int8, int16, int32, int64
use, intrinsic :: iso_fortran_env, only : &
& real32, real64, real128
! 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(/=)
use M_overload, only : operator(//)
! take a single argument
use M_overload, only : sign
! allow strings of different length on merge
use M_overload, only : merge
! convert logical expressions to integer
use M_overload, only : oz, zo, lt, le, eq, ne, gt, ge
implicit none
character(len=:),allocatable :: cmd
character(len=*), parameter :: gen='(*("[",g0,"]":,","))'
! merge() with different string lengths expanded to longest
write(*,gen)merge('a','bbbbb',1.eq.1)
write(*,gen)merge('a','bbbbb',1.eq.2)
write(*,gen)merge(['a','b'],['bbbbb','ccccc'],1.eq.2)
! int() can take strings representing a number as input'
if(int('1234') .eq.1234) &
& write(*,*)'int("STRING") works '
! as can real() and dble()
if(abs(real('1234.56789') - 1234.56789).lt.2*epsilon(0.0)) &
& write(*,*)'real("STRING") works '
if(abs(dble('1234.5678901234567')- 1234.5678901234567d0).lt.epsilon(0.0d0)) &
& write(*,*)'dble("STRING") works '
! and logical values can be treated numerically
write(*,*) merge('int works for .FALSE.','int fails for .FALSE.',int(.FALSE.).ne.0)
write(*,*) merge('int works for .TRUE.','int fails for .TRUE.',int(.TRUE.).eq.0)
write(*,*) sum(int([.true.,.false.,.true.]))
! and == and /= work for logical expressions
if (.true. == .true. ) &
& write(*,*)'== works like .eqv. for LOGICAL values'
if (.true. /= .false. ) &
& write(*,*)'/= works like .neqv. for LOGICAL values'
! // will allow any intrinsic type and convert it to a string
write(*,*)' The value is '//10//' which is less than '//20.2
! logical values as numeric values
write(*,*) sum([int(.false.),int(.false.)])
write(*,*) int([.false.,.true.,.false.])
write(*,*) sum(int([.false.,.true.,.false.]))
! and sign() assumes the second argument is 1
write(*,*) merge('sign works','sign fails',&
& sign(10_int8).eq.1 &
& .and. sign(-10_int8).eq.-1 )
contains
end program demo_M_overload
Results:
AUTHOR
LICENSE
interface int; module procedure int_s2v; end interface
interface real; module procedure real_s2v; end interface
interface dble; module procedure dble_s2v; end interface
Interfaces
-
private function adjustl_atleast(line, length) result(strout)
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
character(len=*),
|
intent(in) |
|
|
:: |
line |
|
integer,
|
intent(in) |
|
|
:: |
length |
|
Return Value
character(kind=len(trim(line))), len=max)
-
private function adjustr_atleast(line, length) result(strout)
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
character(len=*),
|
intent(in) |
|
|
:: |
line |
|
integer,
|
intent(in) |
|
|
:: |
length |
|
Return Value
character(kind=len(trim(line))), len=max)
-
private function dbles_s2v(chars)
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
character(len=*),
|
intent(in) |
|
|
:: |
chars(:) |
|
Return Value
doubleprecision, allocatable, (:)
-
private function ints_s2v(chars)
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
character(len=*),
|
intent(in) |
|
|
:: |
chars(:) |
|
Return Value
integer, allocatable, (:)
-
private elemental function strmerge(str1, str2, expr) result(strout)
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
character(len=*),
|
intent(in) |
|
|
:: |
str1 |
|
character(len=*),
|
intent(in) |
|
|
:: |
str2 |
|
logical,
|
intent(in) |
|
|
:: |
expr |
|
Return Value
character(kind=len(str2)), len=max)
-
private function reals_s2v(chars)
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
character(len=*),
|
intent(in) |
|
|
:: |
chars(:) |
|
Return Value
real, allocatable, (:)
-
private elemental function sign_int8(value)
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
integer(kind=int8),
|
intent(in) |
|
|
:: |
value |
|
Return Value
integer(kind=int8)
Functions
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
logical,
|
intent(in) |
|
|
:: |
logical_val1 |
|
logical,
|
intent(in) |
|
|
:: |
logical_val2 |
|
Return Value
logical
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
logical,
|
intent(in) |
|
|
:: |
logical_val1 |
|
logical,
|
intent(in) |
|
|
:: |
logical_val2 |
|
Return Value
logical
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
integer,
|
intent(in) |
|
|
:: |
ia |
|
integer,
|
intent(in) |
|
|
:: |
ib |
|
Return Value
integer
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
integer,
|
intent(in) |
|
|
:: |
ia |
|
integer,
|
intent(in) |
|
|
:: |
ib |
|
Return Value
integer
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
integer,
|
intent(in) |
|
|
:: |
ia |
|
integer,
|
intent(in) |
|
|
:: |
ib |
|
Return Value
integer
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
integer,
|
intent(in) |
|
|
:: |
ia |
|
integer,
|
intent(in) |
|
|
:: |
ib |
|
Return Value
integer
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
integer,
|
intent(in) |
|
|
:: |
ia |
|
integer,
|
intent(in) |
|
|
:: |
ib |
|
Return Value
integer
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
integer,
|
intent(in) |
|
|
:: |
ia |
|
integer,
|
intent(in) |
|
|
:: |
ib |
|
Return Value
integer
Sample usage:
Read more…
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
logical,
|
intent(in) |
|
|
:: |
expr |
|
Return Value
integer
Sample usage:
Read more…
Arguments
Type |
Intent | Optional | Attributes |
|
Name |
|
logical,
|
intent(in) |
|
|
:: |
expr |
|
Return Value
integer