M_anything Module

NAME

M_anything(3fm) - [M_anything::INTRO] procedures that use polymorphism to allow arguments of different types generically
(LICENSE:MIT)

SYNOPSIS

Syntax:

  use M_anything,only : anyscalar_to_string
  use M_anything,only : anyscalar_to_int64
  use M_anything,only : anyscalar_to_real
  use M_anything,only : anyscalar_to_real128
  use M_anything,only : anyscalar_to_double
  use M_anything,only : anything_to_bytes
  use M_anything,only : anyinteger_to_string
  use M_anything,only : get_type
  use M_anything,only : bytes_to_anything
  use M_anything,only : empty, assignment(=)

DESCRIPTION

   anyscalar_to_string     convert intrinsic type to string
   anyscalar_to_int64      convert integer or real of any kind to 64-bit integer
   anyscalar_to_real       convert integer or real of any kind to real
   anyscalar_to_real128    convert integer or real of any kind to real128
   anyscalar_to_double     convert integer or real of any kind to doubleprecision
   anything_to_bytes       convert anything to bytes
   anyinteger_to_string    convert integer to string
   get_type                return array of strings containing type names of arguments
   empty                   create an empty array

EXAMPLES

At the cost of casting to a different type these functions can (among other uses such as in linked lists) allow for an alternative to duplicating code using generic procedure methods. For example, the following SQUAREALL function can take many input types and return a DOUBLEPRECISION value (it is a trivial example for demonstration purposes, and does not check for overflow, etc.).:

Sample program

 program demo_M_anything
 use, intrinsic :: iso_fortran_env, only : int8, int16, int32, int64
 use, intrinsic :: iso_fortran_env, only : real32, real64, real128
 implicit none
    ! call same function with many scalar input types
    write(*,*)squareall(2_int8)
    write(*,*)squareall(2_int16)
    write(*,*)squareall(2_int32)
    write(*,*)squareall(2_int64)
    write(*,*)squareall(2.0_real32)
    write(*,*)squareall(2.0_real64)
    !write(*,*)squareall(2.0_real128)
 contains

 function squareall(invalue) result (dvalue)
 use M_anything, only : anyscalar_to_double
 class(*),intent(in)  :: invalue
 doubleprecision      :: invalue_local
 doubleprecision      :: dvalue
    invalue_local=anyscalar_to_double(invalue)
    dvalue=invalue_local*invalue_local
 end function squareall

 end program demo_M_anything

Results:

   4.00000000000000
   4.00000000000000
   4.00000000000000
   4.00000000000000
   4.00000000000000
   4.00000000000000
   4.00000000000000

AUTHOR

John S. Urban

LICENSE

MIT

,input_unit,output_unit public setany

subroutine setany(anything,default,answer)

$@(#) M_anything::setany(3fp): set absent parameter to default value

class(),intent(in),optional :: anything class(),intent(in) :: default class(*),intent(out),allocatable :: answer if(present(anything))then answer=anything else answer=default endif end subroutine setany



Variables

Type Visibility Attributes Name Initial
type(Empty_t), public :: empty

singleton


Interfaces

public interface anything_to_bytes

  • private function anything_to_bytes_arr(anything) result(chars)

    NAME

    anything_to_bytes(3f) - [M_anything] convert standard types to bytes (character(len=1):: array(:))
    (LICENSE:MIT)
    

    SYNOPSIS

    function anything_to_bytes(anything) result(chars)
    
     class(*),intent(in)  :: anything
             or
     class(*),intent(in)  :: anything(:)
    
     character(len=1),allocatable :: chars(:)
    

    DESCRIPTION

    This function uses polymorphism to allow input arguments of different
    types. It is used to create other procedures that can take many
    argument types as input options and convert them to a single type
    to simplify storing arbitrary data, to simplify generating data
    hashes, ...
    
    The **transfer(3f)** function is now a standard, even more general
    equivalent.
    

    OPTIONS

    VALUEIN  input array or scalar to convert to type CHARACTER(LEN=1).
             May be of KIND INTEGER(kind=int8), INTEGER(kind=int16),
             INTEGER(kind=int32), INTEGER(kind=int64),
             REAL(kind=real32, REAL(kind=real64),
             REAL(kind=real128), complex, or CHARACTER(len=*)
    

    RETURN

    CHARS    The returned value is an array of bytes (character(len=1)).
    

    EXAMPLES

    Sample program

      program demo_anything_to_bytes
      use M_anything,      only : anything_to_bytes
      implicit none
      integer :: i
         write(*,"('select various types')")
         write(*,'(/,16(1x,z2.2))')anything_to_bytes([(i*i,i=1,10)])
         write(*,'(/,16(1x,z2.2))')anything_to_bytes([11.11,22.22,33.33])
         write(*,'(/,16(1x,z2.2))')anything_to_bytes('This is a string')
    
         write(*,"(/,'compare to TRANSFER(3f)')")
         write(*,'(/,16(1x,z2.2))') transfer([(i*i,i=1,10)],[' '])
         write(*,'(/,16(1x,z2.2))') transfer([11.11,22.22,33.33],[' '])
         write(*,'(/,16(1x,z2.2))') transfer('This is a string',[' '])
      end program demo_anything_to_bytes
    

    ``` Results:

     > select various types
     >
     >  01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00
     >  19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00
     >  51 00 00 00 64 00 00 00
     >
     >  8F C2 31 41 8F C2 B1 41 EC 51 05 42
     >
     >  54 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67
     >
     > compare to TRANSFER(3f)
     >
     >  01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00
     >  19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00
     >  51 00 00 00 64 00 00 00
     >
     >  8F C2 31 41 8F C2 B1 41 EC 51 05 42
     >
     >  54 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67
    

    AUTHOR

    John S. Urban
    

    LICENSE

    MIT
    

    Arguments

    Type IntentOptional Attributes Name
    class(*), intent(in) :: anything(:)

    Return Value character(len=1), allocatable, (:)

  • private function anything_to_bytes_scalar(anything) result(chars)

    Arguments

    Type IntentOptional Attributes Name
    class(*), intent(in) :: anything

    Return Value character(len=1), allocatable, (:)

public interface assignment(=)

  • private subroutine ints_empty_(x, emp)

    NAME

    empty(3f) - [M_anything] set an allocatable array to zero
    (LICENSE:MIT)
    

    SYNOPSIS

    use M_anything, only : empty, assignment(=)
    

    DESCRIPTION

    A convenience routine that sets an array to an empty set.
    

    EXAMPLES

    Sample program:

    program demo_empty_
    use M_anything, only : empty, assignment(=)
    integer, allocatable      :: ints(:)
    character(:), allocatable :: strs(:)
    real, allocatable         :: reals(:)
       ints=empty
       write(*,*)size(ints)
    
       write(*,*)'give them some size ...'
       reals = [1.0,2.0,3.0]
       ints = [1,2,3]
       strs = [character(len=10) :: "one","two","three","four"]
       write(*,*)size(ints)
       write(*,*)size(reals)
       write(*,*)size(strs)
    
       ints=empty
       reals=empty
       strs=empty
       write(*,*)'back to empty ...'
       write(*,*)size(ints)
       write(*,*)size(reals)
       write(*,*)size(strs)
    
    end program demo_empty_
    

    Expected output:

    >             0
    >   give them some size ...
    >             3
    >             3
    >             4
    >   back to empty ...
    >             0
    >             0
    >             0
    

    AUTHOR

    John S. Urban
    

    LICENSE

    MIT
    

    Arguments

    Type IntentOptional Attributes Name
    integer, intent(inout), allocatable :: x(:)
    type(Empty_t), intent(in) :: emp
  • private subroutine reals_empty_(x, emp)

    Arguments

    Type IntentOptional Attributes Name
    real, intent(inout), allocatable :: x(:)
    type(Empty_t), intent(in) :: emp
  • private subroutine doubles_empty_(x, emp)

    Arguments

    Type IntentOptional Attributes Name
    doubleprecision, intent(inout), allocatable :: x(:)
    type(Empty_t), intent(in) :: emp
  • private subroutine strings_empty_(x, emp)

    Arguments

    Type IntentOptional Attributes Name
    character(len=:), intent(inout), allocatable :: x(:)
    type(Empty_t), intent(in) :: emp

public interface bytes_to_anything

  • private subroutine bytes_to_anything_arr(chars, anything)

    NAME

    bytes_to_anything(3f) - [M_anything] convert bytes(character)len=1):: array(:)) to standard types
    (LICENSE:MIT)
    

    SYNOPSIS

    subroutine bytes_to_anything(chars,anything)

    character(len=1),allocatable :: chars(:)
    class(*) :: anything
    

    DESCRIPTION

    This function uses polymorphism to allow input arguments of different
    types. It is used to create other procedures that can take many
    argument types as input options and convert them to a single type
    to simplify storing arbitrary data, to simplify generating data
    hashes, ...
    

    OPTIONS

    CHARS     The input value is an array of bytes (character(len=1)).
    

    RETURN

    ANYTHING  May be of KIND INTEGER(kind=int8), INTEGER(kind=int16),
              INTEGER(kind=int32), INTEGER(kind=int64),
              REAL(kind=real32, REAL(kind=real64),
              REAL(kind=real128), complex, or CHARACTER(len=*)
    

    EXAMPLES

    Sample program

       program demo_bytes_to_anything
       use, intrinsic :: ISO_FORTRAN_ENV, only: &
            CSZ => CHARACTER_STORAGE_SIZE, &
            stderr => error_unit
       use :: M_anything, only : bytes_to_anything, anything_to_bytes
       implicit none
       character(len=1), allocatable :: chars(:)
       character(len=:), allocatable :: line
       character(len=:), allocatable :: lines(:)
       integer                       :: ints(10)
       integer                       :: i, int
       integer,allocatable           :: somesize(:)
    
       call header('integer array to bytes')
       chars = anything_to_bytes([(i*i, i=1, size(ints))])
       write (*, '(/,4(1x,z2.2))') chars
       call bytes_to_anything(chars, ints)
       write(*,*)'and bytes back to integer array'
       write (*, '(/,*(g0,1x))') ints
    
       call header('integer scalar to bytes')
       chars = anything_to_bytes(1234)
       write (*, '(/,"CHARS=",*(1x,z2.2))') chars
       call bytes_to_anything(chars, int)
       write(*,*)'and bytes back to integer scalar'
       write (*, '(/,"INT=",*(g0,1x))') int
    
       call header('a string')
       chars = anything_to_bytes('this is a string')
       write (*, '(/,"CHARS=",*(1x,z2.2))') chars
       write (*, '(/,"CHARS=",*(g0,1x))') chars
       ! string must be long enough to hold chars
       line=repeat(' ',size(chars))
       call bytes_to_anything(chars, line)
       write (*, '(/,"LINE=",*(g0,1x))') line
    
       call header(&
       'a string array (have to know length or size you wish to return to)')
       chars = anything_to_bytes([character(len=4) :: 'a', 'bb', 'ccc' ])
       write (*, '(/,"CHARS=",*(1x,z2.2))') chars
       write (*, '(/,"CHARS=",*(g0,1x))') chars
       ! string must be long enough to hold chars, and have enough elements
       ! can just return as a scalar string if unknown length
       lines=[repeat(' ',size(chars))]
       ! of for that matter just work with the chars(1) array,
       ! but assuming know length in this case
       lines=[(repeat('#',4),i=1,3)]
       call bytes_to_anything(chars, lines)
       write (*, '(/,"LINES=",*("[",g0,"]",1x:))') lines
    
       call header('calculating size to allocate for non-string types')
       ! make sure array is of sufficient size to hold results
       chars = anything_to_bytes([11,22,33,44])
       write (*, '(/,"CHARS=",*(1x,z2.2))') chars
       allocate(somesize(size(chars)/(storage_size(0)/CSZ)))
       call bytes_to_anything(chars, somesize)
       write (*, '(/,"SOMESIZE=",*("[",g0,"]",1x:))') somesize
       contains
       subroutine header(line)
       character(len=*),intent(in) :: line
       write(*,'(*(a))')'#',repeat('=',len(line)+2),'#'
       write(*,'("|",1x,a,1x,"|")') line
       write(*,'(*(a))')'#',repeat('=',len(line)+2),'#'
       end subroutine header
       end program demo_bytes_to_anything
    

    Results:

     > #========================#
     > | integer array to bytes |
     > #========================#
     >
     >  01 00 00 00
     >  04 00 00 00
     >  09 00 00 00
     >  10 00 00 00
     >  19 00 00 00
     >  24 00 00 00
     >  31 00 00 00
     >  40 00 00 00
     >  51 00 00 00
     >  64 00 00 00
     >  and bytes back to integer array
     >
     > 1 4 9 16 25 36 49 64 81 100
     > #=========================#
     > | integer scalar to bytes |
     > #=========================#
     >
     > CHARS= D2 04 00 00
     >  and bytes back to integer scalar
     >
     > INT=1234
     > #==========#
     > | a string |
     > #==========#
     >
     > CHARS= 74 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67
     >
     > CHARS=t h i s   i s   a   s t r i n g
     >
     > LINE=this is a string
     > #====================================================================#
     > | a string array (have to know length or size you wish to return to) |
     > #====================================================================#
     >
     > CHARS= 61 20 20 20 62 62 20 20 63 63 63 20
     >
     > CHARS=a       b b     c c c
     >
     > LINES=[a   ] [bb  ] [ccc ]
     > #===================================================#
     > | calculating size to allocate for non-string types |
     > #===================================================#
     >
     > CHARS= 0B 00 00 00 16 00 00 00 21 00 00 00 2C 00 00 00
     >
     > SOMESIZE=[11] [22] [33] [44]
    

    AUTHOR

    John S. Urban
    

    LICENSE

    MIT
    

    Arguments

    Type IntentOptional Attributes Name
    character(len=1), intent(in) :: chars(:)
    class(*), intent(out) :: anything(:)
  • private subroutine bytes_to_anything_scalar(chars, anything)

    Arguments

    Type IntentOptional Attributes Name
    character(len=1), intent(in) :: chars(:)
    class(*), intent(out) :: anything

public interface get_type

  • private function get_type_arr(anything) result(chars)

    NAME

    get_type(3f) - [M_anything] return array of strings containing type
    names of arguments
    (LICENSE:MIT)
    

    SYNOPSIS

    function get_type(anything) result(chars)
    
     class(*),intent(in)  :: anything
             or
     class(*),intent(in)  :: anything(..)
    
     character(len=:),allocatable :: chars
    

    DESCRIPTION

    This function uses polymorphism to allow input arguments of different
    types. It is used by other procedures that can take many
    argument types as input options.
    

    OPTIONS

    VALUEIN  input array or scalar to return type of
             May be of KIND INTEGER(kind=int8), INTEGER(kind=int16),
             INTEGER(kind=int32), INTEGER(kind=int64),
             REAL(kind=real32, REAL(kind=real64),
             REAL(kind=real128), complex, or CHARACTER(len=*)
    

    RETURN

    CHARS    The returned value is an array of names
    

    EXAMPLES

    Sample program

    program demo_get_type
    use M_anything,      only : get_type
    implicit none
    integer :: i
       write(*,*)get_type([(i*i,i=1,10)])
       write(*,*)get_type([11.11,22.22,33.33])
       write(*,*)get_type('This is a string')
       write(*,*)get_type(30.0d0)
    end program demo_get_type
    

    Results:

     int32
     real32
     character
     real64
    

    AUTHOR

    John S. Urban
    

    LICENSE

    MIT
    

    Arguments

    Type IntentOptional Attributes Name
    class(*), intent(in) :: anything(:)

    Return Value character(len=20)

  • private impure elemental function get_type_scalar(anything) result(chars)

    Arguments

    Type IntentOptional Attributes Name
    class(*), intent(in) :: anything

    Return Value character(len=20)


Functions

public impure function anyinteger_to_string(int) result(out)

Sample program

Read more…

Arguments

Type IntentOptional Attributes Name
class(*), intent(in) :: int

Return Value character(len=:), allocatable

public pure elemental function anyscalar_to_double(valuein) result(d_out)

Sample program

Read more…

Arguments

Type IntentOptional Attributes Name
class(*), intent(in) :: valuein

Return Value doubleprecision

public impure elemental function anyscalar_to_int64(valuein) result(ii38)

Results

Read more…

Arguments

Type IntentOptional Attributes Name
class(*), intent(in) :: valuein

Return Value integer(kind=int64)

public pure elemental function anyscalar_to_real(valuein) result(r_out)

Sample program

Read more…

Arguments

Type IntentOptional Attributes Name
class(*), intent(in) :: valuein

Return Value real

public pure elemental function anyscalar_to_real128(valuein) result(d_out)

Sample program

Read more…

Arguments

Type IntentOptional Attributes Name
class(*), intent(in) :: valuein

Return Value real(kind=real128)

public pure function anyscalar_to_string(gen0, gen1, gen2, gen3, gen4, gen5, gen6, gen7, gen8, gen9, gena, genb, genc, gend, gene, genf, geng, genh, geni, genj, sep)

Sample program:

Read more…

Arguments

Type IntentOptional Attributes Name
class(*), intent(in), optional :: gen0
class(*), intent(in), optional :: gen1
class(*), intent(in), optional :: gen2
class(*), intent(in), optional :: gen3
class(*), intent(in), optional :: gen4
class(*), intent(in), optional :: gen5
class(*), intent(in), optional :: gen6
class(*), intent(in), optional :: gen7
class(*), intent(in), optional :: gen8
class(*), intent(in), optional :: gen9
class(*), intent(in), optional :: gena
class(*), intent(in), optional :: genb
class(*), intent(in), optional :: genc
class(*), intent(in), optional :: gend
class(*), intent(in), optional :: gene
class(*), intent(in), optional :: genf
class(*), intent(in), optional :: geng
class(*), intent(in), optional :: genh
class(*), intent(in), optional :: geni
class(*), intent(in), optional :: genj
character(len=*), intent(in), optional :: sep

Return Value character(len=:), allocatable