MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
listmodule Module Reference

Data Types

type  listtype
 A generic heterogeneous doubly-linked list. More...
 
type  listnodetype
 
interface  isEqualIface
 

Functions/Subroutines

subroutine add (this, objptr)
 Append the given item to the list. More...
 
subroutine clear (this, destroy)
 Deallocate all items in list. More...
 
integer(i4b) function count (this)
 Return number of nodes in list. More...
 
logical function containsobject (this, obj, isEqual)
 Determine whether the list contains the given object. More...
 
subroutine deallocatebackward (this, fromNode)
 Deallocate fromNode and all previous nodes, and reassign firstNode. More...
 
integer(i4b) function getindex (this, obj)
 Get the index of the given item in the list. More...
 
class(*) function, pointer getnextitem (this)
 Get the next item in the list. More...
 
class(*) function, pointer getpreviousitem (this)
 Get the previous item in the list. More...
 
subroutine insertafter (this, objptr, indx)
 Insert the given item after the given index. More...
 
subroutine insertbefore (this, objptr, targetNode)
 Insert the given item before the given node. More...
 
subroutine next (this)
 Move the list's current node pointer and index one node forwards. More...
 
subroutine previous (this)
 Move the list's current node pointer and index one node backwards. More...
 
subroutine reset (this)
 Reset the list's current node pointer and index. More...
 
subroutine remove_node_by_index (this, i, destroyValue)
 Remove the node at the given index, optionally destroying its value. More...
 
subroutine remove_this_node (this, node, destroyValue)
 Remove the given node, optionally destroying its value. More...
 
class(*) function, pointer get_current_item (this)
 Get a pointer to the item at the current node. More...
 
class(*) function, pointer get_item_by_index (this, indx)
 Get a pointer to the item at the given index. More...
 
type(listnodetype) function, pointer get_node_by_index (this, indx)
 Get the node at the given index. More...
 
class(*) function, pointer getitem (this)
 Return a pointer to this node's value. More...
 
subroutine deallocvalue (this, destroy)
 Nullify (optionally deallocating) this node's value. More...
 

Function/Subroutine Documentation

◆ add()

subroutine listmodule::add ( class(listtype), intent(inout)  this,
class(*), intent(inout), pointer  objptr 
)
private

Definition at line 69 of file List.f90.

70  ! -- dummy variables
71  class(ListType), intent(inout) :: this
72  class(*), pointer, intent(inout) :: objptr
73  !
74  if (.not. associated(this%firstNode)) then
75  allocate (this%firstNode)
76  this%firstNode%Value => objptr
77  this%firstNode%prevNode => null()
78  this%lastNode => this%firstNode
79  else
80  allocate (this%lastNode%nextNode)
81  this%lastNode%nextNode%prevNode => this%lastNode
82  this%lastNode%nextNode%value => objptr
83  this%lastNode => this%lastNode%nextNode
84  end if
85  this%nodeCount = this%nodeCount + 1

◆ clear()

subroutine listmodule::clear ( class(listtype this,
logical, intent(in), optional  destroy 
)
private

Definition at line 89 of file List.f90.

90  ! -- dummy variables
91  class(ListType) :: this
92  logical, intent(in), optional :: destroy
93  ! -- local
94  logical :: destroyLocal
95  type(ListNodeType), pointer :: current => null()
96  type(ListNodeType), pointer :: next => null()
97  !
98  destroylocal = .false.
99  if (present(destroy)) then
100  destroylocal = destroy
101  end if
102  !
103  if (.not. associated(this%firstNode)) return
104  ! -- The last node will be deallocated in the loop below.
105  ! Just nullify the pointer to the last node to avoid
106  ! having a dangling pointer. Also nullify currentNode.
107  nullify (this%lastNode)
108  nullify (this%currentNode)
109  !
110  current => this%firstNode
111  do while (associated(current))
112  ! -- Assign a pointer to the next node in the list
113  next => current%nextNode
114  ! -- Deallocate the object stored in the current node
115  call current%DeallocValue(destroylocal)
116  ! -- Deallocate the current node
117  deallocate (current)
118  this%firstNode => next
119  this%nodeCount = this%nodeCount - 1
120  ! -- Advance to the next node
121  current => next
122  end do
123  !
124  call this%Reset()
125 

◆ containsobject()

logical function listmodule::containsobject ( class(listtype), intent(inout)  this,
class(*), pointer  obj,
procedure(isequaliface), intent(in), optional, pointer  isEqual 
)
private

Definition at line 136 of file List.f90.

137  class(ListType), intent(inout) :: this
138  class(*), pointer :: obj
139  procedure(isEqualIface), pointer, intent(in), optional :: isEqual
140  logical :: hasObj
141  ! local
142  type(ListNodeType), pointer :: current => null()
143 
144  hasobj = .false.
145  current => this%firstNode
146  do while (associated(current))
147  if (present(isequal)) then
148  if (isequal(current%Value, obj)) then
149  hasobj = .true.
150  return
151  end if
152  else
153  if (associated(current%Value, obj)) then
154  hasobj = .true.
155  return
156  end if
157  end if
158 
159  ! -- Advance to the next node
160  current => current%nextNode
161  end do
162 

◆ count()

integer(i4b) function listmodule::count ( class(listtype this)
private

Definition at line 129 of file List.f90.

130  integer(I4B) :: Count
131  class(ListType) :: this
132  count = this%nodeCount

◆ deallocatebackward()

subroutine listmodule::deallocatebackward ( class(listtype), intent(inout), target  this,
type(listnodetype), intent(inout), pointer  fromNode 
)
private

Definition at line 166 of file List.f90.

167  ! -- dummy
168  class(ListType), target, intent(inout) :: this
169  type(ListNodeType), pointer, intent(inout) :: fromNode
170  ! -- local
171  type(ListNodeType), pointer :: current => null()
172  type(ListNodeType), pointer :: prev => null()
173  !
174  if (associated(fromnode)) then
175  ! -- reassign firstNode
176  if (associated(fromnode%nextNode)) then
177  this%firstNode => fromnode%nextNode
178  else
179  this%firstNode => null()
180  end if
181  ! -- deallocate fromNode and all previous nodes
182  current => fromnode
183  do while (associated(current))
184  prev => current%prevNode
185  call current%DeallocValue(.true.)
186  deallocate (current)
187  this%nodeCount = this%nodeCount - 1
188  current => prev
189  end do
190  fromnode => null()
191  end if
192 

◆ deallocvalue()

subroutine listmodule::deallocvalue ( class(listnodetype), intent(inout)  this,
logical, intent(in), optional  destroy 
)
private

Definition at line 537 of file List.f90.

538  class(ListNodeType), intent(inout) :: this
539  logical, intent(in), optional :: destroy
540 
541  if (associated(this%Value)) then
542  if (present(destroy)) then
543  if (destroy) then
544  deallocate (this%Value)
545  end if
546  end if
547  nullify (this%Value)
548  end if

◆ get_current_item()

class(*) function, pointer listmodule::get_current_item ( class(listtype), intent(inout), target  this)
private

Definition at line 405 of file List.f90.

406  class(ListType), target, intent(inout) :: this
407  ! result
408  class(*), pointer :: resultobj
409  !
410  resultobj => null()
411  if (associated(this%currentNode)) then
412  resultobj => this%currentNode%Value
413  end if
Here is the caller graph for this function:

◆ get_item_by_index()

class(*) function, pointer listmodule::get_item_by_index ( class(listtype), intent(inout)  this,
integer(i4b), intent(in)  indx 
)
private

Definition at line 417 of file List.f90.

418  ! -- dummy
419  class(ListType), intent(inout) :: this
420  integer(I4B), intent(in) :: indx
421  ! result
422  class(*), pointer :: resultobj
423  ! -- local
424  integer(I4B) :: i
425  !
426  ! -- Initialize
427  resultobj => null()
428  !
429  ! -- Ensure that this%currentNode is associated
430  if (.not. associated(this%currentNode)) then
431  this%currentNodeIndex = 0
432  end if
433  if (this%currentNodeIndex == 0) then
434  if (associated(this%firstNode)) then
435  this%currentNode => this%firstNode
436  this%currentNodeIndex = 1
437  end if
438  end if
439  !
440  ! -- Check indx position relative to current node index
441  i = 0
442  if (indx < this%currentNodeIndex) then
443  ! Start at beginning of list
444  call this%Reset()
445  if (associated(this%firstNode)) then
446  this%currentNode => this%firstNode
447  this%currentNodeIndex = 1
448  i = 1
449  end if
450  else
451  i = this%currentNodeIndex
452  end if
453  if (i == 0) return
454  !
455  ! -- If current node is requested node,
456  ! assign pointer and return
457  if (i == indx) then
458  resultobj => this%currentNode%Value
459  return
460  end if
461  !
462  ! -- Iterate from current node to requested node
463  do while (associated(this%currentNode%nextNode))
464  this%currentNode => this%currentNode%nextNode
465  this%currentNodeIndex = this%currentNodeIndex + 1
466  if (this%currentNodeIndex == indx) then
467  resultobj => this%currentNode%Value
468  return
469  end if
470  end do
Here is the caller graph for this function:

◆ get_node_by_index()

type(listnodetype) function, pointer listmodule::get_node_by_index ( class(listtype), intent(inout)  this,
integer(i4b), intent(in)  indx 
)
private

Definition at line 474 of file List.f90.

475  ! -- dummy
476  class(ListType), intent(inout) :: this
477  integer(I4B), intent(in) :: indx
478  ! result
479  type(ListNodeType), pointer :: resultnode
480  ! -- local
481  integer(I4B) :: i
482  !
483  ! -- Initialize
484  resultnode => null()
485  !
486  ! -- Ensure that this%currentNode is associated
487  if (this%currentNodeIndex == 0) then
488  if (associated(this%firstNode)) then
489  this%currentNode => this%firstNode
490  this%currentNodeIndex = 1
491  end if
492  end if
493  !
494  ! -- Check indx position relative to current node index
495  i = 0
496  if (indx < this%currentNodeIndex) then
497  ! Start at beginning of list
498  call this%Reset()
499  if (associated(this%firstNode)) then
500  this%currentNode => this%firstNode
501  this%currentNodeIndex = 1
502  i = 1
503  end if
504  else
505  i = this%currentNodeIndex
506  end if
507  if (i == 0) return
508  !
509  ! -- If current node is requested node,
510  ! assign pointer and return
511  if (i == indx) then
512  resultnode => this%currentNode
513  return
514  end if
515  !
516  ! -- Iterate from current node to requested node
517  do while (associated(this%currentNode%nextNode))
518  this%currentNode => this%currentNode%nextNode
519  this%currentNodeIndex = this%currentNodeIndex + 1
520  if (this%currentNodeIndex == indx) then
521  resultnode => this%currentNode
522  return
523  end if
524  end do

◆ getindex()

integer(i4b) function listmodule::getindex ( class(listtype), intent(inout), target  this,
class(*), pointer  obj 
)
private

Definition at line 196 of file List.f90.

197  class(ListType), target, intent(inout) :: this
198  class(*), pointer :: obj
199  integer(I4B) :: idx
200  ! local
201  integer(I4B) :: i
202  class(*), pointer :: obj_in_list
203 
204  idx = -1
205  do i = 1, this%Count()
206  obj_in_list => this%GetItem(i)
207  if (associated(obj, obj_in_list)) then
208  idx = i
209  exit
210  end if
211  end do
212 

◆ getitem()

class(*) function, pointer listmodule::getitem ( class(listnodetype), intent(inout)  this)
private

Definition at line 530 of file List.f90.

531  class(ListNodeType), intent(inout) :: this
532  class(*), pointer :: valueObject
533  valueobject => this%Value
Here is the caller graph for this function:

◆ getnextitem()

class(*) function, pointer listmodule::getnextitem ( class(listtype), intent(inout), target  this)
private

Definition at line 216 of file List.f90.

217  class(ListType), target, intent(inout) :: this
218  class(*), pointer :: resultobj
219  call this%Next()
220  resultobj => this%get_current_item()

◆ getpreviousitem()

class(*) function, pointer listmodule::getpreviousitem ( class(listtype), intent(inout), target  this)
private

Definition at line 224 of file List.f90.

225  class(ListType), target, intent(inout) :: this
226  class(*), pointer :: resultobj
227  call this%Previous()
228  resultobj => this%get_current_item()

◆ insertafter()

subroutine listmodule::insertafter ( class(listtype), intent(inout)  this,
class(*), intent(inout), pointer  objptr,
integer(i4b), intent(in)  indx 
)
private

Definition at line 232 of file List.f90.

233  ! -- dummy
234  class(ListType), intent(inout) :: this
235  class(*), pointer, intent(inout) :: objptr
236  integer(I4B), intent(in) :: indx
237  ! -- local
238  integer(I4B) :: numnodes
239  type(ListNodeType), pointer :: precedingNode => null()
240  type(ListNodeType), pointer :: followingNode => null()
241  type(ListNodeType), pointer :: newNode => null()
242  !
243  numnodes = this%Count()
244  if (indx >= numnodes) then
245  call this%Add(objptr)
246  else
247  precedingnode => this%get_node_by_index(indx)
248  if (associated(precedingnode%nextNode)) then
249  followingnode => precedingnode%nextNode
250  allocate (newnode)
251  newnode%Value => objptr
252  newnode%nextNode => followingnode
253  newnode%prevNode => precedingnode
254  precedingnode%nextNode => newnode
255  followingnode%prevNode => newnode
256  this%nodeCount = this%nodeCount + 1
257  else
258  call pstop(1, 'Programming error in ListType%insert_after')
259  end if
260  end if
261 
Here is the call graph for this function:

◆ insertbefore()

subroutine listmodule::insertbefore ( class(listtype), intent(inout)  this,
class(*), intent(inout), pointer  objptr,
type(listnodetype), intent(inout), pointer  targetNode 
)
private

Definition at line 265 of file List.f90.

266  ! -- dummy
267  class(ListType), intent(inout) :: this
268  class(*), pointer, intent(inout) :: objptr
269  type(ListNodeType), pointer, intent(inout) :: targetNode
270  ! -- local
271  type(ListNodeType), pointer :: newNode => null()
272  !
273  if (.not. associated(targetnode)) &
274  call pstop(1, 'Programming error in ListType%InsertBefore')
275  !
276  ! Allocate a new list node and point its Value member to the object
277  allocate (newnode)
278  newnode%Value => objptr
279  !
280  ! Do the insertion
281  newnode%nextNode => targetnode
282  if (associated(targetnode%prevNode)) then
283  ! Insert between two nodes
284  targetnode%prevNode%nextNode => newnode
285  newnode%prevNode => targetnode%prevNode
286  else
287  ! Insert before first node
288  this%firstNode => newnode
289  newnode%prevNode => null()
290  end if
291  targetnode%prevNode => newnode
292  this%nodeCount = this%nodeCount + 1
293 
Here is the call graph for this function:

◆ next()

subroutine listmodule::next ( class(listtype), intent(inout), target  this)
private

Definition at line 297 of file List.f90.

298  class(ListType), target, intent(inout) :: this
299 
300  if (this%currentNodeIndex == 0) then
301  if (associated(this%firstNode)) then
302  this%currentNode => this%firstNode
303  this%currentNodeIndex = 1
304  else
305  this%currentNode => null()
306  this%currentNodeIndex = 0
307  end if
308  else
309  if (associated(this%currentNode%nextNode)) then
310  this%currentNode => this%currentNode%nextNode
311  this%currentNodeIndex = this%currentNodeIndex + 1
312  else
313  this%currentNode => null()
314  this%currentNodeIndex = 0
315  end if
316  end if

◆ previous()

subroutine listmodule::previous ( class(listtype), intent(inout), target  this)
private

Definition at line 320 of file List.f90.

321  class(ListType), target, intent(inout) :: this
322  if (this%currentNodeIndex <= 1) then
323  call this%Reset()
324  else
325  this%currentNode => this%currentNode%prevNode
326  this%currentNodeIndex = this%currentNodeIndex - 1
327  end if

◆ remove_node_by_index()

subroutine listmodule::remove_node_by_index ( class(listtype), intent(inout)  this,
integer(i4b), intent(in)  i,
logical, intent(in)  destroyValue 
)
private

Definition at line 338 of file List.f90.

339  ! -- dummy
340  class(ListType), intent(inout) :: this
341  integer(I4B), intent(in) :: i
342  logical, intent(in) :: destroyValue
343  ! -- local
344  type(ListNodeType), pointer :: node
345  !
346  node => null()
347  node => this%get_node_by_index(i)
348  if (associated(node)) then
349  call this%remove_this_node(node, destroyvalue)
350  end if
351 
Here is the caller graph for this function:

◆ remove_this_node()

subroutine listmodule::remove_this_node ( class(listtype), intent(inout)  this,
type(listnodetype), intent(inout), pointer  node,
logical, intent(in)  destroyValue 
)
private

Definition at line 355 of file List.f90.

356  ! -- dummy
357  class(ListType), intent(inout) :: this
358  type(ListNodeType), pointer, intent(inout) :: node
359  logical, intent(in) :: destroyValue
360  ! -- local
361  !
362  logical :: first, last
363  !
364  first = .false.
365  last = .false.
366  if (associated(node)) then
367  if (associated(node%prevNode)) then
368  if (associated(node%nextNode)) then
369  node%nextNode%prevNode => node%prevNode
370  else
371  node%prevNode%nextNode => null()
372  this%lastNode => node%prevNode
373  end if
374  else
375  first = .true.
376  end if
377  if (associated(node%nextNode)) then
378  if (associated(node%prevNode)) then
379  node%prevNode%nextNode => node%nextNode
380  else
381  node%nextNode%prevNode => null()
382  this%firstNode => node%nextNode
383  end if
384  else
385  last = .true.
386  end if
387  if (destroyvalue) then
388  call node%DeallocValue(destroyvalue)
389  end if
390  deallocate (node)
391  this%nodeCount = this%nodeCount - 1
392  if (first .and. last) then
393  this%firstNode => null()
394  this%lastNode => null()
395  this%currentNode => null()
396  end if
397  call this%Reset()
398  end if
399 
Here is the caller graph for this function:

◆ reset()

subroutine listmodule::reset ( class(listtype), intent(inout), target  this)
private

Definition at line 331 of file List.f90.

332  class(ListType), target, intent(inout) :: this
333  this%currentNode => null()
334  this%currentNodeIndex = 0