Transfer
Fortran's TRANSFER
function (introduced in Fortran 95) is a somewhat strange function that can be used to do some interesting things not otherwise possible in earlier versions of the language. In fact, it can be used to achieve a sort of poor-man's polymorphism. It can also still be useful in modern Fortran.
All this function does is transfers the bitwise representation of one variable into another variable. This is different from casting a variable of one type to another. For example:
program transfer_example
use iso_fortran_env
integer(int64) :: i
real(real64) :: d
i = 1
d = i !d is 1.0000000000000000
d = transfer(i,d) !d is 4.9406564584124654E-324
end program transfer_example
The following example shows how to use TRANSFER
to create a hash function that can operate on any variable or derived type. The dummy argument of the hash_anything
function is an unlimited polymorphic variable (class(*)
). The bitwise representation of this variable is then transferred into a character string big enough to hold it (making use of the Fortran 2008 STORAGE_SIZE
intrinsic), which can then be hashed using any hash function that takes a character string as an input (a basic DJB method is used here).
module hash_module
!integer kind to use for the hash:
use iso_fortran_env, only: ip => INT32
implicit none
contains
function hash_anything(v) result(hash)
!! Hash anything, using unlimited
!! polymorphic variable and transfer()
class(*),intent(in) :: v
integer(ip) :: hash
!!a default character string
!!with the same size as v:
character(len=ceiling(dble(storage_size(v))/&
dble(storage_size(' ')))) :: str
str = transfer(v,str) !transfer bits of v into
!string of the same size
hash = djb_hash(str) !hash it
end function hash_anything
function djb_hash(str) result(hash)
!! Character string hashing with
!! the DJB algorithm. From [1].
character(len=*),intent(in) :: str
integer(ip) :: hash
integer :: i
hash = 5381_ip
do i=1,len(str)
hash = (ishft(hash,5_ip) + hash) + &
ichar(str(i:i))
end do
end function djb_hash
end module hash_module
See also
- Fortran hashing algorithm, July 6, 2013 [Fortran Dev]
- Hash table example [Fortran Wiki]