17 character(len=20),
public :: name =
' '
21 integer(I4B),
private :: currentnodeindex = 0
22 integer(I4B),
private :: nodecount = 0
26 procedure,
public ::
add
52 function isequaliface(obj1, obj2)
result(isEqual)
53 class(*),
pointer :: obj1, obj2
68 subroutine add(this, objptr)
70 class(
listtype),
intent(inout) :: this
71 class(*),
pointer,
intent(inout) :: objptr
73 if (.not.
associated(this%firstNode))
then
74 allocate (this%firstNode)
75 this%firstNode%Value => objptr
76 this%firstNode%prevNode => null()
77 this%lastNode => this%firstNode
79 allocate (this%lastNode%nextNode)
80 this%lastNode%nextNode%prevNode => this%lastNode
81 this%lastNode%nextNode%value => objptr
82 this%lastNode => this%lastNode%nextNode
84 this%nodeCount = this%nodeCount + 1
91 logical,
intent(in),
optional :: destroy
93 logical :: destroyLocal
97 destroylocal = .false.
98 if (
present(destroy))
then
99 destroylocal = destroy
102 if (.not.
associated(this%firstNode))
return
106 nullify (this%lastNode)
107 nullify (this%currentNode)
109 current => this%firstNode
110 do while (
associated(current))
112 next => current%nextNode
114 call current%DeallocValue(destroylocal)
117 this%firstNode => next
118 this%nodeCount = this%nodeCount - 1
129 integer(I4B) ::
count
131 count = this%nodeCount
136 class(
listtype),
intent(inout) :: this
137 class(*),
pointer :: obj
138 procedure(isequaliface),
pointer,
intent(in),
optional :: isequal
144 current => this%firstNode
145 do while (
associated(current))
146 if (
present(isequal))
then
147 if (isequal(current%Value, obj))
then
152 if (
associated(current%Value, obj))
then
159 current => current%nextNode
167 class(
listtype),
target,
intent(inout) :: this
173 if (
associated(fromnode))
then
175 if (
associated(fromnode%nextNode))
then
176 this%firstNode => fromnode%nextNode
178 this%firstNode => null()
182 do while (
associated(current))
183 prev => current%prevNode
184 call current%DeallocValue(.true.)
186 this%nodeCount = this%nodeCount - 1
196 class(
listtype),
target,
intent(inout) :: this
197 class(*),
pointer :: obj
201 class(*),
pointer :: obj_in_list
204 do i = 1, this%Count()
205 obj_in_list => this%GetItem(i)
206 if (
associated(obj, obj_in_list))
then
216 class(
listtype),
target,
intent(inout) :: this
217 class(*),
pointer :: resultobj
219 resultobj => this%get_current_item()
224 class(
listtype),
target,
intent(inout) :: this
225 class(*),
pointer :: resultobj
227 resultobj => this%get_current_item()
233 class(
listtype),
intent(inout) :: this
234 class(*),
pointer,
intent(inout) :: objptr
235 integer(I4B),
intent(in) :: indx
237 integer(I4B) :: numnodes
242 numnodes = this%Count()
243 if (indx >= numnodes)
then
244 call this%Add(objptr)
246 precedingnode => this%get_node_by_index(indx)
247 if (
associated(precedingnode%nextNode))
then
248 followingnode => precedingnode%nextNode
250 newnode%Value => objptr
251 newnode%nextNode => followingnode
252 newnode%prevNode => precedingnode
253 precedingnode%nextNode => newnode
254 followingnode%prevNode => newnode
255 this%nodeCount = this%nodeCount + 1
257 call pstop(1,
'Programming error in ListType%insert_after')
266 class(
listtype),
intent(inout) :: this
267 class(*),
pointer,
intent(inout) :: objptr
268 type(
listnodetype),
pointer,
intent(inout) :: targetNode
272 if (.not.
associated(targetnode)) &
273 call pstop(1,
'Programming error in ListType%InsertBefore')
277 newnode%Value => objptr
280 newnode%nextNode => targetnode
281 if (
associated(targetnode%prevNode))
then
283 targetnode%prevNode%nextNode => newnode
284 newnode%prevNode => targetnode%prevNode
287 this%firstNode => newnode
288 newnode%prevNode => null()
290 targetnode%prevNode => newnode
291 this%nodeCount = this%nodeCount + 1
297 class(
listtype),
target,
intent(inout) :: this
299 if (this%currentNodeIndex == 0)
then
300 if (
associated(this%firstNode))
then
301 this%currentNode => this%firstNode
302 this%currentNodeIndex = 1
304 this%currentNode => null()
305 this%currentNodeIndex = 0
308 if (
associated(this%currentNode%nextNode))
then
309 this%currentNode => this%currentNode%nextNode
310 this%currentNodeIndex = this%currentNodeIndex + 1
312 this%currentNode => null()
313 this%currentNodeIndex = 0
320 class(
listtype),
target,
intent(inout) :: this
321 if (this%currentNodeIndex <= 1)
then
324 this%currentNode => this%currentNode%prevNode
325 this%currentNodeIndex = this%currentNodeIndex - 1
331 class(
listtype),
target,
intent(inout) :: this
332 this%currentNode => null()
333 this%currentNodeIndex = 0
339 class(
listtype),
intent(inout) :: this
340 integer(I4B),
intent(in) :: i
341 logical,
intent(in) :: destroyValue
346 node => this%get_node_by_index(i)
347 if (
associated(node))
then
348 call this%remove_this_node(node, destroyvalue)
356 class(
listtype),
intent(inout) :: this
358 logical,
intent(in) :: destroyValue
361 logical :: first, last
365 if (
associated(node))
then
366 if (
associated(node%prevNode))
then
367 if (
associated(node%nextNode))
then
368 node%nextNode%prevNode => node%prevNode
370 node%prevNode%nextNode => null()
371 this%lastNode => node%prevNode
376 if (
associated(node%nextNode))
then
377 if (
associated(node%prevNode))
then
378 node%prevNode%nextNode => node%nextNode
380 node%nextNode%prevNode => null()
381 this%firstNode => node%nextNode
386 if (destroyvalue)
then
387 call node%DeallocValue(destroyvalue)
390 this%nodeCount = this%nodeCount - 1
391 if (first .and. last)
then
392 this%firstNode => null()
393 this%lastNode => null()
394 this%currentNode => null()
405 class(
listtype),
target,
intent(inout) :: this
407 class(*),
pointer :: resultobj
410 if (
associated(this%currentNode))
then
411 resultobj => this%currentNode%Value
418 class(
listtype),
intent(inout) :: this
419 integer(I4B),
intent(in) :: indx
421 class(*),
pointer :: resultobj
429 if (.not.
associated(this%currentNode))
then
430 this%currentNodeIndex = 0
432 if (this%currentNodeIndex == 0)
then
433 if (
associated(this%firstNode))
then
434 this%currentNode => this%firstNode
435 this%currentNodeIndex = 1
441 if (indx < this%currentNodeIndex)
then
444 if (
associated(this%firstNode))
then
445 this%currentNode => this%firstNode
446 this%currentNodeIndex = 1
450 i = this%currentNodeIndex
457 resultobj => this%currentNode%Value
462 do while (
associated(this%currentNode%nextNode))
463 this%currentNode => this%currentNode%nextNode
464 this%currentNodeIndex = this%currentNodeIndex + 1
465 if (this%currentNodeIndex == indx)
then
466 resultobj => this%currentNode%Value
475 class(
listtype),
intent(inout) :: this
476 integer(I4B),
intent(in) :: indx
486 if (this%currentNodeIndex == 0)
then
487 if (
associated(this%firstNode))
then
488 this%currentNode => this%firstNode
489 this%currentNodeIndex = 1
495 if (indx < this%currentNodeIndex)
then
498 if (
associated(this%firstNode))
then
499 this%currentNode => this%firstNode
500 this%currentNodeIndex = 1
504 i = this%currentNodeIndex
511 resultnode => this%currentNode
516 do while (
associated(this%currentNode%nextNode))
517 this%currentNode => this%currentNode%nextNode
518 this%currentNodeIndex = this%currentNodeIndex + 1
519 if (this%currentNodeIndex == indx)
then
520 resultnode => this%currentNode
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.
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 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.
class(iteratortype) function, allocatable iterator(this)
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.
An iterator used to iterate through a List.
A generic heterogeneous doubly-linked list.