13 character(len=20),
public :: name =
' '
17 integer(I4B),
private :: currentnodeindex = 0
18 integer(I4B),
private :: nodecount = 0
21 procedure,
public ::
add
51 class(*),
pointer,
private ::
Value => null()
60 function isequaliface(obj1, obj2)
result(isEqual)
61 class(*),
pointer :: obj1, obj2
69 subroutine add(this, objptr)
71 class(
listtype),
intent(inout) :: this
72 class(*),
pointer,
intent(inout) :: objptr
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
80 allocate (this%lastNode%nextNode)
81 this%lastNode%nextNode%prevNode => this%lastNode
82 this%lastNode%nextNode%value => objptr
83 this%lastNode => this%lastNode%nextNode
85 this%nodeCount = this%nodeCount + 1
92 logical,
intent(in),
optional :: destroy
94 logical :: destroyLocal
98 destroylocal = .false.
99 if (
present(destroy))
then
100 destroylocal = destroy
103 if (.not.
associated(this%firstNode))
return
107 nullify (this%lastNode)
108 nullify (this%currentNode)
110 current => this%firstNode
111 do while (
associated(current))
113 next => current%nextNode
115 call current%DeallocValue(destroylocal)
118 this%firstNode => next
119 this%nodeCount = this%nodeCount - 1
130 integer(I4B) ::
count
132 count = this%nodeCount
137 class(
listtype),
intent(inout) :: this
138 class(*),
pointer :: obj
139 procedure(isequaliface),
pointer,
intent(in),
optional :: isequal
145 current => this%firstNode
146 do while (
associated(current))
147 if (
present(isequal))
then
148 if (isequal(current%Value, obj))
then
153 if (
associated(current%Value, obj))
then
160 current => current%nextNode
168 class(
listtype),
target,
intent(inout) :: this
174 if (
associated(fromnode))
then
176 if (
associated(fromnode%nextNode))
then
177 this%firstNode => fromnode%nextNode
179 this%firstNode => null()
183 do while (
associated(current))
184 prev => current%prevNode
185 call current%DeallocValue(.true.)
187 this%nodeCount = this%nodeCount - 1
197 class(
listtype),
target,
intent(inout) :: this
198 class(*),
pointer :: obj
202 class(*),
pointer :: obj_in_list
205 do i = 1, this%Count()
206 obj_in_list => this%GetItem(i)
207 if (
associated(obj, obj_in_list))
then
217 class(
listtype),
target,
intent(inout) :: this
218 class(*),
pointer :: resultobj
220 resultobj => this%get_current_item()
225 class(
listtype),
target,
intent(inout) :: this
226 class(*),
pointer :: resultobj
228 resultobj => this%get_current_item()
234 class(
listtype),
intent(inout) :: this
235 class(*),
pointer,
intent(inout) :: objptr
236 integer(I4B),
intent(in) :: indx
238 integer(I4B) :: numnodes
243 numnodes = this%Count()
244 if (indx >= numnodes)
then
245 call this%Add(objptr)
247 precedingnode => this%get_node_by_index(indx)
248 if (
associated(precedingnode%nextNode))
then
249 followingnode => precedingnode%nextNode
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
258 call pstop(1,
'Programming error in ListType%insert_after')
267 class(
listtype),
intent(inout) :: this
268 class(*),
pointer,
intent(inout) :: objptr
269 type(
listnodetype),
pointer,
intent(inout) :: targetNode
273 if (.not.
associated(targetnode)) &
274 call pstop(1,
'Programming error in ListType%InsertBefore')
278 newnode%Value => objptr
281 newnode%nextNode => targetnode
282 if (
associated(targetnode%prevNode))
then
284 targetnode%prevNode%nextNode => newnode
285 newnode%prevNode => targetnode%prevNode
288 this%firstNode => newnode
289 newnode%prevNode => null()
291 targetnode%prevNode => newnode
292 this%nodeCount = this%nodeCount + 1
298 class(
listtype),
target,
intent(inout) :: this
300 if (this%currentNodeIndex == 0)
then
301 if (
associated(this%firstNode))
then
302 this%currentNode => this%firstNode
303 this%currentNodeIndex = 1
305 this%currentNode => null()
306 this%currentNodeIndex = 0
309 if (
associated(this%currentNode%nextNode))
then
310 this%currentNode => this%currentNode%nextNode
311 this%currentNodeIndex = this%currentNodeIndex + 1
313 this%currentNode => null()
314 this%currentNodeIndex = 0
321 class(
listtype),
target,
intent(inout) :: this
322 if (this%currentNodeIndex <= 1)
then
325 this%currentNode => this%currentNode%prevNode
326 this%currentNodeIndex = this%currentNodeIndex - 1
332 class(
listtype),
target,
intent(inout) :: this
333 this%currentNode => null()
334 this%currentNodeIndex = 0
340 class(
listtype),
intent(inout) :: this
341 integer(I4B),
intent(in) :: i
342 logical,
intent(in) :: destroyValue
347 node => this%get_node_by_index(i)
348 if (
associated(node))
then
349 call this%remove_this_node(node, destroyvalue)
357 class(
listtype),
intent(inout) :: this
359 logical,
intent(in) :: destroyValue
362 logical :: first, last
366 if (
associated(node))
then
367 if (
associated(node%prevNode))
then
368 if (
associated(node%nextNode))
then
369 node%nextNode%prevNode => node%prevNode
371 node%prevNode%nextNode => null()
372 this%lastNode => node%prevNode
377 if (
associated(node%nextNode))
then
378 if (
associated(node%prevNode))
then
379 node%prevNode%nextNode => node%nextNode
381 node%nextNode%prevNode => null()
382 this%firstNode => node%nextNode
387 if (destroyvalue)
then
388 call node%DeallocValue(destroyvalue)
391 this%nodeCount = this%nodeCount - 1
392 if (first .and. last)
then
393 this%firstNode => null()
394 this%lastNode => null()
395 this%currentNode => null()
406 class(
listtype),
target,
intent(inout) :: this
408 class(*),
pointer :: resultobj
411 if (
associated(this%currentNode))
then
412 resultobj => this%currentNode%Value
419 class(
listtype),
intent(inout) :: this
420 integer(I4B),
intent(in) :: indx
422 class(*),
pointer :: resultobj
430 if (.not.
associated(this%currentNode))
then
431 this%currentNodeIndex = 0
433 if (this%currentNodeIndex == 0)
then
434 if (
associated(this%firstNode))
then
435 this%currentNode => this%firstNode
436 this%currentNodeIndex = 1
442 if (indx < this%currentNodeIndex)
then
445 if (
associated(this%firstNode))
then
446 this%currentNode => this%firstNode
447 this%currentNodeIndex = 1
451 i = this%currentNodeIndex
458 resultobj => this%currentNode%Value
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
476 class(
listtype),
intent(inout) :: this
477 integer(I4B),
intent(in) :: indx
487 if (this%currentNodeIndex == 0)
then
488 if (
associated(this%firstNode))
then
489 this%currentNode => this%firstNode
490 this%currentNodeIndex = 1
496 if (indx < this%currentNodeIndex)
then
499 if (
associated(this%firstNode))
then
500 this%currentNode => this%firstNode
501 this%currentNodeIndex = 1
505 i = this%currentNodeIndex
512 resultnode => this%currentNode
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
532 class(*),
pointer :: valueobject
533 valueobject => this%Value
539 logical,
intent(in),
optional :: destroy
541 if (
associated(this%Value))
then
542 if (
present(destroy))
then
544 deallocate (this%Value)
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
subroutine pstop(status, message)
Stop the program, optionally specifying an error status code.
This module defines variable data types.
subroutine deallocvalue(this, destroy)
Nullify (optionally deallocating) this node's value.
integer(i4b) function count(this)
Return number of nodes in list.
subroutine insertbefore(this, objptr, targetNode)
Insert the given item before the given node.
subroutine remove_node_by_index(this, i, destroyValue)
Remove the node at the given index, optionally destroying its value.
subroutine reset(this)
Reset the list's current node pointer and index.
class(*) function, pointer getitem(this)
Return a pointer to this node's value.
class(*) function, pointer getpreviousitem(this)
Get the previous item in the list.
class(*) function, pointer get_item_by_index(this, indx)
Get a pointer to the item at the given index.
logical function containsobject(this, obj, isEqual)
Determine whether the list contains the given object.
subroutine add(this, objptr)
Append the given item to the list.
subroutine clear(this, destroy)
Deallocate all items in list.
class(*) function, pointer get_current_item(this)
Get a pointer to the item at the current node.
subroutine previous(this)
Move the list's current node pointer and index one node backwards.
subroutine next(this)
Move the list's current node pointer and index one node forwards.
integer(i4b) function getindex(this, obj)
Get the index of the given item in the list.
class(*) function, pointer getnextitem(this)
Get the next item in the list.
subroutine deallocatebackward(this, fromNode)
Deallocate fromNode and all previous nodes, and reassign firstNode.
type(listnodetype) function, pointer get_node_by_index(this, indx)
Get the node at the given index.
subroutine remove_this_node(this, node, destroyValue)
Remove the given node, optionally destroying its value.
subroutine insertafter(this, objptr, indx)
Insert the given item after the given index.
A generic heterogeneous doubly-linked list.