(git:b279b6b)
list_routinereport.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 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 
21  USE timings_base_type, ONLY: routine_stat_type, callstack_entry_type, routine_report_type
22 
23 
24 #include "../base/base_uses.f90"
25  IMPLICIT NONE
26  PRIVATE
27 
28  PUBLIC :: list_routinereport_type, list_routinereport_init, list_routinereport_push, list_routinereport_pop,&
32 
33 !this is an internal type
34  TYPE private_item_type_routinereport
35  PRIVATE
36  TYPE(routine_report_type), POINTER :: value => null()
37  END TYPE private_item_type_routinereport
38 
39 !this is an internal type
40  TYPE private_item_p_type_routinereport
41  PRIVATE
42  TYPE(private_item_type_routinereport), POINTER :: p => null()
43  END TYPE private_item_p_type_routinereport
44 
45 ! this is the public type, which holds a list-instance
46  TYPE list_routinereport_type
47  PRIVATE
48  TYPE(private_item_p_type_routinereport), DIMENSION(:), POINTER :: arr => null()
49  INTEGER :: size = -1
50  END TYPE list_routinereport_type
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_routinereport_isready(list) RESULT(res)
63  TYPE(list_routinereport_type), intent(in) :: list
64  LOGICAL :: res
65  res = ASSOCIATED(list%arr)
66  END FUNCTION list_routinereport_isready
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_routinereport_init(list, initial_capacity)
79  TYPE(list_routinereport_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) &
88  cpabort("list_routinereport_create: initial_capacity < 0")
89 
90  IF (ASSOCIATED(list%arr)) &
91  cpabort("list_routinereport_create: list is already initialized.")
92 
93  ALLOCATE (list%arr(initial_capacity_), stat=stat)
94  IF (stat /= 0) &
95  cpabort("list_routinereport_init: allocation failed")
96 
97  list%size = 0
98  END SUBROUTINE list_routinereport_init
99 
100 ! **************************************************************************************************
101 !> \brief Deallocated the internal data-structures of the given list.
102 !> Caution: If the stored values are pointers, their targets will
103 !> not get deallocated by this routine.
104 !> \param list ...
105 !> \par History
106 !> 12.2012 created [ole]
107 !> \author Ole Schuett
108 ! **************************************************************************************************
109  SUBROUTINE list_routinereport_destroy(list)
110  TYPE(list_routinereport_type), intent(inout) :: list
111  INTEGER :: i
112  IF (.not. ASSOCIATED(list%arr)) &
113  cpabort("list_routinereport_destroy: list is not initialized.")
114 
115  do i = 1, list%size
116  deallocate (list%arr(i)%p)
117  end do
118  deallocate (list%arr)
119  list%size = -1
120  END SUBROUTINE list_routinereport_destroy
121 
122 ! **************************************************************************************************
123 !> \brief Assings the given value to the given position in the list.
124 !> Thereby, the former value at that position gets overwritten.
125 !> If the position is out of bounds, the program stops.
126 !> \param list ...
127 !> \param value ...
128 !> \param pos Position in the list - musst fulfill 0 < pos < list_size+1.
129 !> \par History
130 !> 12.2012 created [ole]
131 !> \author Ole Schuett
132 ! **************************************************************************************************
133  SUBROUTINE list_routinereport_set(list, value, pos)
134  TYPE(list_routinereport_type), intent(inout) :: list
135  TYPE(routine_report_type), POINTER, intent(in) :: value
136  INTEGER, intent(in) :: pos
137  IF (.not. ASSOCIATED(list%arr)) &
138  cpabort("list_routinereport_set: list is not initialized.")
139  IF (pos < 1) &
140  cpabort("list_routinereport_set: pos < 1")
141  IF (pos > list%size) &
142  cpabort("list_routinereport_set: pos > size")
143  list%arr(pos)%p%value =>value
144  END SUBROUTINE list_routinereport_set
145 
146 ! **************************************************************************************************
147 !> \brief Appends the given value at the end of the list.
148 !> \param list ...
149 !> \param value ...
150 !> \par History
151 !> 12.2012 created [ole]
152 !> \author Ole Schuett
153 ! **************************************************************************************************
154  SUBROUTINE list_routinereport_push(list, value)
155  TYPE(list_routinereport_type), intent(inout) :: list
156  TYPE(routine_report_type), POINTER, intent(in) :: value
157  INTEGER :: stat
158 
159  IF (.not. ASSOCIATED(list%arr)) &
160  cpabort("list_routinereport_push: list is not initialized.")
161  if (list%size == size(list%arr)) &
162  call change_capacity_routinereport (list, 2*size(list%arr) + 1)
163 
164  list%size = list%size + 1
165  ALLOCATE (list%arr(list%size)%p, stat=stat)
166  IF (stat /= 0) &
167  cpabort("list_routinereport_push: allocation failed")
168  list%arr(list%size)%p%value =>value
169  END SUBROUTINE list_routinereport_push
170 
171 ! **************************************************************************************************
172 !> \brief Inserts the given value at the givenn position within the list.
173 !> Values which lay behind the insertion-position move one position up.
174 !> \param list ...
175 !> \param value ...
176 !> \param pos Position in the list - musst fulfill 0 < pos < list_size+2 .
177 !> \par History
178 !> 12.2012 created [ole]
179 !> \author Ole Schuett
180 ! **************************************************************************************************
181  SUBROUTINE list_routinereport_insert(list, value, pos)
182  TYPE(list_routinereport_type), intent(inout) :: list
183  TYPE(routine_report_type), POINTER, intent(in) :: value
184  INTEGER, intent(in) :: pos
185  INTEGER :: i, stat
186 
187  IF (.not. ASSOCIATED(list%arr)) &
188  cpabort("list_routinereport_insert: list is not initialized.")
189  IF (pos < 1) &
190  cpabort("list_routinereport_insert: pos < 1")
191  IF (pos > list%size + 1) &
192  cpabort("list_routinereport_insert: pos > size+1")
193 
194  if (list%size == size(list%arr)) &
195  call change_capacity_routinereport (list, 2*size(list%arr) + 1)
196 
197  list%size = list%size + 1
198  do i = list%size, pos + 1, -1
199  list%arr(i)%p => list%arr(i - 1)%p
200  end do
201 
202  ALLOCATE (list%arr(pos)%p, stat=stat)
203  IF (stat /= 0) &
204  cpabort("list_routinereport_insert: allocation failed.")
205  list%arr(pos)%p%value =>value
206  END SUBROUTINE list_routinereport_insert
207 
208 ! **************************************************************************************************
209 !> \brief Returns the last element in the list.
210 !> Is equivalent to: list_routinereport_get(list, list_routinereport_size(list))
211 !> \param list ...
212 !> \return ...
213 !> \par History
214 !> 12.2012 created [ole]
215 !> \author Ole Schuett
216 ! **************************************************************************************************
217  FUNCTION list_routinereport_peek(list) RESULT(value)
218  TYPE(list_routinereport_type), intent(inout) :: list
219  TYPE(routine_report_type), POINTER :: value
220 
221  IF (.not. ASSOCIATED(list%arr)) &
222  cpabort("list_routinereport_peek: list is not initialized.")
223  IF (list%size < 1) &
224  cpabort("list_routinereport_peek: list is empty.")
225 
226  value =>list%arr(list%size)%p%value
227  END FUNCTION list_routinereport_peek
228 
229 ! **************************************************************************************************
230 !> \brief Returns the last element in the list and removes it.
231 !> Is equivialent to:
232 !> value = list_routinereport_get(list, list_routinereport_size(list))
233 !> call list_routinereport_del(list, list_routinereport_size(list))
234 !>
235 !> \param list ...
236 !> \return ...
237 !> \par History
238 !> 12.2012 created [ole]
239 !> \author Ole Schuett
240 ! **************************************************************************************************
241  FUNCTION list_routinereport_pop(list) RESULT(value)
242  TYPE(list_routinereport_type), intent(inout) :: list
243  TYPE(routine_report_type), POINTER :: value
244 
245  IF (.not. ASSOCIATED(list%arr)) &
246  cpabort("list_routinereport_pop: list is not initialized.")
247  IF (list%size < 1) &
248  cpabort("list_routinereport_pop: list is empty.")
249 
250  value =>list%arr(list%size)%p%value
251  deallocate (list%arr(list%size)%p)
252  list%size = list%size - 1
253  END FUNCTION list_routinereport_pop
254 
255 ! **************************************************************************************************
256 !> \brief Removes all values from the list. The list itself is not deallocated.
257 !> \param list ...
258 !> \par History
259 !> 12.2012 created [ole]
260 !> \author Ole Schuett
261 ! **************************************************************************************************
262  SUBROUTINE list_routinereport_clear(list)
263  TYPE(list_routinereport_type), intent(inout) :: list
264  INTEGER :: i
265 
266  IF (.not. ASSOCIATED(list%arr)) &
267  cpabort("list_routinereport_clear: list is not initialized.")
268 
269  do i = 1, list%size
270  deallocate (list%arr(i)%p)
271  end do
272  list%size = 0
273  END SUBROUTINE list_routinereport_clear
274 
275 !
276 ! **************************************************************************************************
277 !> \brief Returns the value at the given position from the list.
278 !> \param list ...
279 !> \param pos Position in the list - musst fulfill 0 < pos < list_size+1 .
280 !> \return ...
281 !> \par History
282 !> 12.2012 created [ole]
283 !> \author Ole Schuett
284 ! **************************************************************************************************
285  FUNCTION list_routinereport_get(list, pos) RESULT(value)
286  TYPE(list_routinereport_type), intent(in) :: list
287  INTEGER, intent(in) :: pos
288  TYPE(routine_report_type), POINTER :: value
289 
290  IF (.not. ASSOCIATED(list%arr)) &
291  cpabort("list_routinereport_get: list is not initialized.")
292  IF (pos < 1) &
293  cpabort("list_routinereport_get: pos < 1")
294  IF (pos > list%size) &
295  cpabort("list_routinereport_get: pos > size")
296 
297  value =>list%arr(pos)%p%value
298 
299  END FUNCTION list_routinereport_get
300 
301 ! **************************************************************************************************
302 !> \brief Removes the value at the given position from the list.
303 !> \param list ...
304 !> \param pos Position in the list - musst fulfill 0 < pos < list_size+1 .
305 !> \par History
306 !> 12.2012 created [ole]
307 !> \author Ole Schuett
308 ! **************************************************************************************************
309  SUBROUTINE list_routinereport_del(list, pos)
310  TYPE(list_routinereport_type), intent(inout) :: list
311  INTEGER, intent(in) :: pos
312  INTEGER :: i
313 
314  IF (.not. ASSOCIATED(list%arr)) &
315  cpabort("list_routinereport_del: list is not initialized.")
316  IF (pos < 1) &
317  cpabort("list_routinereport_det: pos < 1")
318  IF (pos > list%size) &
319  cpabort("list_routinereport_det: pos > size")
320 
321  deallocate (list%arr(pos)%p)
322  do i = pos, list%size - 1
323  list%arr(i)%p => list%arr(i + 1)%p
324  end do
325 
326  list%size = list%size - 1
327 
328  END SUBROUTINE list_routinereport_del
329 
330 ! **************************************************************************************************
331 !> \brief Returns the current size of the list.
332 !> \param list ...
333 !> \return ...
334 !> \par History
335 !> 12.2012 created [ole]
336 !> \author Ole Schuett
337 ! **************************************************************************************************
338  FUNCTION list_routinereport_size(list) RESULT(size)
339  TYPE(list_routinereport_type), intent(in) :: list
340  INTEGER :: size
341 
342  IF (.not. ASSOCIATED(list%arr)) &
343  cpabort("list_routinereport_size: list is not initialized.")
344 
345  size = list%size
346  END FUNCTION list_routinereport_size
347 
348 ! **************************************************************************************************
349 !> \brief Internal routine for changing the size of the internal array.
350 !> \param list ...
351 !> \param new_capacity ...
352 !> \par History
353 !> 12.2012 created [ole]
354 !> \author Ole Schuett
355 ! **************************************************************************************************
356  SUBROUTINE change_capacity_routinereport (list, new_capacity)
357  TYPE(list_routinereport_type), intent(inout) :: list
358  INTEGER, intent(in) :: new_capacity
359  INTEGER :: i, new_cap, stat
360  TYPE(private_item_p_type_routinereport), DIMENSION(:), POINTER :: old_arr
361 
362  new_cap = new_capacity
363  IF (new_cap < 0) &
364  cpabort("list_routinereport_change_capacity: new_capacity < 0")
365  IF (new_cap < list%size) &
366  cpabort("list_routinereport_change_capacity: new_capacity < size")
367  IF (new_cap > huge(i)) THEN
368  IF (size(list%arr) == huge(i)) &
369  cpabort("list_routinereport_change_capacity: list has reached integer limit.")
370  new_cap = huge(i) ! grow as far as possible
371  END IF
372 
373  old_arr => list%arr
374  allocate (list%arr(new_cap), stat=stat)
375  IF (stat /= 0) &
376  cpabort("list_routinereport_change_capacity: allocation failed")
377 
378  do i = 1, list%size
379  allocate (list%arr(i)%p, stat=stat)
380  IF (stat /= 0) &
381  cpabort("list_routinereport_change_capacity: allocation failed")
382  list%arr(i)%p%value =>old_arr(i)%p%value
383  deallocate (old_arr(i)%p)
384  end do
385  deallocate (old_arr)
386 
387  END SUBROUTINE change_capacity_routinereport
388 
389 END MODULE list_routinereport
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
subroutine, public list_routinereport_destroy(list)
Deallocated the internal data-structures of the given list. Caution: If the stored values are pointer...
integer function, public list_routinereport_size(list)
Returns the current size of the list.
logical function, public list_routinereport_isready(list)
Test if the given list has been initialized.
type(routine_report_type) function, pointer, public list_routinereport_peek(list)
Returns the last element in the list. Is equivalent to: list_routinereport_get(list,...
type(routine_report_type) function, pointer, public list_routinereport_pop(list)
Returns the last element in the list and removes it. Is equivialent to: value = list_routinereport_ge...
subroutine, public list_routinereport_clear(list)
Removes all values from the list. The list itself is not deallocated.
subroutine, public list_routinereport_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_routinereport_init(list, initial_capacity)
Allocates the internal data-structures of the given list. This has to be called before any of the oth...
subroutine, public list_routinereport_del(list, pos)
Removes the value at the given position from the list.
subroutine, public list_routinereport_push(list, value)
Appends the given value at the end of the list.
subroutine, public list_routinereport_insert(list, value, pos)
Inserts the given value at the givenn position within the list. Values which lay behind the insertion...
type(routine_report_type) function, pointer, public list_routinereport_get(list, pos)
Returns the value at the given position from the list.
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,...