EIRAM
atomic and molecular data in form of polynomial fits
linkedlist.f90
Go to the documentation of this file.
1 ! linkedlist.f90 --
2 ! Include file for defining linked lists where each element holds
3 ! the same kind of data
4 !
5 ! See the example/test program for the way to use this
6 !
7 ! Note:
8 ! You should only use pointer variables of this type, no
9 ! ordinary variables, as sometimes the memory pointed to
10 ! will be deallocated. The subroutines and functions
11 ! are designed to minimize mistakes (for instance: using
12 ! = instead of =>)
13 !
14 ! $Id: linkedlist.f90,v 1.2 2006/03/26 19:03:53 arjenmarkus Exp $
15 !
16 ! Define the linked-list data type
17 !
18 type linked_list
19  type(linked_list), pointer :: next
20  type(list_data) :: data
21 end type linked_list
22 
23 !
24 ! define a private (!) interface to prevent
25 ! mistakes with ordinary assignment
26 !
27 interface assignment(=)
28  module procedure list_assign
29 end interface
30 private :: list_assign
31 
32 !
33 ! Define the subroutines and functions
34 !
35 contains
36 
37 ! list_assign
38 ! Subroutine to prevent errors with assignment
39 ! Arguments:
40 ! list_left List on the left-hand side
41 ! list_right List on the right-hand side
42 !
43 subroutine list_assign( list_left, list_right )
44  type(linked_list), INTENT(OUT) :: list_left
45  type(linked_list), INTENT(IN) :: list_right
46  !type(LINKED_LIST), pointer :: list_left
47  !type(LINKED_LIST), pointer :: list_right
48 
49  !
50  ! Note the order!
51  !
52  stop 'Error: ordinary assignment for lists'
53  list_left%next => null()
54 end subroutine list_assign
55 
56 ! list_create --
57 ! Create and initialise a list
58 ! Arguments:
59 ! list Pointer to new linked list
60 ! data The data for the first element
61 ! Note:
62 ! This version assumes a shallow copy is enough
63 ! (that is, there are no pointers within the data
64 ! to be stored)
65 ! It also assumes the argument list does not already
66 ! refer to a list. Use list_destroy first to
67 ! destroy up an old list.
68 !
69 subroutine list_create( list, data )
70  type(linked_list), pointer :: list
71  type(list_data), intent(in) :: data
72 
73  allocate( list )
74  list%next => null()
75  list%data = data
76 end subroutine list_create
77 
78 ! list_destroy --
79 ! Destroy an entire list
80 ! Arguments:
81 ! list Pointer to the list to be destroyed
82 ! Note:
83 ! This version assumes that there are no
84 ! pointers within the data that need deallocation
85 !
86 subroutine list_destroy( list )
87  type(linked_list), pointer :: list
88 
89  type(linked_list), pointer :: current
90  type(linked_list), pointer :: next
91 
92  current => list
93  do while ( associated(current%next) )
94  next => current%next
95  deallocate( current )
96  current => next
97  enddo
98 end subroutine list_destroy
99 
100 ! list_count --
101 ! Count the number of items in the list
102 ! Arguments:
103 ! list Pointer to the list
104 !
105 integer function list_count( list )
106  type(linked_list), pointer :: list
107 
108  type(linked_list), pointer :: current
109  type(linked_list), pointer :: next
110 
111  if ( associated(list) ) then
112  list_count = 1
113  current => list
114  do while ( associated(current%next) )
115  current => current%next
116  list_count = list_count + 1
117  enddo
118  else
119  list_count = 0
120  endif
121 end function list_count
122 
123 ! list_next
124 ! Return the next element (if any)
125 ! Arguments:
126 ! elem Element in the linked list
127 ! Result:
128 !
129 function list_next( elem ) result(next)
130  type(linked_list), pointer :: elem
131  type(linked_list), pointer :: next
132 
133  next => elem%next
134 
135 end function list_next
136 
137 ! list_insert
138 ! Insert a new element
139 ! Arguments:
140 ! elem Element in the linked list after
141 ! which to insert the new element
142 ! data The data for the new element
143 !
144 subroutine list_insert( elem, data )
145  type(linked_list), pointer :: elem
146  type(list_data), intent(in) :: data
147 
148  type(linked_list), pointer :: next
149 
150  allocate(next)
151 
152  next%next => elem%next
153  elem%next => next
154  next%data = data
155 end subroutine list_insert
156 
157 ! list_insert_head
158 ! Insert a new element before the first element
159 ! Arguments:
160 ! list Start of the list
161 ! data The data for the new element
162 !
163 subroutine list_insert_head( list, data )
164  type(linked_list), pointer :: list
165  type(list_data), intent(in) :: data
166 
167  type(linked_list), pointer :: elem
168 
169  allocate(elem)
170  elem%data = data
171 
172  elem%next => list
173  list => elem
174 end subroutine list_insert_head
175 
176 ! list_delete_element
177 ! Delete an element from the list
178 ! Arguments:
179 ! list Header of the list
180 ! elem Element in the linked list to be
181 ! removed
182 !
183 subroutine list_delete_element( list, elem )
184  type(linked_list), pointer :: list
185  type(linked_list), pointer :: elem
186 
187  type(linked_list), pointer :: current
188  type(linked_list), pointer :: prev
189 
190  if ( associated(list,elem) ) then
191  list => elem%next
192  deallocate( elem )
193  else
194  current => list
195  prev => list
196  do while ( associated(current) )
197  if ( associated(current,elem) ) then
198  prev%next => current%next
199  deallocate( current ) ! Is also "elem"
200  exit
201  endif
202  prev => current
203  current => current%next
204  enddo
205  endif
206 ! allocate(next)
207 !
208 ! next%next => elem%next
209 ! elem%next => next
210 ! next%data = data
211 end subroutine list_delete_element
212 
213 ! list_get_data
214 ! Get the data stored with a list element
215 ! Arguments:
216 ! elem Element in the linked list
217 !
218 function list_get_data( elem ) result(data)
219  type(linked_list), pointer :: elem
220 
221  type(list_data) :: data
222 
223  data = elem%data
224 end function list_get_data
225 
226 ! list_put_data
227 ! Store new data with a list element
228 ! Arguments:
229 ! elem Element in the linked list
230 ! data The data to be stored
231 !
232 subroutine list_put_data( elem, data )
233  type(linked_list), pointer :: elem
234  type(list_data), intent(in) :: data
235 
236  elem%data = data
237 end subroutine list_put_data
238