(git:d2a9ebd)
Loading...
Searching...
No Matches
list_callstackentry.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief An array-based list which grows on demand.
10!> When the internal array is full, a new array of twice the size will be
11!> allocated and the items are copied over.
12!>
13!> This list can also be used as a stack.
14!> Have look at list_push(), list_pop() and list_peek().
15!> \par History
16!> 12.2012 first version [ole]
17!> \author Ole Schuett
18! **************************************************************************************************
19
22
23
24#include "../base/base_uses.f90"
25 IMPLICIT NONE
26 PRIVATE
27
32
33!this is an internal type
34 TYPE private_item_type_callstackentry
35 PRIVATE
36 TYPE(callstack_entry_type) :: value = callstack_entry_type()
37 END TYPE private_item_type_callstackentry
38
39!this is an internal type
40 TYPE private_item_p_type_callstackentry
41 PRIVATE
42 TYPE(private_item_type_callstackentry), POINTER :: p => null()
43 END TYPE private_item_p_type_callstackentry
44
45! this is the public type, which holds a list-instance
47 PRIVATE
48 TYPE(private_item_p_type_callstackentry), DIMENSION(:), POINTER :: arr => null()
49 INTEGER :: size = -1
51
52 CONTAINS
53
54! **************************************************************************************************
55!> \brief Test if the given list has been initialized.
56!> \param list ...
57!> \return ...
58!> \par History
59!> 12.2012 created [ole]
60!> \author Ole Schuett
61! **************************************************************************************************
62 FUNCTION list_callstackentry_isready(list) RESULT(res)
63 TYPE(list_callstackentry_type), intent(in) :: list
64 LOGICAL :: res
65 res = ASSOCIATED(list%arr)
67
68! **************************************************************************************************
69!> \brief Allocates the internal data-structures of the given list.
70!> This has to be called before any of the other routines.
71!> For deallocation call list_[valuetype]_destroy.
72!> \param list ...
73!> \param initial_capacity The initial size of the internal array (default=11).
74!> \par History
75!> 12.2012 created [ole]
76!> \author Ole Schuett
77! **************************************************************************************************
78 SUBROUTINE list_callstackentry_init(list, initial_capacity)
79 TYPE(list_callstackentry_type), intent(inout) :: list
80 INTEGER, INTENT(in), OPTIONAL :: initial_capacity
81 INTEGER :: stat
82 INTEGER :: initial_capacity_
83
84 initial_capacity_ = 11
85 If (PRESENT(initial_capacity)) initial_capacity_ = initial_capacity
86
87 IF (initial_capacity_ < 0) THEN
88 cpabort("list_callstackentry_create: initial_capacity < 0")
89 END IF
90
91 IF (ASSOCIATED(list%arr)) THEN
92 cpabort("list_callstackentry_create: list is already initialized.")
93 END IF
94
95 ALLOCATE (list%arr(initial_capacity_), stat=stat)
96 IF (stat /= 0) THEN
97 cpabort("list_callstackentry_init: allocation failed")
98 END IF
99
100 list%size = 0
101 END SUBROUTINE list_callstackentry_init
102
103! **************************************************************************************************
104!> \brief Deallocated the internal data-structures of the given list.
105!> Caution: If the stored values are pointers, their targets will
106!> not get deallocated by this routine.
107!> \param list ...
108!> \par History
109!> 12.2012 created [ole]
110!> \author Ole Schuett
111! **************************************************************************************************
113 TYPE(list_callstackentry_type), intent(inout) :: list
114 INTEGER :: i
115 IF (.not. ASSOCIATED(list%arr)) THEN
116 cpabort("list_callstackentry_destroy: list is not initialized.")
117 END IF
118
119 do i = 1, list%size
120 deallocate (list%arr(i)%p)
121 end do
122 deallocate (list%arr)
123 list%size = -1
124 END SUBROUTINE list_callstackentry_destroy
125
126! **************************************************************************************************
127!> \brief Assings the given value to the given position in the list.
128!> Thereby, the former value at that position gets overwritten.
129!> If the position is out of bounds, the program stops.
130!> \param list ...
131!> \param value ...
132!> \param pos Position in the list - musst fulfill 0 < pos < list_size+1.
133!> \par History
134!> 12.2012 created [ole]
135!> \author Ole Schuett
136! **************************************************************************************************
137 SUBROUTINE list_callstackentry_set(list, value, pos)
138 TYPE(list_callstackentry_type), intent(inout) :: list
139 TYPE(callstack_entry_type), intent(in) :: value
140 INTEGER, intent(in) :: pos
141 IF (.not. ASSOCIATED(list%arr)) THEN
142 cpabort("list_callstackentry_set: list is not initialized.")
143 END IF
144 IF (pos < 1) THEN
145 cpabort("list_callstackentry_set: pos < 1")
146 END IF
147 IF (pos > list%size) THEN
148 cpabort("list_callstackentry_set: pos > size")
149 END IF
150 list%arr(pos)%p%value =value
151 END SUBROUTINE list_callstackentry_set
152
153! **************************************************************************************************
154!> \brief Appends the given value at the end of the list.
155!> \param list ...
156!> \param value ...
157!> \par History
158!> 12.2012 created [ole]
159!> \author Ole Schuett
160! **************************************************************************************************
161 SUBROUTINE list_callstackentry_push(list, value)
162 TYPE(list_callstackentry_type), intent(inout) :: list
163 TYPE(callstack_entry_type), intent(in) :: value
164 INTEGER :: stat
165
166 IF (.not. ASSOCIATED(list%arr)) THEN
167 cpabort("list_callstackentry_push: list is not initialized.")
168 END IF
169 IF (list%size == size(list%arr)) THEN
170 CALL change_capacity_callstackentry (list, 2*size(list%arr) + 1)
171 END IF
172
173 list%size = list%size + 1
174 ALLOCATE (list%arr(list%size)%p, stat=stat)
175 IF (stat /= 0) THEN
176 cpabort("list_callstackentry_push: allocation failed")
177 END IF
178 list%arr(list%size)%p%value =value
179 END SUBROUTINE list_callstackentry_push
180
181! **************************************************************************************************
182!> \brief Inserts the given value at the givenn position within the list.
183!> Values which lay behind the insertion-position move one position up.
184!> \param list ...
185!> \param value ...
186!> \param pos Position in the list - musst fulfill 0 < pos < list_size+2 .
187!> \par History
188!> 12.2012 created [ole]
189!> \author Ole Schuett
190! **************************************************************************************************
191 SUBROUTINE list_callstackentry_insert(list, value, pos)
192 TYPE(list_callstackentry_type), intent(inout) :: list
193 TYPE(callstack_entry_type), intent(in) :: value
194 INTEGER, intent(in) :: pos
195 INTEGER :: i, stat
196
197 IF (.not. ASSOCIATED(list%arr)) THEN
198 cpabort("list_callstackentry_insert: list is not initialized.")
199 END IF
200 IF (pos < 1) THEN
201 cpabort("list_callstackentry_insert: pos < 1")
202 END IF
203 IF (pos > list%size + 1) THEN
204 cpabort("list_callstackentry_insert: pos > size+1")
205 END IF
206
207 if (list%size == size(list%arr)) THEN
208 call change_capacity_callstackentry (list, 2*size(list%arr) + 1)
209 END IF
210
211 list%size = list%size + 1
212 do i = list%size, pos + 1, -1
213 list%arr(i)%p => list%arr(i - 1)%p
214 end do
215
216 ALLOCATE (list%arr(pos)%p, stat=stat)
217 IF (stat /= 0) THEN
218 cpabort("list_callstackentry_insert: allocation failed.")
219 END IF
220 list%arr(pos)%p%value =value
221 END SUBROUTINE list_callstackentry_insert
222
223! **************************************************************************************************
224!> \brief Returns the last element in the list.
225!> Is equivalent to: list_callstackentry_get(list, list_callstackentry_size(list))
226!> \param list ...
227!> \return ...
228!> \par History
229!> 12.2012 created [ole]
230!> \author Ole Schuett
231! **************************************************************************************************
232 FUNCTION list_callstackentry_peek(list) RESULT(value)
233 TYPE(list_callstackentry_type), intent(inout) :: list
234 TYPE(callstack_entry_type) :: value
235
236 IF (.not. ASSOCIATED(list%arr)) THEN
237 cpabort("list_callstackentry_peek: list is not initialized.")
238 END IF
239 IF (list%size < 1) THEN
240 cpabort("list_callstackentry_peek: list is empty.")
241 END IF
242
243 value =list%arr(list%size)%p%value
244 END FUNCTION list_callstackentry_peek
245
246! **************************************************************************************************
247!> \brief Returns the last element in the list and removes it.
248!> Is equivialent to:
249!> value = list_callstackentry_get(list, list_callstackentry_size(list))
250!> call list_callstackentry_del(list, list_callstackentry_size(list))
251!>
252!> \param list ...
253!> \return ...
254!> \par History
255!> 12.2012 created [ole]
256!> \author Ole Schuett
257! **************************************************************************************************
258 FUNCTION list_callstackentry_pop(list) RESULT(value)
259 TYPE(list_callstackentry_type), intent(inout) :: list
260 TYPE(callstack_entry_type) :: value
261
262 IF (.NOT. ASSOCIATED(list%arr)) THEN
263 cpabort("list_callstackentry_pop: list is not initialized.")
264 END IF
265 IF (list%size < 1) THEN
266 cpabort("list_callstackentry_pop: list is empty.")
267 END IF
268
269 value =list%arr(list%size)%p%value
270 deallocate (list%arr(list%size)%p)
271 list%size = list%size - 1
272 END FUNCTION list_callstackentry_pop
273
274! **************************************************************************************************
275!> \brief Removes all values from the list. The list itself is not deallocated.
276!> \param list ...
277!> \par History
278!> 12.2012 created [ole]
279!> \author Ole Schuett
280! **************************************************************************************************
282 TYPE(list_callstackentry_type), intent(inout) :: list
283 INTEGER :: i
284
285 IF (.not. ASSOCIATED(list%arr)) THEN
286 cpabort("list_callstackentry_clear: list is not initialized.")
287 END IF
288
289 DO i = 1, list%size
290 deallocate (list%arr(i)%p)
291 END DO
292 list%size = 0
293 END SUBROUTINE list_callstackentry_clear
294
295!
296! **************************************************************************************************
297!> \brief Returns the value at the given position from the list.
298!> \param list ...
299!> \param pos Position in the list - musst fulfill 0 < pos < list_size+1 .
300!> \return ...
301!> \par History
302!> 12.2012 created [ole]
303!> \author Ole Schuett
304! **************************************************************************************************
305 FUNCTION list_callstackentry_get(list, pos) RESULT(value)
306 TYPE(list_callstackentry_type), intent(in) :: list
307 INTEGER, intent(in) :: pos
308 TYPE(callstack_entry_type) :: value
309
310 IF (.NOT. ASSOCIATED(list%arr)) THEN
311 cpabort("list_callstackentry_get: list is not initialized.")
312 END IF
313 IF (pos < 1) THEN
314 cpabort("list_callstackentry_get: pos < 1")
315 END IF
316 IF (pos > list%size) THEN
317 cpabort("list_callstackentry_get: pos > size")
318 END IF
319
320 value =list%arr(pos)%p%value
321
322 END FUNCTION list_callstackentry_get
323
324! **************************************************************************************************
325!> \brief Removes the value at the given position from the list.
326!> \param list ...
327!> \param pos Position in the list - musst fulfill 0 < pos < list_size+1 .
328!> \par History
329!> 12.2012 created [ole]
330!> \author Ole Schuett
331! **************************************************************************************************
332 SUBROUTINE list_callstackentry_del(list, pos)
333 TYPE(list_callstackentry_type), intent(inout) :: list
334 INTEGER, intent(in) :: pos
335 INTEGER :: i
336
337 IF (.NOT. ASSOCIATED(list%arr)) THEN
338 cpabort("list_callstackentry_del: list is not initialized.")
339 END IF
340 IF (pos < 1) THEN
341 cpabort("list_callstackentry_det: pos < 1")
342 END IF
343 IF (pos > list%size) THEN
344 cpabort("list_callstackentry_det: pos > size")
345 END IF
346
347 deallocate (list%arr(pos)%p)
348 DO i = pos, list%size - 1
349 list%arr(i)%p => list%arr(i + 1)%p
350 END DO
351
352 list%size = list%size - 1
353
354 END SUBROUTINE list_callstackentry_del
355
356! **************************************************************************************************
357!> \brief Returns the current size of the list.
358!> \param list ...
359!> \return ...
360!> \par History
361!> 12.2012 created [ole]
362!> \author Ole Schuett
363! **************************************************************************************************
364 FUNCTION list_callstackentry_size(list) RESULT(size)
365 TYPE(list_callstackentry_type), intent(in) :: list
366 INTEGER :: size
367
368 IF (.NOT. ASSOCIATED(list%arr)) THEN
369 cpabort("list_callstackentry_size: list is not initialized.")
370 END IF
371
372 size = list%size
373 END FUNCTION list_callstackentry_size
374
375! **************************************************************************************************
376!> \brief Internal routine for changing the size of the internal array.
377!> \param list ...
378!> \param new_capacity ...
379!> \par History
380!> 12.2012 created [ole]
381!> \author Ole Schuett
382! **************************************************************************************************
383 SUBROUTINE change_capacity_callstackentry (list, new_capacity)
384 TYPE(list_callstackentry_type), intent(inout) :: list
385 INTEGER, intent(in) :: new_capacity
386 INTEGER :: i, new_cap, stat
387 TYPE(private_item_p_type_callstackentry), DIMENSION(:), POINTER :: old_arr
388
389 new_cap = new_capacity
390 IF (new_cap < 0) THEN
391 cpabort("list_callstackentry_change_capacity: new_capacity < 0")
392 END IF
393 IF (new_cap < list%size) THEN
394 cpabort("list_callstackentry_change_capacity: new_capacity < size")
395 END IF
396 IF (new_cap > huge(i)) THEN
397 IF (size(list%arr) == huge(i)) THEN
398 cpabort("list_callstackentry_change_capacity: list has reached integer limit.")
399 END IF
400 new_cap = huge(i) ! grow as far as possible
401 END IF
402
403 old_arr => list%arr
404 allocate (list%arr(new_cap), stat=stat)
405 IF (stat /= 0) THEN
406 cpabort("list_callstackentry_change_capacity: allocation failed")
407 END IF
408
409 DO i = 1, list%size
410 allocate (list%arr(i)%p, stat=stat)
411 IF (stat /= 0) THEN
412 cpabort("list_callstackentry_change_capacity: allocation failed")
413 END IF
414 list%arr(i)%p%value =old_arr(i)%p%value
415 DEALLOCATE (old_arr(i)%p)
416 END DO
417 DEALLOCATE (old_arr)
418
419 END SUBROUTINE change_capacity_callstackentry
420
421END MODULE list_callstackentry
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
subroutine, public list_callstackentry_push(list, value)
Appends the given value at the end of the list.
subroutine, public list_callstackentry_set(list, value, pos)
Assings the given value to the given position in the list. Thereby, the former value at that position...
subroutine, public list_callstackentry_del(list, pos)
Removes the value at the given position from the list.
integer function, public list_callstackentry_size(list)
Returns the current size of the list.
type(callstack_entry_type) function, public list_callstackentry_get(list, pos)
Returns the value at the given position from the list.
subroutine, public list_callstackentry_destroy(list)
Deallocated the internal data-structures of the given list. Caution: If the stored values are pointer...
subroutine, public list_callstackentry_insert(list, value, pos)
Inserts the given value at the givenn position within the list. Values which lay behind the insertion...
subroutine, public list_callstackentry_init(list, initial_capacity)
Allocates the internal data-structures of the given list. This has to be called before any of the oth...
type(callstack_entry_type) function, public list_callstackentry_pop(list)
Returns the last element in the list and removes it. Is equivialent to: value = list_callstackentry_g...
subroutine, public list_callstackentry_clear(list)
Removes all values from the list. The list itself is not deallocated.
type(callstack_entry_type) function, public list_callstackentry_peek(list)
Returns the last element in the list. Is equivalent to: list_callstackentry_get(list,...
logical function, public list_callstackentry_isready(list)
Test if the given list has been initialized.
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition list.F:24
Types used by timings.F and timings_report.F The types in this module are used within dict or list,...