From 9a9fedb403ca27f3c5e84bb94fae87be62e19882 Mon Sep 17 00:00:00 2001 From: Jeremie Vandenplas Date: Wed, 22 Jun 2022 19:28:36 +0200 Subject: [PATCH 01/10] add get_other_scalar from stdlib_hashmap_wrappers --- src/CMakeLists.txt | 2 +- ...ppers.f90 => stdlib_hashmap_wrappers.fypp} | 62 ++++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) rename src/{stdlib_hashmap_wrappers.f90 => stdlib_hashmap_wrappers.fypp} (85%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b79d920e9..5584757cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ set(fppFiles stdlib_hash_64bit_fnv.fypp stdlib_hash_64bit_pengy.fypp stdlib_hash_64bit_spookyv2.fypp + stdlib_hashmap_wrappers.fypp stdlib_io.fypp stdlib_io_npy.fypp stdlib_io_npy_load.fypp @@ -84,7 +85,6 @@ fypp_f90("${fyppFlags}" "${fppFiles}" outFiles) set(SRC stdlib_array.f90 stdlib_error.f90 - stdlib_hashmap_wrappers.f90 stdlib_hashmaps.f90 stdlib_hashmap_chaining.f90 stdlib_hashmap_open.f90 diff --git a/src/stdlib_hashmap_wrappers.f90 b/src/stdlib_hashmap_wrappers.fypp similarity index 85% rename from src/stdlib_hashmap_wrappers.f90 rename to src/stdlib_hashmap_wrappers.fypp index 67b13b96e..dfdc35ada 100755 --- a/src/stdlib_hashmap_wrappers.f90 +++ b/src/stdlib_hashmap_wrappers.fypp @@ -1,3 +1,4 @@ +#:include "common.fypp" !! The module STDLIB_HASHMAP_WRAPPERS provides wrappers for various !! entities used by the hash map procedures. These include wrappers for the !! `key` and `other` data, and hashing procedures to operate on entities of @@ -15,7 +16,12 @@ module stdlib_hashmap_wrappers int16, & int32, & int64, & - dp + sp, & + dp, & + xdp, & + qp, & + lk, & + c_bool implicit none @@ -31,6 +37,7 @@ module stdlib_hashmap_wrappers free_key, & free_other, & get, & + get_other_scalar, & hasher_fun, & operator(==), & seeded_nmhash32_hasher, & @@ -87,6 +94,7 @@ end function hasher_fun interface get module procedure get_char_key, & + get_other, & get_int8_key end interface get @@ -260,6 +268,58 @@ subroutine get_other( other, value ) end subroutine get_other + + subroutine get_other_scalar(other, value_char & + #:set IRL_KINDS_TYPES = INT_KINDS_TYPES + REAL_KINDS_TYPES + LOG_KINDS_TYPES + #:for k1, t1 in IRL_KINDS_TYPES + , value_${k1}$ & + #:endfor + #:for k1, t1 in CMPLX_KINDS_TYPES + , value_c${k1}$ & + #:endfor + , exists) +!! Version: Experimental +!! +!! Gets the content of the other as a scalar of a kind provided by stdlib_kinds + class(other_type), intent(in) :: other + character(len=:), allocatable, intent(out), optional :: value_char + #:for k1, t1 in IRL_KINDS_TYPES + ${t1}$, intent(out), optional :: value_${k1}$ + #:endfor + #:for k1, t1 in CMPLX_KINDS_TYPES + ${t1}$, intent(out), optional :: value_c${k1}$ + #:endfor + logical, intent(out), optional :: exists + + logical :: exists_ + + exists_ = .false. + + if (.not.allocated(other % value)) then + if (present(exists)) exists = exists_ + return + end if + + select type(d => other % value) + #:for k1, t1 in IRL_KINDS_TYPES + type is ( ${t1}$ ) + if (present(value_${k1}$)) then + value_${k1}$ = d + exists_ = .true. + end if + #:endfor + #:for k1, t1 in CMPLX_KINDS_TYPES + type is ( ${t1}$ ) + if (present(value_${k1}$)) then + value_c${k1}$ = d + exists_ = .true. + end if + #:endfor + end select + + if (present(exists)) exists = exists_ + + end subroutine subroutine get_int8_key( key, value ) !! Version: Experimental From b81e34f46439cea43287e8dc15826eb7a0207d03 Mon Sep 17 00:00:00 2001 From: Jeremie Vandenplas Date: Wed, 22 Jun 2022 21:16:34 +0200 Subject: [PATCH 02/10] add tests + fix issues --- src/stdlib_hashmap_wrappers.fypp | 7 +- src/tests/hashmaps/test_maps.fypp | 143 ++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-) diff --git a/src/stdlib_hashmap_wrappers.fypp b/src/stdlib_hashmap_wrappers.fypp index dfdc35ada..adfd73476 100755 --- a/src/stdlib_hashmap_wrappers.fypp +++ b/src/stdlib_hashmap_wrappers.fypp @@ -301,6 +301,11 @@ contains end if select type(d => other % value) + type is ( character(*) ) + if (present(value_char)) then + value_char = d + exists_ = .true. + end if #:for k1, t1 in IRL_KINDS_TYPES type is ( ${t1}$ ) if (present(value_${k1}$)) then @@ -310,7 +315,7 @@ contains #:endfor #:for k1, t1 in CMPLX_KINDS_TYPES type is ( ${t1}$ ) - if (present(value_${k1}$)) then + if (present(value_c${k1}$)) then value_c${k1}$ = d exists_ = .true. end if diff --git a/src/tests/hashmaps/test_maps.fypp b/src/tests/hashmaps/test_maps.fypp index cd1e3a4ee..735e7206f 100644 --- a/src/tests/hashmaps/test_maps.fypp +++ b/src/tests/hashmaps/test_maps.fypp @@ -1,5 +1,146 @@ +#:include "common.fypp" #:set HASH_NAME = ["fnv_1_hasher", "fnv_1a_hasher", "seeded_nmhash32_hasher", "seeded_nmhash32x_hasher", "seeded_water_hasher"] #:set SIZE_NAME = ["16", "256"] + +#:set IR_KINDS_TYPES = INT_KINDS_TYPES + REAL_KINDS_TYPES + +module test_stdlib_hashmap_wrappers + use testdrive, only : new_unittest, unittest_type, error_type, check + use stdlib_kinds, only: sp, dp, xdp, qp, int8, int16, int32, int64, lk + + use stdlib_hashmap_wrappers, only: other_type, set, get_other_scalar + + implicit none + private + + public :: collect_stdlib_wrappers + +contains + + !> Collect all exported unit tests + subroutine collect_stdlib_wrappers(testsuite) + !> Collection of tests + type(unittest_type), allocatable, intent(out) :: testsuite(:) + + testsuite = [ & + new_unittest("hashmap-get-other-scalar-char", test_get_other_scalar_char) & + #:for k1, t1 in IR_KINDS_TYPES + , new_unittest("hashmap-get-other-scalar-${k1}$", test_get_other_scalar_${k1}$) & + #:endfor + #:for k1, t1 in CMPLX_KINDS_TYPES + , new_unittest("hashmap-get-other-scalar-c${k1}$", test_get_other_scalar_c${k1}$) & + #:endfor + , new_unittest("hashmap-get-other-scalar-lk", test_get_other_scalar_lk) & + ] + + end subroutine collect_stdlib_wrappers + + subroutine test_get_other_scalar_char(error) + type(error_type), allocatable, intent(out) :: error + + character(len=:), allocatable :: value_in, value_out + type(other_type) :: other + logical :: exists + + value_in = 'abcdef' + + call set ( other, value_in ) + + call get_other_scalar(other, value_char = value_out) + print*,'aaa ',value_in, value_out + call check(error, value_in, value_out, "get_other_scalar char: value_in not equal to value_out") + return + + call get_other_scalar(other, value_char = value_out, exists = exists) + call check(error, value_in, value_out, "get_other_scalar char: value_in not equal to value_out") + return + call check(error, exists, "get_other_scalar char: exists should be .true.") + + end subroutine + + #:for k1, t1 in IR_KINDS_TYPES + subroutine test_get_other_scalar_${k1}$(error) + type(error_type), allocatable, intent(out) :: error + + ${t1}$ :: value_in, value_out + type(other_type) :: other + logical :: exists + + value_in = 13 + + call set ( other, value_in ) + + call get_other_scalar(other, value_${k1}$ = value_out) + + call check(error, value_in, value_out, "get_other_scalar ${k1}$: value_in not equal to value_out") + return + + call get_other_scalar(other, value_${k1}$ = value_out, exists = exists) + + call check(error, value_in, value_out, "get_other_scalar ${k1}$: value_in not equal to value_out") + return + call check(error, exists, "get_other_scalar ${k1}$: exists should be .true.") + return + + end subroutine + #:endfor + + #:for k1, t1 in CMPLX_KINDS_TYPES + subroutine test_get_other_scalar_c${k1}$(error) + type(error_type), allocatable, intent(out) :: error + + ${t1}$ :: value_in, value_out + type(other_type) :: other + logical :: exists + + value_in = (13._${k1}$, -3._${k1}$) + + call set ( other, value_in ) + + call get_other_scalar(other, value_c${k1}$ = value_out) + + call check(error, value_in, value_out, "get_other_scalar c${k1}$: value_in not equal to value_out") + return + + call get_other_scalar(other, value_c${k1}$ = value_out, exists = exists) + + call check(error, value_in, value_out, "get_other_scalar c${k1}$: value_in not equal to value_out") + return + call check(error, exists, "get_other_scalar c${k1}$: exists should be .true.") + return + + end subroutine + #:endfor + + + subroutine test_get_other_scalar_lk(error) + type(error_type), allocatable, intent(out) :: error + + logical(lk) :: value_in, value_out + type(other_type) :: other + logical :: exists + + value_in = .true. + + call set ( other, value_in ) + + call get_other_scalar(other, value_lk = value_out) + + call check(error, value_in .eqv. value_out, "get_other_scalar lk: value_in not equal to value_out") + return + + call get_other_scalar(other, value_lk = value_out, exists = exists) + + call check(error, value_in .eqv. value_out, "get_other_scalar lk: value_in not equal to value_out") + return + call check(error, exists, "get_other_scalar lk: exists should be .true.") + return + + end subroutine + +end module + + module test_stdlib_chaining_maps !! Test various aspects of the runtime system. !! Running this program may require increasing the stack size to above 48 MBytes @@ -354,6 +495,7 @@ program tester use testdrive, only : run_testsuite, new_testsuite, testsuite_type use test_stdlib_open_maps, only : collect_stdlib_open_maps use test_stdlib_chaining_maps, only : collect_stdlib_chaining_maps + use test_stdlib_hashmap_wrappers, only : collect_stdlib_wrappers implicit none integer :: stat, is type(testsuite_type), allocatable :: testsuites(:) @@ -364,6 +506,7 @@ program tester testsuites = [ & new_testsuite("stdlib-open-maps", collect_stdlib_open_maps) & , new_testsuite("stdlib-chaining-maps", collect_stdlib_chaining_maps) & + , new_testsuite("stdlib-hashmap-wrappers", collect_stdlib_wrappers) & ] do is = 1, size(testsuites) From e29fbd741dc8715ddd4fee28a793ab53bc538345 Mon Sep 17 00:00:00 2001 From: Jeremie Vandenplas Date: Wed, 22 Jun 2022 21:55:24 +0200 Subject: [PATCH 03/10] add specs --- doc/specs/stdlib_hashmaps.md | 79 +++++++++++++++++++++++++++++++ src/stdlib_hashmap_wrappers.fypp | 1 + src/tests/hashmaps/test_maps.fypp | 2 +- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/doc/specs/stdlib_hashmaps.md b/doc/specs/stdlib_hashmaps.md index abe6b92c8..d22c2c189 100644 --- a/doc/specs/stdlib_hashmaps.md +++ b/doc/specs/stdlib_hashmaps.md @@ -172,6 +172,10 @@ Procedures to manipulate `other_type` data: * `get( other, value )` - extracts the contents of `other` into the `class(*)` variable `value`. +* `get_other_scalar( other, value [, exists])` - extracts the content of + `other` into the scalar variable `value` of a kind provided by the module + `stdlib_kinds`. + * `set( other, value )` - sets the content of `other` to the `class(*)` variable `value`. @@ -584,6 +588,81 @@ an allocatable of `class(*)`. It is an `intent(out)` argument. end program demo_get ``` +#### `get_other_scalar` - extracts a scalar value from a derived type + +##### Status + +Experimental + +##### Description + +Extracts a scalar value from a `other_type` and stores it in the scalar variable +`value`. + +##### Syntax + +`call [[stdlib_hashmap_wrappers:get_other_scalar]]( other[, value_char, +value_int8, value_int16, value_int32, value_int64, value_sp, value_dp, value_csp, value_cdp, value_lk, +exists] )` + +##### Class + +Subroutine. + +##### Argument + +`other`: shall be a scalar expression of type `other_type`. It +is an `intent(in)` argument. + +`value_char`: shall be a scalar `character(len=:), allocatable) variable. It is an +`intent(out)` `optional` argument. + +`value_int8`, `value_int16`, `value_int32`, `value_int64`: shall be a scalar +`integer` of kind `int8`, `int16`, `int32`, `int64`, respectively. It is an +`intent(out)` `optional` argument. + +`value_sp`, `value_dp`: shall be a scalar `real` of kind `sp`, `dp` respectively. +It is an `intent(out)` `optional` argument. + +`value_csp`, `value_cdp`: shall be a scalar `complex` of kind `sp`, `dp` respectively. +It is an `intent(out)` `optional` argument. + +`value_lk`: shall be a scalar `logical` of kind `lk`. It is an `intent(out)` +`optional` argument. + +`exists`: shall be a scalar `logical`. It is an `intent(out)` `optional` +argument. + +#### Result + +The provided scalar variable contains the value of the `other_type` if both are of +the same type; otherwise the provided scalar variable is undefined. + +`exists` is `.true.` if the provided scalar variable and the value of the +other_type are of the same type. Otherwise, `exists` is `.false.` + +##### Example + +```fortran + program demo_get + use stdlib_hashmap_wrappers, only: & + get, key_type, set + use iso_fortran_env, only: int8 + implicit none + integer(int8), allocatable :: value(:), result(:) + type(key_type) :: key + integer(int_8) :: i + allocate( value(1:15) ) + do i=1, 15 + value(i) = i + end do + call set( key, value ) + call get( key, result ) + print *, 'RESULT == VALUE = ', all( value == result ) + end program demo_get +``` + + #### `hasher_fun`- serves aa a function prototype. diff --git a/src/stdlib_hashmap_wrappers.fypp b/src/stdlib_hashmap_wrappers.fypp index adfd73476..ddda32147 100755 --- a/src/stdlib_hashmap_wrappers.fypp +++ b/src/stdlib_hashmap_wrappers.fypp @@ -281,6 +281,7 @@ contains !! Version: Experimental !! !! Gets the content of the other as a scalar of a kind provided by stdlib_kinds +!! ([Specifications](../page/specs/stdlib_hashmaps.html#get_other_scalar-extracts-a-scalar-value-from-a-derived-type)) class(other_type), intent(in) :: other character(len=:), allocatable, intent(out), optional :: value_char #:for k1, t1 in IRL_KINDS_TYPES diff --git a/src/tests/hashmaps/test_maps.fypp b/src/tests/hashmaps/test_maps.fypp index 735e7206f..ea0738e9d 100644 --- a/src/tests/hashmaps/test_maps.fypp +++ b/src/tests/hashmaps/test_maps.fypp @@ -47,7 +47,7 @@ contains call set ( other, value_in ) call get_other_scalar(other, value_char = value_out) - print*,'aaa ',value_in, value_out + call check(error, value_in, value_out, "get_other_scalar char: value_in not equal to value_out") return From 88e6f36b740b719cc61d5c0608bccb622c3d9a91 Mon Sep 17 00:00:00 2001 From: Jeremie Vandenplas Date: Wed, 22 Jun 2022 22:05:21 +0200 Subject: [PATCH 04/10] add example in specs --- doc/specs/stdlib_hashmaps.md | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/doc/specs/stdlib_hashmaps.md b/doc/specs/stdlib_hashmaps.md index d22c2c189..26335141c 100644 --- a/doc/specs/stdlib_hashmaps.md +++ b/doc/specs/stdlib_hashmaps.md @@ -609,7 +609,7 @@ exists] )` Subroutine. -##### Argument +##### Arguments `other`: shall be a scalar expression of type `other_type`. It is an `intent(in)` argument. @@ -644,26 +644,20 @@ other_type are of the same type. Otherwise, `exists` is `.false.` ##### Example ```fortran - program demo_get + program demo_get_other_scalar use stdlib_hashmap_wrappers, only: & - get, key_type, set - use iso_fortran_env, only: int8 + get_other_scalar, other_type, set + use stdlib_kinds, only: int32 implicit none - integer(int8), allocatable :: value(:), result(:) - type(key_type) :: key - integer(int_8) :: i - allocate( value(1:15) ) - do i=1, 15 - value(i) = i - end do - call set( key, value ) - call get( key, result ) - print *, 'RESULT == VALUE = ', all( value == result ) + integer(int32) :: value, result + type(other_type) :: other + value = 15 + call set( other, value ) + call get_other_scalar( other, result ) + print *, 'RESULT == VALUE = ', ( value == result ) end program demo_get ``` - - #### `hasher_fun`- serves aa a function prototype. ##### Status From 350f19b077d3d0efa70f92fb8b893b9c7e58e6da Mon Sep 17 00:00:00 2001 From: Jeremie Vandenplas Date: Thu, 4 Aug 2022 19:51:39 +0200 Subject: [PATCH 05/10] API for get_other_scalar simplified --- src/stdlib_hashmap_wrappers.fypp | 77 +++++++++++++++++-------------- src/tests/hashmaps/test_maps.fypp | 16 +++---- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/stdlib_hashmap_wrappers.fypp b/src/stdlib_hashmap_wrappers.fypp index ddda32147..3255acefe 100755 --- a/src/stdlib_hashmap_wrappers.fypp +++ b/src/stdlib_hashmap_wrappers.fypp @@ -1,4 +1,5 @@ #:include "common.fypp" +#:set IRLC_KINDS_TYPES = INT_KINDS_TYPES + REAL_KINDS_TYPES + LOG_KINDS_TYPES + CMPLX_KINDS_TYPES !! The module STDLIB_HASHMAP_WRAPPERS provides wrappers for various !! entities used by the hash map procedures. These include wrappers for the !! `key` and `other` data, and hashing procedures to operate on entities of @@ -99,6 +100,15 @@ module stdlib_hashmap_wrappers end interface get + interface get_other_scalar + + module procedure get_other_scalar_char + #:for k1, t1 in IRLC_KINDS_TYPES + module procedure get_other_scalar_${t1[0]}$${k1}$ + #:endfor + + end interface get_other_scalar + interface operator(==) module procedure equal_keys @@ -268,28 +278,13 @@ contains end subroutine get_other - - subroutine get_other_scalar(other, value_char & - #:set IRL_KINDS_TYPES = INT_KINDS_TYPES + REAL_KINDS_TYPES + LOG_KINDS_TYPES - #:for k1, t1 in IRL_KINDS_TYPES - , value_${k1}$ & - #:endfor - #:for k1, t1 in CMPLX_KINDS_TYPES - , value_c${k1}$ & - #:endfor - , exists) + subroutine get_other_scalar_char(other, value, exists) !! Version: Experimental !! !! Gets the content of the other as a scalar of a kind provided by stdlib_kinds !! ([Specifications](../page/specs/stdlib_hashmaps.html#get_other_scalar-extracts-a-scalar-value-from-a-derived-type)) class(other_type), intent(in) :: other - character(len=:), allocatable, intent(out), optional :: value_char - #:for k1, t1 in IRL_KINDS_TYPES - ${t1}$, intent(out), optional :: value_${k1}$ - #:endfor - #:for k1, t1 in CMPLX_KINDS_TYPES - ${t1}$, intent(out), optional :: value_c${k1}$ - #:endfor + character(len=:), allocatable, intent(out) :: value logical, intent(out), optional :: exists logical :: exists_ @@ -303,29 +298,43 @@ contains select type(d => other % value) type is ( character(*) ) - if (present(value_char)) then - value_char = d - exists_ = .true. - end if - #:for k1, t1 in IRL_KINDS_TYPES - type is ( ${t1}$ ) - if (present(value_${k1}$)) then - value_${k1}$ = d - exists_ = .true. - end if - #:endfor - #:for k1, t1 in CMPLX_KINDS_TYPES + value = d + exists_ = .true. + end select + + if (present(exists)) exists = exists_ + + end subroutine + + #:for k1, t1 in IRLC_KINDS_TYPES + subroutine get_other_scalar_${t1[0]}$${k1}$(other, value, exists) +!! Version: Experimental +!! +!! Gets the content of the other as a scalar of a kind provided by stdlib_kinds +!! ([Specifications](../page/specs/stdlib_hashmaps.html#get_other_scalar-extracts-a-scalar-value-from-a-derived-type)) + class(other_type), intent(in) :: other + ${t1}$, intent(out) :: value + logical, intent(out), optional :: exists + + logical :: exists_ + + exists_ = .false. + + if (.not.allocated(other % value)) then + if (present(exists)) exists = exists_ + return + end if + + select type(d => other % value) type is ( ${t1}$ ) - if (present(value_c${k1}$)) then - value_c${k1}$ = d - exists_ = .true. - end if - #:endfor + value = d + exists_ = .true. end select if (present(exists)) exists = exists_ end subroutine + #:endfor subroutine get_int8_key( key, value ) !! Version: Experimental diff --git a/src/tests/hashmaps/test_maps.fypp b/src/tests/hashmaps/test_maps.fypp index ea0738e9d..52887e2fc 100644 --- a/src/tests/hashmaps/test_maps.fypp +++ b/src/tests/hashmaps/test_maps.fypp @@ -46,12 +46,12 @@ contains call set ( other, value_in ) - call get_other_scalar(other, value_char = value_out) + call get_other_scalar(other, value_out) call check(error, value_in, value_out, "get_other_scalar char: value_in not equal to value_out") return - call get_other_scalar(other, value_char = value_out, exists = exists) + call get_other_scalar(other, value_out, exists = exists) call check(error, value_in, value_out, "get_other_scalar char: value_in not equal to value_out") return call check(error, exists, "get_other_scalar char: exists should be .true.") @@ -70,12 +70,12 @@ contains call set ( other, value_in ) - call get_other_scalar(other, value_${k1}$ = value_out) + call get_other_scalar(other, value_out) call check(error, value_in, value_out, "get_other_scalar ${k1}$: value_in not equal to value_out") return - call get_other_scalar(other, value_${k1}$ = value_out, exists = exists) + call get_other_scalar(other, value_out, exists = exists) call check(error, value_in, value_out, "get_other_scalar ${k1}$: value_in not equal to value_out") return @@ -97,12 +97,12 @@ contains call set ( other, value_in ) - call get_other_scalar(other, value_c${k1}$ = value_out) + call get_other_scalar(other, value_out) call check(error, value_in, value_out, "get_other_scalar c${k1}$: value_in not equal to value_out") return - call get_other_scalar(other, value_c${k1}$ = value_out, exists = exists) + call get_other_scalar(other, value_out, exists = exists) call check(error, value_in, value_out, "get_other_scalar c${k1}$: value_in not equal to value_out") return @@ -124,12 +124,12 @@ contains call set ( other, value_in ) - call get_other_scalar(other, value_lk = value_out) + call get_other_scalar(other, value_out) call check(error, value_in .eqv. value_out, "get_other_scalar lk: value_in not equal to value_out") return - call get_other_scalar(other, value_lk = value_out, exists = exists) + call get_other_scalar(other, value_out, exists = exists) call check(error, value_in .eqv. value_out, "get_other_scalar lk: value_in not equal to value_out") return From 8cb2d7230bace0f33ea6c9afe2c9cc2730d3b28f Mon Sep 17 00:00:00 2001 From: Jeremie Vandenplas Date: Thu, 4 Aug 2022 20:00:39 +0200 Subject: [PATCH 06/10] update stdlib_hashmaps for API get_other_scalar --- doc/specs/stdlib_hashmaps.md | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/doc/specs/stdlib_hashmaps.md b/doc/specs/stdlib_hashmaps.md index 26335141c..2eeca823c 100644 --- a/doc/specs/stdlib_hashmaps.md +++ b/doc/specs/stdlib_hashmaps.md @@ -601,9 +601,7 @@ Extracts a scalar value from a `other_type` and stores it in the scalar variable ##### Syntax -`call [[stdlib_hashmap_wrappers:get_other_scalar]]( other[, value_char, -value_int8, value_int16, value_int32, value_int64, value_sp, value_dp, value_csp, value_cdp, value_lk, -exists] )` +`call [[stdlib_hashmap_wrappers:get_other_scalar(interface)]]( other, value[, exists] )` ##### Class @@ -614,21 +612,8 @@ Subroutine. `other`: shall be a scalar expression of type `other_type`. It is an `intent(in)` argument. -`value_char`: shall be a scalar `character(len=:), allocatable) variable. It is an -`intent(out)` `optional` argument. - -`value_int8`, `value_int16`, `value_int32`, `value_int64`: shall be a scalar -`integer` of kind `int8`, `int16`, `int32`, `int64`, respectively. It is an -`intent(out)` `optional` argument. - -`value_sp`, `value_dp`: shall be a scalar `real` of kind `sp`, `dp` respectively. -It is an `intent(out)` `optional` argument. - -`value_csp`, `value_cdp`: shall be a scalar `complex` of kind `sp`, `dp` respectively. -It is an `intent(out)` `optional` argument. - -`value_lk`: shall be a scalar `logical` of kind `lk`. It is an `intent(out)` -`optional` argument. +`value`: shall be a scalar of type `character(*)`, or of any type of `integer`, +`real` or `complex`, or of any type of `logical`. It is an `intent(out)` argument. `exists`: shall be a scalar `logical`. It is an `intent(out)` `optional` argument. @@ -639,7 +624,7 @@ The provided scalar variable contains the value of the `other_type` if both are the same type; otherwise the provided scalar variable is undefined. `exists` is `.true.` if the provided scalar variable and the value of the -other_type are of the same type. Otherwise, `exists` is `.false.` +`other_type` are of the same type. Otherwise, `exists` is `.false.` ##### Example From d66a3c349155f8b3c2e8f7f85b5ec9c57c8f0a1b Mon Sep 17 00:00:00 2001 From: Jeremie Vandenplas Date: Thu, 4 Aug 2022 14:03:43 -0400 Subject: [PATCH 07/10] Update doc/specs/stdlib_hashmaps.md --- doc/specs/stdlib_hashmaps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/specs/stdlib_hashmaps.md b/doc/specs/stdlib_hashmaps.md index 2eeca823c..fa2c9d270 100644 --- a/doc/specs/stdlib_hashmaps.md +++ b/doc/specs/stdlib_hashmaps.md @@ -639,7 +639,7 @@ the same type; otherwise the provided scalar variable is undefined. value = 15 call set( other, value ) call get_other_scalar( other, result ) - print *, 'RESULT == VALUE = ', ( value == result ) + print *, 'RESULT == VALUE = ', ( result == value ) end program demo_get ``` From 0afe611a3f4162c93292bb6d3f150a2df6d92b08 Mon Sep 17 00:00:00 2001 From: Jeremie Vandenplas Date: Thu, 4 Aug 2022 20:39:46 +0200 Subject: [PATCH 08/10] update hashmap specs --- doc/specs/stdlib_hashmaps.md | 13 +------------ .../hashmaps/example_hashmaps_get_other_scalar.f90 | 13 +++++++++++++ 2 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 example/hashmaps/example_hashmaps_get_other_scalar.f90 diff --git a/doc/specs/stdlib_hashmaps.md b/doc/specs/stdlib_hashmaps.md index 360fac722..2c75eca2f 100644 --- a/doc/specs/stdlib_hashmaps.md +++ b/doc/specs/stdlib_hashmaps.md @@ -529,18 +529,7 @@ the same type; otherwise the provided scalar variable is undefined. ##### Example ```fortran - program demo_get_other_scalar - use stdlib_hashmap_wrappers, only: & - get_other_scalar, other_type, set - use stdlib_kinds, only: int32 - implicit none - integer(int32) :: value, result - type(other_type) :: other - value = 15 - call set( other, value ) - call get_other_scalar( other, result ) - print *, 'RESULT == VALUE = ', ( value == result ) - end program demo_get +{!example/hashmaps/example_hashmaps_get_other_scalar.f90!} ``` #### `hasher_fun`- serves as a function prototype. diff --git a/example/hashmaps/example_hashmaps_get_other_scalar.f90 b/example/hashmaps/example_hashmaps_get_other_scalar.f90 new file mode 100644 index 000000000..abc684bd6 --- /dev/null +++ b/example/hashmaps/example_hashmaps_get_other_scalar.f90 @@ -0,0 +1,13 @@ + program example_hashmaps_get_other_scalar + use stdlib_hashmap_wrappers, only: & + get_other_scalar, other_type, set + use stdlib_kinds, only: int32 + implicit none + integer(int32) :: value, result + type(other_type) :: other + value = 15 + call set( other, value ) + call get_other_scalar( other, result ) + print *, 'RESULT == VALUE = ', ( value == result ) + end program demo_get + From 5286c72b87f6a0a607f44d5b010cce1ccd8bd048 Mon Sep 17 00:00:00 2001 From: Jeremie Vandenplas Date: Thu, 4 Aug 2022 21:09:56 +0200 Subject: [PATCH 09/10] replace get_other_scalar by get --- doc/specs/stdlib_hashmaps.md | 64 ++++++------------- example/hashmaps/CMakeLists.txt | 1 + .../example_hashmaps_get_other_scalar.f90 | 24 ++++--- src/stdlib_hashmap_wrappers.fypp | 11 +--- test/hashmaps/test_maps.fypp | 42 ++++++------ 5 files changed, 56 insertions(+), 86 deletions(-) diff --git a/doc/specs/stdlib_hashmaps.md b/doc/specs/stdlib_hashmaps.md index 2c75eca2f..704455e5a 100644 --- a/doc/specs/stdlib_hashmaps.md +++ b/doc/specs/stdlib_hashmaps.md @@ -462,7 +462,7 @@ in the variable `value`. or -`call [[stdlib_hashmap_wrappers:get]]( other, value )` +`call [[stdlib_hashmap_wrappers:get]]( other, value[, exists] )` ##### Class @@ -476,58 +476,36 @@ is an `intent(in)` argument. `other`: shall be a scalar expression of type `other_type`. It is an `intent(in)` argument. -`value`: if the the first argument is of `key_type` `value` shall be +`value`: if the first argument is of `key_type` `value` shall be an allocatable default character string variable, or an allocatable vector variable of type integer and kind `int8`, otherwise the first argument is of `other_type` and `value` shall be -an allocatable of `class(*)`. It is an `intent(out)` argument. - -##### Example - -```fortran -{!example/hashmaps/example_hashmaps_get.f90!} -``` - -#### `get_other_scalar` - extracts a scalar value from a derived type - -##### Status - -Experimental - -##### Description - -Extracts a scalar value from a `other_type` and stores it in the scalar variable -`value`. - -##### Syntax - -`call [[stdlib_hashmap_wrappers:get_other_scalar(interface)]]( other, value[, exists] )` - -##### Class - -Subroutine. - -##### Arguments - -`other`: shall be a scalar expression of type `other_type`. It -is an `intent(in)` argument. - -`value`: shall be a scalar of type `character(*)`, or of any type of `integer`, -`real` or `complex`, or of any type of `logical`. It is an `intent(out)` argument. - -`exists`: shall be a scalar `logical`. It is an `intent(out)` `optional` +an allocatable of `class(*)`, or a scalar of type `character(*)`, +or of any type of `integer`, `real` or `complex`, or of any type of `logical`. +It is an `intent(out)` argument. + +`exists`: shall be a scalar `logical`. It can be only provided when the +first argument is of `other_type` and the second argument is a scalar of +type `character(*)`, or of any type of `integer`, `real` or `complex`, +or of any type of `logical`. It is an `intent(out)` `optional` argument. #### Result -The provided scalar variable contains the value of the `other_type` if both are of -the same type; otherwise the provided scalar variable is undefined. +When the first argument is of `other_type`, the second argument contains +the value of the `other_type` if both are of the same type; otherwise +the provided scalar variable is undefined. -`exists` is `.true.` if the provided scalar variable and the value of the -`other_type` are of the same type. Otherwise, `exists` is `.false.` +The `logical` `exists` is `.true.` if the provided scalar variable and +the value of the `other_type` are of the same type. Otherwise, `exists` is `.false.` -##### Example +##### Examples +###### Example 1: +```fortran +{!example/hashmaps/example_hashmaps_get.f90!} +``` +###### Example 2: ```fortran {!example/hashmaps/example_hashmaps_get_other_scalar.f90!} ``` diff --git a/example/hashmaps/CMakeLists.txt b/example/hashmaps/CMakeLists.txt index c3962fcfb..1eafbc987 100644 --- a/example/hashmaps/CMakeLists.txt +++ b/example/hashmaps/CMakeLists.txt @@ -9,6 +9,7 @@ ADD_EXAMPLE(hashmaps_free_key) ADD_EXAMPLE(hashmaps_free_other) ADD_EXAMPLE(hashmaps_get) ADD_EXAMPLE(hashmaps_get_other_data) +ADD_EXAMPLE(hashmaps_get_other_scalar) ADD_EXAMPLE(hashmaps_hasher_fun) ADD_EXAMPLE(hashmaps_init) ADD_EXAMPLE(hashmaps_key_test) diff --git a/example/hashmaps/example_hashmaps_get_other_scalar.f90 b/example/hashmaps/example_hashmaps_get_other_scalar.f90 index abc684bd6..b56c0d3bb 100644 --- a/example/hashmaps/example_hashmaps_get_other_scalar.f90 +++ b/example/hashmaps/example_hashmaps_get_other_scalar.f90 @@ -1,13 +1,11 @@ - program example_hashmaps_get_other_scalar - use stdlib_hashmap_wrappers, only: & - get_other_scalar, other_type, set - use stdlib_kinds, only: int32 - implicit none - integer(int32) :: value, result - type(other_type) :: other - value = 15 - call set( other, value ) - call get_other_scalar( other, result ) - print *, 'RESULT == VALUE = ', ( value == result ) - end program demo_get - +program example_hashmaps_get_other_scalar + use stdlib_hashmap_wrappers, only: & + get, other_type, set + implicit none + integer :: value, result + type(other_type) :: other + value = 15 + call set( other, value ) + call get( other, result ) + print *, 'RESULT == VALUE = ', ( result == value ) +end program example_hashmaps_get_other_scalar diff --git a/src/stdlib_hashmap_wrappers.fypp b/src/stdlib_hashmap_wrappers.fypp index 870330c91..0fea7c96f 100755 --- a/src/stdlib_hashmap_wrappers.fypp +++ b/src/stdlib_hashmap_wrappers.fypp @@ -38,7 +38,6 @@ module stdlib_hashmap_wrappers free_key, & free_other, & get, & - get_other_scalar, & hasher_fun, & operator(==), & seeded_nmhash32_hasher, & @@ -98,16 +97,12 @@ module stdlib_hashmap_wrappers get_int8_key, & get_other - end interface get - - interface get_other_scalar - module procedure get_other_scalar_char #:for k1, t1 in IRLC_KINDS_TYPES module procedure get_other_scalar_${t1[0]}$${k1}$ #:endfor - end interface get_other_scalar + end interface get interface operator(==) @@ -281,8 +276,7 @@ contains subroutine get_other_scalar_char(other, value, exists) !! Version: Experimental !! -!! Gets the content of the other as a scalar of a kind provided by stdlib_kinds -!! ([Specifications](../page/specs/stdlib_hashmaps.html#get_other_scalar-extracts-a-scalar-value-from-a-derived-type)) +!! Gets the content of the other as a scalar of a type character(*) class(other_type), intent(in) :: other character(len=:), allocatable, intent(out) :: value logical, intent(out), optional :: exists @@ -311,7 +305,6 @@ contains !! Version: Experimental !! !! Gets the content of the other as a scalar of a kind provided by stdlib_kinds -!! ([Specifications](../page/specs/stdlib_hashmaps.html#get_other_scalar-extracts-a-scalar-value-from-a-derived-type)) class(other_type), intent(in) :: other ${t1}$, intent(out) :: value logical, intent(out), optional :: exists diff --git a/test/hashmaps/test_maps.fypp b/test/hashmaps/test_maps.fypp index 52887e2fc..4940e722f 100644 --- a/test/hashmaps/test_maps.fypp +++ b/test/hashmaps/test_maps.fypp @@ -8,7 +8,7 @@ module test_stdlib_hashmap_wrappers use testdrive, only : new_unittest, unittest_type, error_type, check use stdlib_kinds, only: sp, dp, xdp, qp, int8, int16, int32, int64, lk - use stdlib_hashmap_wrappers, only: other_type, set, get_other_scalar + use stdlib_hashmap_wrappers, only: other_type, set, get implicit none private @@ -46,15 +46,15 @@ contains call set ( other, value_in ) - call get_other_scalar(other, value_out) + call get(other, value_out) - call check(error, value_in, value_out, "get_other_scalar char: value_in not equal to value_out") + call check(error, value_in, value_out, "get char: value_in not equal to value_out") return - call get_other_scalar(other, value_out, exists = exists) - call check(error, value_in, value_out, "get_other_scalar char: value_in not equal to value_out") + call get(other, value_out, exists = exists) + call check(error, value_in, value_out, "get char: value_in not equal to value_out") return - call check(error, exists, "get_other_scalar char: exists should be .true.") + call check(error, exists, "get char: exists should be .true.") end subroutine @@ -70,16 +70,16 @@ contains call set ( other, value_in ) - call get_other_scalar(other, value_out) + call get(other, value_out) - call check(error, value_in, value_out, "get_other_scalar ${k1}$: value_in not equal to value_out") + call check(error, value_in, value_out, "get ${k1}$: value_in not equal to value_out") return - call get_other_scalar(other, value_out, exists = exists) + call get(other, value_out, exists = exists) - call check(error, value_in, value_out, "get_other_scalar ${k1}$: value_in not equal to value_out") + call check(error, value_in, value_out, "get ${k1}$: value_in not equal to value_out") return - call check(error, exists, "get_other_scalar ${k1}$: exists should be .true.") + call check(error, exists, "get ${k1}$: exists should be .true.") return end subroutine @@ -97,16 +97,16 @@ contains call set ( other, value_in ) - call get_other_scalar(other, value_out) + call get(other, value_out) - call check(error, value_in, value_out, "get_other_scalar c${k1}$: value_in not equal to value_out") + call check(error, value_in, value_out, "get c${k1}$: value_in not equal to value_out") return - call get_other_scalar(other, value_out, exists = exists) + call get(other, value_out, exists = exists) - call check(error, value_in, value_out, "get_other_scalar c${k1}$: value_in not equal to value_out") + call check(error, value_in, value_out, "get c${k1}$: value_in not equal to value_out") return - call check(error, exists, "get_other_scalar c${k1}$: exists should be .true.") + call check(error, exists, "get c${k1}$: exists should be .true.") return end subroutine @@ -124,16 +124,16 @@ contains call set ( other, value_in ) - call get_other_scalar(other, value_out) + call get(other, value_out) - call check(error, value_in .eqv. value_out, "get_other_scalar lk: value_in not equal to value_out") + call check(error, value_in .eqv. value_out, "get lk: value_in not equal to value_out") return - call get_other_scalar(other, value_out, exists = exists) + call get(other, value_out, exists = exists) - call check(error, value_in .eqv. value_out, "get_other_scalar lk: value_in not equal to value_out") + call check(error, value_in .eqv. value_out, "get lk: value_in not equal to value_out") return - call check(error, exists, "get_other_scalar lk: exists should be .true.") + call check(error, exists, "get lk: exists should be .true.") return end subroutine From 4d74978d7cf373a909f424a103aa53038fa4c201 Mon Sep 17 00:00:00 2001 From: Jeremie Vandenplas Date: Thu, 4 Aug 2022 15:12:10 -0400 Subject: [PATCH 10/10] Update doc/specs/stdlib_hashmaps.md --- doc/specs/stdlib_hashmaps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/specs/stdlib_hashmaps.md b/doc/specs/stdlib_hashmaps.md index 704455e5a..00568b4f3 100644 --- a/doc/specs/stdlib_hashmaps.md +++ b/doc/specs/stdlib_hashmaps.md @@ -172,7 +172,7 @@ Procedures to manipulate `other_type` data: * `get( other, value )` - extracts the contents of `other` into the `class(*)` variable `value`. -* `get_other_scalar( other, value [, exists])` - extracts the content of +* `get( other, value [, exists])` - extracts the content of `other` into the scalar variable `value` of a kind provided by the module `stdlib_kinds`.