OpenCMISS-Iron Internal API Documentation
linkedlist_routines.f90
Go to the documentation of this file.
1 
3 
4 #include "macros.h"
5 
6  USE base_routines
7  USE constants
8  USE kinds
10  implicit none
11 
12  private ! by default
13 
14  ! types
16  integer(intg) :: data
17  type(linkedlistitem),pointer :: next => null()
18  end type
19 
21  type(linkedlistitem),pointer :: root => null()
22  type(linkedlistitem),pointer :: last => null()
23  end type
24 
25  interface linkedlist_add
26  module procedure linkedlist_add_data
27  module procedure linkedlist_add_list
28  end interface
29 
30  ! public types
31  public :: linkedlistitem,linkedlist
32 
33  ! public subs
36 
37 contains
38 
39 ! -------------------------------------------------------------------
40 
42  SUBROUTINE linkedlist_add_data(list,data,ERR,ERROR,*)
43 
44  TYPE(linkedlist),INTENT(INOUT) :: list
45  INTEGER(INTG),INTENT(IN) :: data
46  INTEGER(INTG), INTENT(OUT) :: ERR
47  TYPE(varying_string), INTENT(OUT) :: ERROR
48  ! local variables
49  TYPE(linkedlistitem),pointer :: current
50 
51  enters("LinkedList_Add_Data",err,error,*999)
52 
53  if (associated(list%root)) then
54  ! add to the tail end (for now)
55  current => list%last
56  allocate(current%next)
57  current%next%data = data
58  list%last => current%next
59  else
60  allocate(list%root)
61  list%root%data = data
62  list%last => list%root
63  endif
64 
65  exits("LinkedList_Add_Data")
66  RETURN
67 999 errorsexits("LinkedList_Add_Data",err,error)
68  RETURN 1
69 
70  End SUBROUTINE linkedlist_add_data
71 
72 
73 ! -------------------------------------------------------------------
74 
76  Subroutine linkedlist_add_list(list,addlist,ERR,ERROR,*)
77  type(linkedlist),intent(inout) :: list
78  type(linkedlist),intent(in) :: addlist
79  INTEGER(INTG), INTENT(OUT) :: ERR
80  TYPE(varying_string), INTENT(OUT) :: ERROR
81  ! local variables
82  type(linkedlistitem),pointer :: current
83 
84  if (linkedlist_is_empty(addlist)) return
85 
86  current => addlist%root
87  do
88  call linkedlist_add_data(list,current%data,err,error,*999)
89  if (associated(current%next)) then
90  current => current%next
91  else
92  exit
93  endif
94  enddo
95 
96  exits("LinkedList_Add_List")
97  RETURN
98 999 errorsexits("LinkedList_Add_List",err,error)
99  RETURN 1
100 
101  End Subroutine linkedlist_add_list
102 
103 ! -------------------------------------------------------------------
104 
106  Subroutine linkedlist_remove_first(list,data,ERR,ERROR,*)
107  type(linkedlist),intent(inout) :: list
108  integer(intg),intent(out) :: data
109  INTEGER(INTG), INTENT(OUT) :: ERR
110  TYPE(varying_string), INTENT(OUT) :: ERROR
111  ! local variables
112  type(linkedlistitem),pointer :: next
113 
114  if (associated(list%root)) then
115  data = list%root%data
116  next => list%root%next
117  deallocate(list%root)
118  list%root => next
119  if (associated(list%root)) then
120  if (.not.associated(list%root%next)) list%last => list%root ! only one left
121  else
122  list%last => null()
123  endif
124  else
125  write(*,*) ">>> warning: linked list is empty and cannot remove first item"
126  endif
127 
128  End Subroutine linkedlist_remove_first
129 
130 ! -------------------------------------------------------------------
131 
133  Subroutine linkedlist_remove_last(list,data,ERR,ERROR,*)
134  type(linkedlist),intent(inout) :: list
135  integer(intg),intent(out) :: data
136  INTEGER(INTG), INTENT(OUT) :: ERR
137  TYPE(varying_string), INTENT(OUT) :: ERROR
138  ! local variables
139  type(linkedlistitem),pointer :: current
140 
141  if (.not.associated(list%root)) then
142  write(*,*) ">>> warning: linked list is empty and cannot remove last item"
143  return
144  endif
145  current => list%root
146 
147  do
148  if (associated(current%next)) then
149  if (associated(current%next%next)) then
150  current => current%next
151  else
152  ! next one is the last one
153  data = current%next%data
154  deallocate(current%next)
155  current%next => null()
156  list%last => current
157  exit
158  endif
159  else
160  ! there must be only one item in the list?
161  data = current%data
162  deallocate(list%root)
163  list%root => null()
164  list%last => null()
165  exit
166  endif
167  enddo
168 
169  End Subroutine linkedlist_remove_last
170 
171 ! -------------------------------------------------------------------
172 
174  Subroutine linkedlist_destroy(list,ERR,ERROR,*)
176  TYPE(linkedlist), INTENT(inout) :: list
177  INTEGER(INTG), INTENT(OUT) :: ERR
178  TYPE(varying_string), INTENT(OUT) :: ERROR
179  ! local variables
180  TYPE(linkedlistitem), POINTER :: current,next
181 
182  if (.not.associated(list%root)) return
183 
184  current => list%root
185  do
186  if (associated(current%next)) then
187  next => current%next
188  deallocate(current)
189  current => next
190  else
191  deallocate(current)
192  exit
193  endif
194  enddo
195 
196  list%root => null()
197  list%last => null()
198 
199  End SUBROUTINE linkedlist_destroy
200 
201 ! -------------------------------------------------------------------
202 
204  Function linkedlist_is_empty(list)
205  type(linkedlist),intent(in) :: list
206  logical :: LinkedList_is_Empty
207 
208  linkedlist_is_empty = .true.
209  if (associated(list%root)) linkedlist_is_empty = .false.
210 
211  End Function linkedlist_is_empty
212 
213 ! -------------------------------------------------------------------
214 
216  Subroutine linkedlist_to_array(list,array,ERR,ERROR,*)
217  type(linkedlist),intent(in) :: list
218  integer(INTG),allocatable,intent(out) :: array(:)
219  INTEGER(INTG), INTENT(OUT) :: ERR
220  TYPE(varying_string), INTENT(OUT) :: ERROR
221  ! local variables
222  integer(INTG) :: i,n
223  type(linkedlistitem),pointer :: current
224 
225  ! return zero-size array if list is empty
226  if (linkedlist_is_empty(list)) then
227  allocate(array(0))
228  return
229  endif
230 
231  ! first traversing to find size
232  current => list%root
233  n=1
234  do
235  if (associated(current%next)) then
236  n=n+1
237  current => current%next
238  else
239  exit
240  endif
241  enddo
242 
243  ! copy to array
244  if (allocated(array)) deallocate(array)
245  allocate(array(n),stat=err)
246  !IF (ERR/=0) CALL ...
247  current => list%root
248  do i=1,n
249  array(i)=current%data
250  current => current%next
251  enddo
252 
253  End Subroutine linkedlist_to_array
254 
255 End Module linkedlist_routines
subroutine, public enters(NAME, ERR, ERROR,)
Records the entry into the named procedure and initialises the error code.
subroutine, public linkedlist_destroy(list, ERR, ERROR,)
will delete and deallocate all items
subroutine, public linkedlist_remove_last(list, data, ERR, ERROR,)
removes the first item from list and returns its value in data
subroutine, public linkedlist_to_array(list, array, ERR, ERROR,)
copies out the data to an allocatable array
This module provides an iso_varying_string module, conformant to the API specified in ISO/IEC 1539-2:...
Only for integer data type for now.
This module contains all program wide constants.
Definition: constants.f90:45
subroutine, public exits(NAME)
Records the exit out of the named procedure.
subroutine linkedlist_add_list(list, addlist, ERR, ERROR,)
adds all data from one list to another
This module contains all the low-level base routines e.g., all debug, control, and low-level communic...
subroutine, public linkedlist_remove_first(list, data, ERR, ERROR,)
removes the first item from list and returns its value in data
subroutine linkedlist_add_data(list, data, ERR, ERROR,)
initialises or adds a piece of data to list
logical function, public linkedlist_is_empty(list)
returns true if the list is empty
This module contains all kind definitions.
Definition: kinds.f90:45