MODFLOW 6  version 6.6.0.dev0
USGS Modular Hydrologic Model
CharString.f90
Go to the documentation of this file.
2 
3  implicit none
4  private
5  public :: characterstringtype
6 
7  !> This class is used to store a single deferred-length
8  !! character string. It was designed to work in an
9  !! array implementation so that a jagged character array
10  !! could be used in MODFLOW and stored in the memory
11  !! manager.
12  !!
13  !! The overloaded methods allow instances to behave like
14  !! a regular string and work with intrinsic Fortran
15  !! character strings. Ideas for the implementation were
16  !! inspired by:
17  !! https://gitlab.com/everythingfunctional/iso_varying_string
18  !
19  !! Can be improved as necessary to overload other string
20  !! functions, such as write_formatted, trim, len, ...
21  !!
22  !<
24  private
25  character(len=:), allocatable :: charstring
26  contains
27  procedure, pass(lhs) :: assign_to_charstring
28  procedure, pass(rhs) :: assign_from_charstring
29  procedure, pass(rhs) :: character_eq_charstring
30  procedure, pass(lhs) :: charstring_eq_character
32  procedure :: write_unformatted
33  procedure :: strlen
34  procedure :: destroy
35  generic :: assignment(=) => assign_to_charstring, assign_from_charstring
36  generic :: operator(==) => character_eq_charstring, &
39  ! not supported by gfortran 5 and 6
40  ! disable for now
41  ! generic :: write (unformatted) => write_unformatted
42  end type characterstringtype
43 
44 contains
45 
46  recursive subroutine assign_to_charstring(lhs, rhs)
47  class(characterstringtype), intent(out) :: lhs
48  character(len=*), intent(in) :: rhs
49  logical :: allocate_charstring
50  allocate_charstring = .false.
51  if (allocated(lhs%charstring)) then
52  if (len(lhs%charstring) <= len(rhs)) then
53  lhs%charstring(:) = rhs
54  else
55  allocate_charstring = .true.
56  end if
57  else
58  allocate_charstring = .true.
59  end if
60  if (allocate_charstring) then
61  lhs%charstring = rhs
62  end if
63  end subroutine assign_to_charstring
64 
65  subroutine assign_from_charstring(lhs, rhs)
66  character(len=*), intent(out) :: lhs
67  class(characterstringtype), intent(in) :: rhs
68  if (allocated(rhs%charstring)) then
69  lhs = rhs%charstring
70  else
71  lhs = ''
72  end if
73  end subroutine assign_from_charstring
74 
75  elemental function character_eq_charstring(lhs, rhs) result(equals)
76  character(len=*), intent(in) :: lhs
77  class(characterstringtype), intent(in) :: rhs
78  logical :: equals
79  if (allocated(rhs%charstring)) then
80  equals = lhs == rhs%charstring
81  else
82  equals = lhs == ''
83  end if
84  end function character_eq_charstring
85 
86  elemental function charstring_eq_character(lhs, rhs) result(equals)
87  class(characterstringtype), intent(in) :: lhs
88  character(len=*), intent(in) :: rhs
89  logical :: equals
90  if (allocated(lhs%charstring)) then
91  equals = lhs%charstring == rhs
92  else
93  equals = rhs == ''
94  end if
95  end function charstring_eq_character
96 
97  elemental function charstring_eq_charstring(this, rhs) result(equals)
98  class(characterstringtype), intent(in) :: this
99  class(characterstringtype), intent(in) :: rhs
100  logical :: equals
101 
102  equals = .false.
103  if (allocated(this%charstring)) then
104  equals = (rhs == this%charstring)
105  end if
106 
107  end function charstring_eq_charstring
108 
109  subroutine write_unformatted(this, unit, iostat, iomsg)
110  class(characterstringtype), intent(in) :: this
111  integer, intent(in) :: unit
112  integer, intent(out) :: iostat
113  character(len=*), intent(inout) :: iomsg
114  iostat = 0
115  if (allocated(this%charstring)) then
116  write (unit, iostat=iostat) this%charstring
117  end if
118  end subroutine write_unformatted
119 
120  function strlen(this) result(length)
121  class(characterstringtype), intent(in) :: this
122  integer :: length
123 
124  if (allocated(this%charstring)) then
125  length = len(this%charstring)
126  else
127  length = 0
128  end if
129  end function strlen
130 
131  subroutine destroy(this)
132  class(characterstringtype), intent(inout) :: this
133  if (allocated(this%charstring)) deallocate (this%charstring)
134  end subroutine destroy
135 
136 end module characterstringmodule
elemental logical function charstring_eq_character(lhs, rhs)
Definition: CharString.f90:87
recursive subroutine assign_to_charstring(lhs, rhs)
Definition: CharString.f90:47
subroutine write_unformatted(this, unit, iostat, iomsg)
Definition: CharString.f90:110
elemental logical function character_eq_charstring(lhs, rhs)
Definition: CharString.f90:76
subroutine assign_from_charstring(lhs, rhs)
Definition: CharString.f90:66
elemental logical function charstring_eq_charstring(this, rhs)
Definition: CharString.f90:98
integer function strlen(this)
Definition: CharString.f90:121
subroutine destroy(this)
Definition: CharString.f90:132
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23