gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
dc_hash.f90
Go to the documentation of this file.
1!-----------------------------------------------------------------------
2! Copyright (c) 2000-2026 Gtool Development Group. All rights reserved.
3!-----------------------------------------------------------------------
142
144 use dc_types, only : string
145 implicit none
146 private
147
148 public:: hash
151
152 !-----------------------------------------------
153 ! 後方互換用
154 ! For backward compatibility
155 public:: put, putline, get, rewind, next, delete, number
156
168 type hash
169 private
170 type(HASH_INTERNAL), pointer :: hash_table(:) => null()
171
173 integer :: search_index = 0
174
176 end type hash
177
184 type hash_internal
185 private
186 character(STRING) :: key
187
189 character(STRING) :: value
190
192 end type hash_internal
193
194 interface dchashput
195 module procedure dchashput0
196 end interface
197
198 interface dchashnumber
199 module procedure dchashnumber0
200 end interface
201
203 module procedure dchashputline0
204 end interface
205
206 interface dchashrewind
207 module procedure dchashrewind0
208 end interface
209
210 interface dchashnext
211 module procedure dchashnext0
212 end interface
213
214 interface dchashget
215 module procedure dchashget0
216 end interface
217
218 interface dchashdelete
219 module procedure dchashdelete0
220 end interface
221
222 !-----------------------------------------------
223 ! 後方互換用
224 ! For backward compatibility
225 interface put
226 module procedure dchashput0
227 end interface
228
229 interface number
230 module procedure dchashnumber0
231 end interface
232
233 interface putline
234 module procedure dchashputline0
235 end interface
236
237 interface rewind
238 module procedure dchashrewind0
239 end interface
240
241 interface next
242 module procedure dchashnext0
243 end interface
244
245 interface get
246 module procedure dchashget0
247 end interface
248
249 interface delete
250 module procedure dchashdelete0
251 end interface
252
253contains
254
276 subroutine dchashput0(hashv, key, value)
277 implicit none
278 type(hash), intent(inout) :: hashv
279 character(*), intent(in) :: key, value
280 type(hash_internal), pointer :: hash_table_tmp(:) => null()
281 integer :: table_size, new_index, i
282 logical :: found
283 character(STRING) :: search_value
284 continue
285 call dchashget(hashv, key, search_value, found)
286 if (.not. found) then
287 table_size = dchashnumber(hashv)
288 if (table_size > 0) then
289 allocate(hash_table_tmp(table_size))
290 hash_table_tmp = hashv % hash_table
291 deallocate(hashv % hash_table)
292 allocate(hashv % hash_table(table_size + 1))
293 hashv % hash_table(1:table_size) = hash_table_tmp(1:table_size)
294 deallocate(hash_table_tmp)
295 new_index = table_size + 1
296 else
297 allocate(hashv % hash_table(1))
298 new_index = 1
299 end if
300
301 hashv % hash_table(new_index) % key = key
302 hashv % hash_table(new_index) % value = value
303 else
304 do i = 1, size(hashv % hash_table)
305 if (trim(hashv % hash_table(i) % key) == trim(key)) then
306 hashv % hash_table(i) % value = value
307 end if
308 end do
309 end if
310
311 end subroutine dchashput0
312
313
331 function dchashnumber0(hashv) result(result)
332 implicit none
333 type(hash), intent(in) :: hashv
334 integer :: result
335 continue
336 if (associated(hashv % hash_table)) then
337 result = size(hashv % hash_table)
338 else
339 result = 0
340 end if
341 end function dchashnumber0
342
401 subroutine dchashrewind0(hashv)
402 implicit none
403 type(hash), intent(inout) :: hashv
404 continue
405 hashv % search_index = 1
406 end subroutine dchashrewind0
407
431 subroutine dchashnext0(hashv, key, value, end)
432 implicit none
433 type(hash), intent(inout) :: hashv
434 character(*), intent(out) :: key
435 character(*), intent(out), optional :: value
436 logical, intent(out) :: end
437 integer :: table_size
438 character(STRING) :: value_tmp
439 continue
440 table_size = dchashnumber(hashv)
441 if (table_size < hashv % search_index) then
442 key = ''
443 value_tmp = ''
444 end = .true.
445 else
446 key = hashv % hash_table(hashv % search_index) % key
447 value_tmp = hashv % hash_table(hashv % search_index) % value
448 end = .false.
449 hashv % search_index = hashv % search_index + 1
450 end if
451 if (present(value)) then
452 value = value_tmp
453 end if
454
455 end subroutine dchashnext0
456
457
475 subroutine dchashputline0(hashv)
476 use dc_types, only: string
477 use dc_string, only: printf, joinchar
478 implicit none
479 type(hash), intent(in) :: hashv
480 type(hash) :: hashv_tmp
481 character(len = STRING):: key, value
482 logical:: end
483 continue
484 hashv_tmp = hashv
485
486 call printf(6, '#<HASH:: ')
487 call dchashrewind(hashv_tmp)
488 do
489 call dchashnext(hashv_tmp, key, value, end)
490 if (end) exit
491 call printf(6, ' "%c" -> "%c",', &
492 & c1=trim(key), c2=trim(value))
493 enddo
494 call printf(6, '> ')
495
496 end subroutine dchashputline0
497
498
530 subroutine dchashget0(hashv, key, value, found)
531 use dc_types, only: string
532 implicit none
533 type(hash), intent(inout) :: hashv
534 character(*), intent(in) :: key
535 character(*), intent(out) :: value
536 logical, intent(out), optional :: found
537 character(STRING) :: search_key, search_value
538 logical :: end
539 continue
540 call dchashrewind(hashv)
541 do
542 call dchashnext(hashv, search_key, search_value, end)
543 if (end) then
544 value = ''
545 if (present(found)) found = .false.
546 exit
547 end if
548
549 if (trim(search_key) == trim(key)) then
550 value = search_value
551 if (present(found)) found = .true.
552 exit
553 end if
554 enddo
555
556 end subroutine dchashget0
557
582 subroutine dchashdelete0(hashv, key)
583 implicit none
584 type(hash), intent(inout) :: hashv
585 character(*), intent(in), optional :: key
586 type(hash_internal), pointer :: hash_table_tmp(:) => null()
587 integer :: table_size, i, j
588 logical :: found
589 character(STRING) :: search_value
590 continue
591 if (present(key)) then
592 call dchashget(hashv, key, search_value, found)
593 table_size = dchashnumber(hashv)
594 if (found .and. table_size > 1) then
595 allocate(hash_table_tmp(table_size))
596 hash_table_tmp = hashv % hash_table
597 deallocate(hashv % hash_table)
598 allocate(hashv % hash_table(table_size - 1))
599 j = 1
600 do i = 1, table_size
601 if (trim(hash_table_tmp(i) % key) /= trim(key)) then
602 hashv % hash_table(j) % key = hash_table_tmp(i) % key
603 hashv % hash_table(j) % value = hash_table_tmp(i) % value
604 j = j + 1
605 end if
606 end do
607
608 deallocate(hash_table_tmp)
609 elseif (found .and. table_size == 1) then
610 deallocate(hashv % hash_table)
611 end if
612 else
613 if (associated(hashv % hash_table)) deallocate(hashv % hash_table)
614 end if
615
616 end subroutine dchashdelete0
617
619end module dc_hash
Hash (associative array) module.
Definition dc_hash.f90:143
Handling character types.
Definition dc_string.f90:83
character(string) function, public joinchar(carray, expr)
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public string
Character length for string
Definition dc_types.f90:137