MODFLOW 6  version 6.7.0.dev0
USGS Modular Hydrologic Model
STLVecInt.f90
Go to the documentation of this file.
2  use kindmodule, only: i4b, lgp
3  use simmodule, only: ustop
5  implicit none
6  private
7  public :: stlvecint
8 
9  integer(I4B), parameter :: defaultinitialcapacity = 4
10 
11  ! This is a dynamic vector type for integers
12  type :: stlvecint
13  integer(I4B), private, allocatable :: values(:) !< the internal array for storage
14  integer(I4B) :: size !< the number of elements (technically this stuff should be unsigned)
15  integer(I4B) :: capacity !< the reserved storage
16  contains
17  procedure, pass(this) :: init !< allocate memory, init size and capacity
18  procedure, pass(this) :: push_back !< adds an element at the end of the vector
19  procedure, pass(this) :: push_back_unique !< adds an element at the end of the vector, if not present yet
20  procedure, pass(this) :: add_array !< adds elements of array at the end of the vector
21  procedure, pass(this) :: add_array_unique !< adds elements of array at the end of the vector, if not present yet
22  procedure, pass(this) :: at !< random access, unsafe, no bounds checking
23  procedure, pass(this) :: at_safe !< random access with bounds checking
24  procedure, pass(this) :: set !< set value at index, no bounds checking
25  procedure, pass(this) :: clear !< empties the vector, leaves memory unchanged
26  procedure, pass(this) :: shrink_to_fit !< reduces the allocated memory to fit the actual vector size
27  procedure, pass(this) :: destroy !< deletes the memory
28  procedure, pass(this) :: contains !< true when element already present
29  procedure, pass(this) :: get_index !< return index of first occurrence of value in array, -1 when not present
30  procedure, pass(this) :: get_values !< returns a copy of the values
31  ! private
32  procedure, private, pass(this) :: expand
33  end type stlvecint
34 
35 contains ! module routines
36 
37  subroutine init(this, capacity)
38  class(stlvecint), intent(inout) :: this
39  integer(I4B), intent(in), optional :: capacity ! the initial capacity, when given
40 
41  if (present(capacity)) then
42  this%capacity = capacity
43  else
44  this%capacity = defaultinitialcapacity
45  end if
46 
47  allocate (this%values(this%capacity))
48  this%size = 0
49 
50  end subroutine init
51 
52  subroutine push_back(this, newValue)
53  class(stlvecint), intent(inout) :: this
54  integer(I4B) :: newValue
55  ! check capacity
56  if (this%size + 1 > this%capacity) then
57  call this%expand()
58  end if
59 
60  this%size = this%size + 1
61  this%values(this%size) = newvalue
62 
63  end subroutine push_back
64 
65  subroutine push_back_unique(this, newValue)
66  class(stlvecint), intent(inout) :: this
67  integer(I4B) :: newValue
68 
69  if (.not. this%contains(newvalue)) then
70  call this%push_back(newvalue)
71  end if
72 
73  end subroutine push_back_unique
74 
75  subroutine add_array(this, array)
76  class(stlvecint), intent(inout) :: this
77  integer(I4B), dimension(:), pointer :: array
78  ! local
79  integer(I4B) :: i
80 
81  do i = 1, size(array)
82  call this%push_back(array(i))
83  end do
84 
85  end subroutine add_array
86 
87  subroutine add_array_unique(this, array)
88  class(stlvecint), intent(inout) :: this
89  integer(I4B), dimension(:), pointer :: array
90  ! local
91  integer(I4B) :: i
92 
93  do i = 1, size(array)
94  if (.not. this%contains(array(i))) then
95  call this%push_back(array(i))
96  end if
97  end do
98 
99  end subroutine add_array_unique
100 
101  function at(this, idx) result(value)
102  class(stlvecint), intent(in) :: this
103  integer(I4B), intent(in) :: idx
104  integer(I4B) :: value
105 
106  value = this%values(idx)
107 
108  end function at
109 
110  function at_safe(this, idx) result(value)
111  class(stlvecint), intent(inout) :: this
112  integer(I4B), intent(in) :: idx
113  integer(I4B) :: value
114 
115  if (idx > this%size) then
116  write (*, *) 'STLVecInt exception: access out of bounds, index ', idx, &
117  ' exceeds actual size (', this%size, ')'
118  call ustop()
119  end if
120  value = this%at(idx)
121 
122  end function at_safe
123 
124  subroutine set(this, idx, value)
125  class(stlvecint), intent(inout) :: this
126  integer(I4B), intent(in) :: idx
127  integer(I4B) :: value
128 
129  this%values(idx) = value
130 
131  end subroutine set
132 
133  subroutine clear(this)
134  class(stlvecint), intent(inout) :: this
135 
136  ! really, this is all there is to it...
137  this%size = 0
138 
139  end subroutine clear
140 
141  subroutine shrink_to_fit(this)
142  class(stlvecint), intent(inout) :: this
143  ! local
144  integer(I4B), allocatable :: tempValues(:)
145  integer(I4B) :: i, newSize
146 
147  if (this%size == this%capacity) then
148  return
149  end if
150 
151  ! store temp
152  newsize = this%size
153  allocate (tempvalues(newsize))
154  do i = 1, newsize
155  tempvalues(i) = this%values(i)
156  end do
157 
158  ! reinit
159  call this%destroy()
160  call this%init(newsize)
161 
162  ! copy back
163  do i = 1, newsize
164  call this%push_back(tempvalues(i))
165  end do
166 
167  end subroutine shrink_to_fit
168 
169  subroutine destroy(this)
170  class(stlvecint), intent(inout) :: this
171 
172  if (allocated(this%values)) then
173  deallocate (this%values)
174  this%size = 0
175  this%capacity = 0
176  else
177  write (*, *) 'STLVecInt exception: cannot delete an unallocated array'
178  call ustop()
179  end if
180 
181  end subroutine destroy
182 
183  ! expand the array with the given strategy, at
184  ! least by 1
185  subroutine expand(this)
186  class(stlvecint), intent(inout) :: this
187  integer(I4B) :: increment
188 
189  ! expansion strategy
190  increment = this%capacity / 2 + 1
191  call expandarray(this%values, increment)
192  this%capacity = this%capacity + increment
193 
194  end subroutine expand
195 
196  ! check if the element is already present
197  function contains(this, val) result(res)
198  class(stlvecint), intent(inout) :: this
199  integer(I4B) :: val
200  logical(LGP) :: res
201  ! local
202  integer(I4B) :: i
203 
204  res = .false.
205  do i = 1, this%size
206  if (this%at(i) == val) then
207  res = .true.
208  return
209  end if
210  end do
211 
212  end function contains
213 
214  !> @brief Return index of first occurrence,
215  !< returns -1 when not present
216  function get_index(this, val) result(idx)
217  class(stlvecint), intent(inout) :: this
218  integer(I4B) :: val
219  integer(I4B) :: idx
220  ! local
221  integer(I4B) :: i
222 
223  idx = -1
224  do i = 1, this%size
225  if (this%at(i) == val) then
226  idx = i
227  return
228  end if
229  end do
230 
231  end function get_index
232 
233  function get_values(this) result(values)
234  class(stlvecint), intent(in) :: this
235  integer(I4B), dimension(:), allocatable :: values
236 
237  values = this%values(1:this%size)
238 
239  end function get_values
240 
241 end module stlvecintmodule
subroutine init()
Definition: GridSorting.f90:24
This module defines variable data types.
Definition: kind.f90:8
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public ustop(stopmess, ioutlocal)
Stop the simulation.
Definition: Sim.f90:312
subroutine push_back_unique(this, newValue)
Definition: STLVecInt.f90:66
subroutine set(this, idx, value)
Definition: STLVecInt.f90:125
subroutine push_back(this, newValue)
Definition: STLVecInt.f90:53
subroutine shrink_to_fit(this)
Definition: STLVecInt.f90:142
subroutine clear(this)
Definition: STLVecInt.f90:134
integer(i4b) function at_safe(this, idx)
Definition: STLVecInt.f90:111
integer(i4b) function, dimension(:), allocatable get_values(this)
Definition: STLVecInt.f90:234
logical(lgp) function contains(this, val)
Definition: STLVecInt.f90:198
subroutine expand(this)
Definition: STLVecInt.f90:186
integer(i4b) function at(this, idx)
Definition: STLVecInt.f90:102
subroutine add_array(this, array)
Definition: STLVecInt.f90:76
subroutine destroy(this)
Definition: STLVecInt.f90:170
subroutine add_array_unique(this, array)
Definition: STLVecInt.f90:88
integer(i4b) function get_index(this, val)
Return index of first occurrence,.
Definition: STLVecInt.f90:217
integer(i4b), parameter defaultinitialcapacity
Definition: STLVecInt.f90:9