m_overload Module

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

John S. Urban

LICENSE

Public Domain

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

public interface adjustl

  • private function adjustl_atleast(line, length) result(strout)

    Arguments

    Type IntentOptional Attributes Name
    character(len=*), intent(in) :: line
    integer, intent(in) :: length

    Return Value character(kind=len(trim(line))), len=max)

public interface adjustr

  • private function adjustr_atleast(line, length) result(strout)

    Arguments

    Type IntentOptional Attributes Name
    character(len=*), intent(in) :: line
    integer, intent(in) :: length

    Return Value character(kind=len(trim(line))), len=max)

public interface dble

  • private function dbles_s2v(chars)

    Arguments

    Type IntentOptional Attributes Name
    character(len=*), intent(in) :: chars(:)

    Return Value doubleprecision, allocatable, (:)

public interface int

  • private function ints_s2v(chars)

    Arguments

    Type IntentOptional Attributes Name
    character(len=*), intent(in) :: chars(:)

    Return Value integer, allocatable, (:)

public interface merge

  • private elemental function strmerge(str1, str2, expr) result(strout)

    Arguments

    Type IntentOptional Attributes Name
    character(len=*), intent(in) :: str1
    character(len=*), intent(in) :: str2
    logical, intent(in) :: expr

    Return Value character(kind=len(str2)), len=max)

public interface real

  • private function reals_s2v(chars)

    Arguments

    Type IntentOptional Attributes Name
    character(len=*), intent(in) :: chars(:)

    Return Value real, allocatable, (:)

public interface sign

  • private elemental function sign_int8(value)

    Arguments

    Type IntentOptional Attributes Name
    integer(kind=int8), intent(in) :: value

    Return Value integer(kind=int8)


Functions

public function boolean_equal(logical_val1, logical_val2)

Arguments

Type IntentOptional Attributes Name
logical, intent(in) :: logical_val1
logical, intent(in) :: logical_val2

Return Value logical

public function boolean_notequal(logical_val1, logical_val2)

Arguments

Type IntentOptional Attributes Name
logical, intent(in) :: logical_val1
logical, intent(in) :: logical_val2

Return Value logical

public pure elemental function eq(ia, ib)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: ia
integer, intent(in) :: ib

Return Value integer

public pure elemental function ge(ia, ib)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: ia
integer, intent(in) :: ib

Return Value integer

public pure elemental function gt(ia, ib)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: ia
integer, intent(in) :: ib

Return Value integer

public pure elemental function le(ia, ib)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: ia
integer, intent(in) :: ib

Return Value integer

public pure elemental function lt(ia, ib)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: ia
integer, intent(in) :: ib

Return Value integer

public pure elemental function ne(ia, ib)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: ia
integer, intent(in) :: ib

Return Value integer

public pure elemental function oz(expr)

Sample usage:

Read more…

Arguments

Type IntentOptional Attributes Name
logical, intent(in) :: expr

Return Value integer

public pure elemental function zo(expr)

Sample usage:

Read more…

Arguments

Type IntentOptional Attributes Name
logical, intent(in) :: expr

Return Value integer