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