Revision abfdea1171a642ae9562f206f55de18dff988559 authored by Jon Wolfe on 21 April 2022, 17:30:08 UTC, committed by Jon Wolfe on 21 April 2022, 17:30:08 UTC
1 parent 90ff912
shr_strconvert_mod.F90
module shr_strconvert_mod
! This module defines toString, a generic function for creating character type
! representations of data, as implemented for the most commonly used intrinsic
! types:
!
! - 4 and 8 byte integer
! - 4 and 8 byte real
! - logical
!
! No toString implementation is provided for character input, but this may be
! added if some use case arises.
!
! Currently, only scalar inputs are supported. The return type of this function
! is character with deferred (allocatable) length.
!
! The functions for integers and reals allow an optional format_string argument,
! which can be used to control the padding and precision of output as with any
! write statement. However, the implementations internally must use a
! preallocated buffer, so a format_string that significantly increases the size
! of the output may cause a run-time error or undefined behavior in the program.
!
! Other modules may want to provide extensions of toString for their own derived
! types. In this case there are two guidelines to observe:
!
! - It is preferable to have only one mandatory argument, which is the object to
! produce a string from. There may be other formatting options, but the
! implementation should do something sensible without these.
!
! - Since the main purpose of toString is to provide a human-readable
! representation of a type, especially for documentation or debugging
! purposes, refrain from printing large array components in their entirety
! (instead consider printing only the shape, or statistics such as
! min/mean/max for arrays of numbers).
use shr_kind_mod, only: &
i4 => shr_kind_i4, &
i8 => shr_kind_i8, &
r4 => shr_kind_r4, &
r8 => shr_kind_r8, &
cs => shr_kind_cs
use shr_infnan_mod, only: &
isnan => shr_infnan_isnan
implicit none
private
! Human-readable representation of data.
public :: toString
interface toString
module procedure i4ToString
module procedure i8ToString
module procedure r4ToString
module procedure r8ToString
module procedure logicalToString
end interface toString
contains
pure function i4ToString(input, format_string) result(string)
integer(i4), intent(in) :: input
character(len=*), intent(in), optional :: format_string
character(len=:), allocatable :: string
character(len=cs) :: buffer
if (present(format_string)) then
write(buffer, format_string) input
else
! For most compilers, these two statements are equivalent to a format of
! '(I0)', but that's not technically in the standard.
write(buffer, '(I11)') input
buffer = adjustl(buffer)
end if
allocate(string, source=trim(buffer))
end function i4ToString
pure function i8ToString(input, format_string) result(string)
integer(i8), intent(in) :: input
character(len=*), intent(in), optional :: format_string
character(len=:), allocatable :: string
character(len=cs) :: buffer
if (present(format_string)) then
write(buffer, format_string) input
else
! For most compilers, these two statements are equivalent to a format of
! '(I0)', but that's not technically in the standard.
write(buffer, '(I20)') input
buffer = adjustl(buffer)
end if
allocate(string, source=trim(buffer))
end function i8ToString
pure function r4ToString(input, format_string) result(string)
real(r4), intent(in) :: input
character(len=*), intent(in), optional :: format_string
character(len=:), allocatable :: string
character(len=cs) :: buffer
if (present(format_string)) then
write(buffer, format_string) input
else
write(buffer, '(ES15.8 E2)') input
buffer = adjustl(buffer)
! Deal with the fact that the "+" sign is optional by simply adding it if
! it is not present, so that the default format is standardized across
! compilers.
! Assumes that compilers do not treat the sign bit on NaN values specially.
if (.not. isnan(input) .and. all(buffer(1:1) /= ["-", "+"])) then
buffer = "+" // trim(buffer)
end if
end if
allocate(string, source=trim(buffer))
end function r4ToString
pure function r8ToString(input, format_string) result(string)
real(r8), intent(in) :: input
character(len=*), intent(in), optional :: format_string
character(len=:), allocatable :: string
character(len=cs) :: buffer
if (present(format_string)) then
write(buffer, format_string) input
else
write(buffer, '(ES24.16 E3)') input
buffer = adjustl(buffer)
! Deal with the fact that the "+" sign is optional by simply adding it if
! it is not present, so that the default format is standardized across
! compilers.
! Assumes that compilers do not treat the sign bit on NaN values specially.
if (.not. isnan(input) .and. all(buffer(1:1) /= ["-", "+"])) then
buffer = "+" // trim(buffer)
end if
end if
allocate(string, source=trim(buffer))
end function r8ToString
pure function logicalToString(input) result(string)
logical, intent(in) :: input
character(len=:), allocatable :: string
! We could use a write statement, but this is easier.
allocate(character(len=1) :: string)
if (input) then
string = "T"
else
string = "F"
end if
end function logicalToString
end module shr_strconvert_mod
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...