-
Notifications
You must be signed in to change notification settings - Fork 1
/
shr_strconvert_mod.F90
166 lines (135 loc) · 5.16 KB
/
shr_strconvert_mod.F90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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