dictionary.f90 Source File


This file depends on

sourcefile~~dictionary.f90~~EfferentGraph sourcefile~dictionary.f90 dictionary.f90 sourcefile~variable.f90 variable.f90 sourcefile~dictionary.f90->sourcefile~variable.f90

Contents

Source Code


Source Code

! @LICENSE@, see README.md
! Generic purpose dictionary as in any scripting language
! It has the power to contain any data by using the variable type.
module dictionary
  !! A key-value dictionary module to contain _any_ data in fortran.
  !!
  !! This module implements a generic dictionary-type (`type(dictionary_t)`)
  !! which may contain _any_ data-type using the `variable_t` data-type defined
  !! in `variable`.
  !!
  !! Example:
  !!
  !!```fortran
  !! real :: r
  !! real :: ra(10)
  !! real, target :: rb(10)
  !! type(dictionary_t) :: dict
  !! dict = ('Value'.kv.r)
  !!```
  !!
  use, intrinsic :: iso_c_binding
  use variable
  implicit none
  private
  integer, parameter :: ih = selected_int_kind(4)
  integer, parameter :: is = selected_int_kind(9)
  integer, parameter :: il = selected_int_kind(18)
  integer, parameter :: sp = selected_real_kind(p=6)
  integer, parameter :: dp = selected_real_kind(p=15)
  ! Internal variables for determining the maximum size of the dictionaries.
  ! We could consider changing this to a variable size string
  ! However, that will increase the dependencies and will most likely not yield
  ! a better interface.
  !> Maximum character length of the keys in the dictionary, no
  !! index/key can be longer than this.
  integer, parameter :: DICTIONARY_KEY_LENGTH = 48
  public :: DICTIONARY_KEY_LENGTH
  ! A parameter returned if not found.
  character(len=DICTIONARY_KEY_LENGTH), parameter :: DICTIONARY_NOT_FOUND = 'ERROR: key not found'
  public :: DICTIONARY_NOT_FOUND
  !> The dictionary container it-self
  !!
  !! All contained variables are private.
  type :: dictionary_t
     ! We will keep the dictionary private so that any coding
     ! has to use .KEY. and .VAL. etc.
     type(dictionary_entry_), pointer :: first => null()
     integer :: len = 0
  end type dictionary_t
  public :: dictionary_t
  !> Return the length of a dictionary, by internal counting algorithms
  interface len
     module procedure len_
  end interface
  public :: LEN
  !> Actually count number of elements in the dictionary by forcing the traversing
  interface llen
     module procedure llen_
  end interface
  public :: LLEN
  !> Print out all keys and which data-type it contains as well as the hash-number
  interface print
     module procedure print_
  end interface
  public :: print
  ! Concatenate dicts or list of dicts to list of dicts
  !> Concatenate, or extend, dictionaries, this can
  !! be done on it-self `dic = dic // ('key'.kv.1)
  interface operator( // )
     module procedure d_cat_d
  end interface
  public :: operator( // )
  ! Retrieve the key from a dictionary (unary)
  !> Returns the key of the current _top_ entry,
  interface operator( .KEY. )
     module procedure key
  end interface
  public :: operator(.KEY.)
  ! check whether key exists in dictionary
  !> Returns .true. if the key exists in the dictionary, else returns false.
  interface operator( .IN. )
     module procedure in
  end interface
  public :: operator(.IN.)
  ! check whether key not exists in dictionary
  !> Returns .not. ('key' .in. dict)
  interface operator( .NIN. )
     module procedure nin
  end interface
  public :: operator(.NIN.)
  ! Retrieve the value from a dictionary (unary)
  !> Returns the value from a dictionary by copy
  interface operator( .VAL. )
     module procedure value
  end interface
  public :: operator(.VAL.)
  !> Returns the value from a dictionary by pointer
  interface operator( .VALP. )
     module procedure value_p
  end interface
  public :: operator(.VALP.)
  ! Retrieve the hash value from a dictionary entry (unary)
  interface operator( .HASH. )
     module procedure hash
  end interface
  public :: operator(.HASH.)
  ! Checks for two dicts have all the same keys
  !> Checks whether all keys are the same in two dictionaries.
  interface operator( .EQ. )
     module procedure d_eq_d
  end interface
  public :: operator(.EQ.) ! Overloaded
  ! Checks for two dicts do not share any common keys
  !> Checks whether not all keys are the same in two dictionaries.
  interface operator( .NE. )
     module procedure d_ne_d
  end interface
  public :: operator(.NE.) ! Overloaded
  ! Steps one time in the dictionary (unary)
  !> Looping construct.
  interface operator( .NEXT. )
     module procedure d_next
  end interface
  public :: operator(.NEXT.)
  ! Retrieve the first of a dictionary (unary)
  !> Returns the first entry
  interface operator( .FIRST. )
     module procedure d_first
  end interface
  public :: operator(.FIRST.)
  ! Check whether the dictionary is empty (unary)
  !> Checks if it is an empty dictionary, i.e. no keys exist
  interface operator( .EMPTY. )
     module procedure d_empty
  end interface
  public :: operator(.EMPTY.)
  interface hash_coll
     module procedure hash_coll_
  end interface
  public :: hash_coll
  interface delete
     module procedure delete_
  end interface
  public :: delete
  interface pop
     module procedure pop_
  end interface
  public :: pop
  interface copy
     module procedure copy_
  end interface
  public :: copy
  interface nullify
     module procedure nullify_
     module procedure nullify_key_
  end interface
  public :: nullify
  interface extend
     module procedure sub_d_cat_d
  end interface
  public :: extend
  interface which
     module procedure d_key_which
  end interface
  public :: which
  public :: assign, associate
interface operator(.KV.)
module procedure d_kv_a0_0
module procedure d_kv_var
module procedure d_kv_a1
module procedure d_kv_s0
module procedure d_kv_s1
module procedure d_kv_s2
module procedure d_kv_s3
module procedure d_kv_d0
module procedure d_kv_d1
module procedure d_kv_d2
module procedure d_kv_d3
module procedure d_kv_c0
module procedure d_kv_c1
module procedure d_kv_c2
module procedure d_kv_c3
module procedure d_kv_z0
module procedure d_kv_z1
module procedure d_kv_z2
module procedure d_kv_z3
module procedure d_kv_b0
module procedure d_kv_b1
module procedure d_kv_b2
module procedure d_kv_b3
module procedure d_kv_h0
module procedure d_kv_h1
module procedure d_kv_h2
module procedure d_kv_h3
module procedure d_kv_i0
module procedure d_kv_i1
module procedure d_kv_i2
module procedure d_kv_i3
module procedure d_kv_l0
module procedure d_kv_l1
module procedure d_kv_l2
module procedure d_kv_l3
module procedure d_kv_cp0
module procedure d_kv_cp1
module procedure d_kv_fp0
module procedure d_kv_fp1
end interface
interface operator(.KVP.)
module procedure d_kvp_var
module procedure d_kvp_dict
module procedure d_kvp_a1
module procedure d_kvp_s0
module procedure d_kvp_s1
module procedure d_kvp_s2
module procedure d_kvp_s3
module procedure d_kvp_d0
module procedure d_kvp_d1
module procedure d_kvp_d2
module procedure d_kvp_d3
module procedure d_kvp_c0
module procedure d_kvp_c1
module procedure d_kvp_c2
module procedure d_kvp_c3
module procedure d_kvp_z0
module procedure d_kvp_z1
module procedure d_kvp_z2
module procedure d_kvp_z3
module procedure d_kvp_b0
module procedure d_kvp_b1
module procedure d_kvp_b2
module procedure d_kvp_b3
module procedure d_kvp_h0
module procedure d_kvp_h1
module procedure d_kvp_h2
module procedure d_kvp_h3
module procedure d_kvp_i0
module procedure d_kvp_i1
module procedure d_kvp_i2
module procedure d_kvp_i3
module procedure d_kvp_l0
module procedure d_kvp_l1
module procedure d_kvp_l2
module procedure d_kvp_l3
module procedure d_kvp_cp0
module procedure d_kvp_cp1
module procedure d_kvp_fp0
module procedure d_kvp_fp1
end interface
interface assign
module procedure d_get_val
module procedure d_get_val_a_
module procedure d_get_val_a1
module procedure d_get_val_first_a1
module procedure d_get_val_s0
module procedure d_get_val_first_s0
module procedure d_get_val_s1
module procedure d_get_val_first_s1
module procedure d_get_val_s2
module procedure d_get_val_first_s2
module procedure d_get_val_s3
module procedure d_get_val_first_s3
module procedure d_get_val_d0
module procedure d_get_val_first_d0
module procedure d_get_val_d1
module procedure d_get_val_first_d1
module procedure d_get_val_d2
module procedure d_get_val_first_d2
module procedure d_get_val_d3
module procedure d_get_val_first_d3
module procedure d_get_val_c0
module procedure d_get_val_first_c0
module procedure d_get_val_c1
module procedure d_get_val_first_c1
module procedure d_get_val_c2
module procedure d_get_val_first_c2
module procedure d_get_val_c3
module procedure d_get_val_first_c3
module procedure d_get_val_z0
module procedure d_get_val_first_z0
module procedure d_get_val_z1
module procedure d_get_val_first_z1
module procedure d_get_val_z2
module procedure d_get_val_first_z2
module procedure d_get_val_z3
module procedure d_get_val_first_z3
module procedure d_get_val_b0
module procedure d_get_val_first_b0
module procedure d_get_val_b1
module procedure d_get_val_first_b1
module procedure d_get_val_b2
module procedure d_get_val_first_b2
module procedure d_get_val_b3
module procedure d_get_val_first_b3
module procedure d_get_val_h0
module procedure d_get_val_first_h0
module procedure d_get_val_h1
module procedure d_get_val_first_h1
module procedure d_get_val_h2
module procedure d_get_val_first_h2
module procedure d_get_val_h3
module procedure d_get_val_first_h3
module procedure d_get_val_i0
module procedure d_get_val_first_i0
module procedure d_get_val_i1
module procedure d_get_val_first_i1
module procedure d_get_val_i2
module procedure d_get_val_first_i2
module procedure d_get_val_i3
module procedure d_get_val_first_i3
module procedure d_get_val_l0
module procedure d_get_val_first_l0
module procedure d_get_val_l1
module procedure d_get_val_first_l1
module procedure d_get_val_l2
module procedure d_get_val_first_l2
module procedure d_get_val_l3
module procedure d_get_val_first_l3
module procedure d_get_val_cp0
module procedure d_get_val_first_cp0
module procedure d_get_val_cp1
module procedure d_get_val_first_cp1
module procedure d_get_val_fp0
module procedure d_get_val_first_fp0
module procedure d_get_val_fp1
module procedure d_get_val_first_fp1
end interface
interface associate
module procedure d_get_p_val
module procedure d_get_p_dict
module procedure d_get_p_a1
module procedure d_get_p_first_a1
module procedure d_get_p_s0
module procedure d_get_p_first_s0
module procedure d_get_p_s1
module procedure d_get_p_first_s1
module procedure d_get_p_s2
module procedure d_get_p_first_s2
module procedure d_get_p_s3
module procedure d_get_p_first_s3
module procedure d_get_p_d0
module procedure d_get_p_first_d0
module procedure d_get_p_d1
module procedure d_get_p_first_d1
module procedure d_get_p_d2
module procedure d_get_p_first_d2
module procedure d_get_p_d3
module procedure d_get_p_first_d3
module procedure d_get_p_c0
module procedure d_get_p_first_c0
module procedure d_get_p_c1
module procedure d_get_p_first_c1
module procedure d_get_p_c2
module procedure d_get_p_first_c2
module procedure d_get_p_c3
module procedure d_get_p_first_c3
module procedure d_get_p_z0
module procedure d_get_p_first_z0
module procedure d_get_p_z1
module procedure d_get_p_first_z1
module procedure d_get_p_z2
module procedure d_get_p_first_z2
module procedure d_get_p_z3
module procedure d_get_p_first_z3
module procedure d_get_p_b0
module procedure d_get_p_first_b0
module procedure d_get_p_b1
module procedure d_get_p_first_b1
module procedure d_get_p_b2
module procedure d_get_p_first_b2
module procedure d_get_p_b3
module procedure d_get_p_first_b3
module procedure d_get_p_h0
module procedure d_get_p_first_h0
module procedure d_get_p_h1
module procedure d_get_p_first_h1
module procedure d_get_p_h2
module procedure d_get_p_first_h2
module procedure d_get_p_h3
module procedure d_get_p_first_h3
module procedure d_get_p_i0
module procedure d_get_p_first_i0
module procedure d_get_p_i1
module procedure d_get_p_first_i1
module procedure d_get_p_i2
module procedure d_get_p_first_i2
module procedure d_get_p_i3
module procedure d_get_p_first_i3
module procedure d_get_p_l0
module procedure d_get_p_first_l0
module procedure d_get_p_l1
module procedure d_get_p_first_l1
module procedure d_get_p_l2
module procedure d_get_p_first_l2
module procedure d_get_p_l3
module procedure d_get_p_first_l3
module procedure d_get_p_cp0
module procedure d_get_p_first_cp0
module procedure d_get_p_cp1
module procedure d_get_p_first_cp1
module procedure d_get_p_fp0
module procedure d_get_p_first_fp0
module procedure d_get_p_fp1
module procedure d_get_p_first_fp1
end interface
  ! Create a dict type: 'key' .KV. 'val'
  public :: operator(.KV.)
  ! Create a dict type: 'key' .KVP. 'pointer'
  public :: operator(.KVP.)
  ! We need to create a linked list to create arbitrarily long dictionaries...
  ! The dictionary entry is not visible outside.
  type :: dictionary_entry_
     character(len=DICTIONARY_KEY_LENGTH) :: key = ' '
     ! in order to extend the dictionary to contain a dictionary
     ! we simply need to add the dictionary type to the variable
     ! library.
     type(variable_t) :: value
     integer :: hash = 0
     type(dictionary_entry_), pointer :: next => null()
  end type dictionary_entry_
contains
  pure function hash_val(key) result(val)
    character(len=*), intent(in) :: key
    integer :: val
    integer :: i
    ! This is 32-bit integers, hence a 32-bit hash
    integer, parameter :: FNV_OFF = 28491 ! see crt_hash_basis.f90
    integer, parameter :: FNV_PRIME = 16777619
    integer, parameter :: MAX_32 = huge(1)
    ! Initialize by the FNV_OFF hash for 32 bit
    val = FNV_OFF
    do i = 1 , min(DICTIONARY_KEY_LENGTH,len_trim(key))
       val = ieor(val,iachar(key(i:i)))
       val = mod(val * FNV_PRIME, MAX_32)
    end do
  end function hash_val
  pure function new_d_key(key) result(d)
    character(len=*), intent(in) :: key
    type(dictionary_t) :: d
    allocate(d%first)
    if ( len_trim(key) > DICTIONARY_KEY_LENGTH ) then
       d%first%key = key(1:DICTIONARY_KEY_LENGTH)
    else
       d%first%key = trim(key)
    end if
    d%first%hash = hash_val(key)
    d%len = 1
    nullify(d%first%next)
  end function new_d_key
  ! Retrieves the key value in a dictionary type (or a list)
  ! We expect that the key will only be called on single element dictionaries...
  pure function key(d)
    type(dictionary_t), intent(in) :: d
    character(len=DICTIONARY_KEY_LENGTH) :: key
    key = d%first%key
  end function key
  ! Retrieves the value value in a dictionary type (or a list)
  function value(d)
    type(dictionary_t), intent(in) :: d
    type(variable_t) :: value
    call assign(value,d%first%value)
  end function value
  function value_p(d)
    type(dictionary_t), intent(in) :: d
    type(variable_t) :: value_p
    call associate(value_p,d%first%value)
  end function value_p
  ! Returns the hash value of the dictionary first item...
  pure function hash(d)
    type(dictionary_t), intent(in) :: d
    integer :: hash
    hash = d%first%hash
  end function hash
  ! Returns number of collisions in the hash-table
  ! The optional keyword 'max' can be used to
  ! extract the maximum number of collisions for
  ! one hash-value (i.e. not total collisions).
  function hash_coll_(this,max) result(col)
    type(dictionary_t), intent(inout) :: this
    logical, intent(in), optional :: max
    integer :: col
    integer :: chash, max_now, same
    type(dictionary_entry_), pointer :: ld
    col = 0
    if ( .empty. this ) return
    ! Initialize
    same = 0
    max_now = 0
    ld => this%first
    chash = ld%hash
    do while ( associated(ld) )
       if ( chash == ld%hash ) then
          ! total collisions
          col = col + 1
          ! count total current collisions
          max_now = max_now + 1
       else
          chash = ld%hash
          if ( max_now > same ) then
             same = max_now
          end if
          max_now = 0
       end if
       ld => ld%next
    end do
    ! If the user requests maximum collisions
    ! for any given hash value
    if ( present(max) ) then
       if ( max ) col = same
    end if
    ! return col
  end function hash_coll_
  function in(key,d)
    character(len=*), intent(in) :: key
    type(dictionary_t), intent(in) :: d
    type(dictionary_t) :: ld
    integer :: hash, lhash
    logical :: in
    hash = hash_val(key)
    ld = .first. d
    search: do while ( .not. (.empty. ld) )
       lhash = .hash. ld
       if ( hash > lhash ) then
          ! skip to next search
       else if ( hash < lhash ) then
          exit search
       else if ( hash == lhash ) then
          if ( key .eq. .KEY. ld ) then
             in = .true.
             return
          end if
       end if
       ld = .next. ld
    end do search
    in = .false.
  end function in
  function nin(key,d)
    character(len=*), intent(in) :: key
    type(dictionary_t), intent(in) :: d
    logical :: nin
    nin = .not. in(key,d)
  end function nin
  ! Compares two dict types against each other
  ! Will do comparison by hash.
  function d_eq_d(d1,d2) result(bool)
    type(dictionary_t), intent(in) :: d1,d2
    logical :: bool
    type(dictionary_t) :: tmp1, tmp2
    bool = len(d1) == len(d2)
    if ( .not. bool ) return
    bool = .hash. d1 == .hash. d2
    if ( .not. bool ) return
    ! if all the keys are going to be the same
    ! the we know that the hash-tags are going to
    ! be the same... :)
    tmp1 = .first. d1
    tmp2 = .first. d2
    do while ( .not. (.empty. tmp1) )
       bool = .hash. tmp1 == .hash. tmp2
       if ( .not. bool ) return
       tmp1 = .next. tmp1
       tmp2 = .next. tmp2
    end do
  end function d_eq_d
  ! Compares two dict types against each other
  ! not necessarily the negative of .eq.
  function d_ne_d(d1,d2) result(bool)
    type(dictionary_t), intent(in) :: d1,d2
    logical :: bool
    type(dictionary_t) :: tmp1, tmp2
    tmp1 = .first. d1
    do while ( .not. (.empty. tmp1) )
       tmp2 = .first. d2
       do while ( .not. (.empty. tmp2) )
          bool = .hash. tmp1 == .hash. tmp2
          if ( bool ) then
             bool = .false.
             return
          end if
          tmp2 = .next. tmp2
       end do
       tmp1 = .next. tmp1
    end do
  end function d_ne_d
  ! Concatenate two dictionaries to one dictionary...
  ! it does not work with elemental as the
  function d_cat_d(d1,d2) result(d)
    type(dictionary_t), intent(in) :: d1,d2
    type(dictionary_t) :: d
    if ( .empty. d1 ) then
       if ( .empty. d2 ) return
       call copy_assign(d2,d)
       return
    end if
    call copy_assign(d1,d)
    call sub_d_cat_d(d,d2)
  end function d_cat_d
  ! Concatenate two dictionaries to one dictionary...
  ! it does not work with elemental as the
  subroutine sub_d_cat_d(d,d2)
    type(dictionary_t), intent(inout) :: d
    type(dictionary_t), intent(in) :: d2
    type(dictionary_entry_), pointer :: ladd, lnext
    type(dictionary_t) :: fd
    integer :: kh
    if ( .empty. d ) then
       if ( .empty. d2 ) return
       call copy_assign(d2,d)
       return
    end if
    if ( .empty. d2 ) return
    ladd => d2%first
    fd%len = 0
    fd%first => d%first
    do
       ! step ...
       lnext => ladd%next ! we need to get the next
       kh = fd%first%hash
       ! before it gets deassociated
       call d_insert(fd,ladd)
       ! Now if the hash has changed it means
       ! that the algorithm has put the new
       ! key in front of the first one.
       ! As this can ONLY occur once
       ! we know that it must be before
       ! the d%first as well.
       ! We hence update d%first and
       ! do not update the fd%first as it points correctly.
       if ( kh /= fd%first%hash ) then
          d%first => fd%first
       else
          ! The hash table has not been updated.
          ! Thus the key has been added afterwards
          ! and we can safely step in the
          ! linked list wîth our fake dictionary.
          ! In case the hash values are equivalent
          ! then the key will be put in sequence
          ! of arrival, and thus a deterministic pattern
          ! is achieved.
          fd%first => ladd
       end if
       if ( .not. associated(lnext) ) exit
       ladd => lnext
    end do
    d%len = d%len + fd%len
  end subroutine sub_d_cat_d
  subroutine d_insert(d,entry)
    type(dictionary_t), intent(inout) :: d
    type(dictionary_entry_), intent(inout), pointer :: entry
    type(dictionary_entry_), pointer :: search, prev
    ! if the dictionary is empty
    ! simply put it first
    if ( .not. associated(d%first) ) then
       d%first => entry
       d%len = 1
       return
    end if
    nullify(prev)
    ! Initialize search...
    search => d%first
    ! The easy case...
    if ( search%hash > entry%hash ) then
       entry%next => d%first
       d%first => entry
       d%len = d%len + 1
       return
    else if ( search%hash == entry%hash ) then
       ! If the key already exists we will simply overwrite
       if ( search%key == entry%key ) then
          call assign(search%value,entry%value)
          return
       end if
    end if
    search_loop: do
       ! step...
       prev => search
       ! step...
       search => prev%next
       if ( .not. associated(search) ) exit search_loop
       if ( search%hash > entry%hash ) then
          prev%next => entry
          entry%next => search
          d%len = d%len + 1
          return
       else if ( search%hash == entry%hash ) then
          ! If the key already exists we will simply overwrite
          if ( search%key == entry%key ) then
             call assign(search%value,entry%value)
             return
          end if
       end if
    end do search_loop
    prev%next => entry
    ! Increment length of the dictionary...
    d%len = d%len + 1
    ! As we could insert from a dictionary we have to reset, to not do endless loops...
    nullify(entry%next)
  end subroutine d_insert
  !> Generate the copy routine
  subroutine copy_(from, to)
    type(dictionary_t), intent(in) :: from
    type(dictionary_t), intent(inout) :: to
    type(dictionary_entry_), pointer :: d
    type(variable_t) :: v
    ! Delete the dictionary
    call delete(to)
    d => from%first
    do while ( associated(d) )
       ! Associate data...
       call associate(v, d%value)
       ! Copy data, hence .kv.
       to = to
       d => d%next
    end do
    ! Clean up pointers...
    call nullify(v)
    nullify(d)
  end subroutine copy_
  ! Retrieve the length of the dictionary...
  pure function len_(d)
    type(dictionary_t), intent(in) :: d
    integer :: len_
    len_ = d%len
  end function len_
  function llen_(this)
    type(dictionary_t), intent(inout) :: this
    type(dictionary_entry_), pointer :: d
    integer :: llen_
    llen_ = 0
    d => this%first
    do while ( associated(d) )
       llen_ = llen_ + 1
       d => d%next
    end do
  end function llen_
  function d_next(d)
    type(dictionary_t), intent(in) :: d
    type(dictionary_t) :: d_next
    d_next%first => d%first%next
    d_next%len = d%len - 1
  end function d_next
  pure function d_empty(d)
    type(dictionary_t), intent(in) :: d
    logical :: d_empty
    d_empty = .not. associated(d%first)
  end function d_empty
  function d_first(d)
    type(dictionary_t), intent(in) :: d
    type(dictionary_t) :: d_first
    call copy_assign(d,d_first)
  end function d_first
  subroutine copy_assign(din,dcopy)
    type(dictionary_t), intent(in) :: din
    type(dictionary_t), intent(inout) :: dcopy
    dcopy%first => din%first
    dcopy%len = din%len
  end subroutine copy_assign
  subroutine print_(d)
    type(dictionary_t), intent(in) :: d
    type(dictionary_t) :: ld
    ld = .first. d
    do while ( .not. .empty. ld )
       write(*,'(t2,a,tr1,a,i0,a)') trim(.key. ld), &
            '['//trim(ld%first%value%t)//'] (',.hash. ld,')'
       ld = .next. ld
    end do
  end subroutine print_
  subroutine delete_(this,key,dealloc)
    type(dictionary_t), intent(inout) :: this
    character(len=*), intent(in), optional :: key
    logical, intent(in), optional :: dealloc
    type(dictionary_entry_), pointer :: de, pr
    logical :: ldealloc
    integer :: kh
    ! We default to de-allocation of everything
    ldealloc = .true.
    if ( present(dealloc) ) ldealloc = dealloc
    ! if no keys are present, simply return
    if ( .not. associated(this%first) ) then
       this%len = 0
       return
    end if
    if ( present(key) ) then
       ! we only need to delete the one key
       kh = hash_val(key)
       pr => this%first
       if ( kh == pr%hash ) then
          if ( key == pr%key ) then
             this%first => pr%next
             this%len = this%len - 1
             call delete(pr%value,dealloc=ldealloc)
             nullify(pr%next)
             deallocate(pr)
             nullify(pr)
             return
          end if
       end if
       ! more complicated case
       de => pr%next
       do while ( associated(de) )
          ! We know it is sorted with hash-tags.
          ! So if we are beyond the hash, we just quit.
          if ( kh < de%hash ) exit ! it does not exist
          if ( de%hash == kh ) then
             if ( de%key == key ) then
                pr%next => de%next
                call delete(de%value,dealloc=ldealloc)
                nullify(de%next)
                deallocate(de)
                this%len = this%len - 1
                exit
             end if
          end if
          pr => de
          de => de%next
       end do
       return
    end if
    ! delete the entire entry-tree
    call del_dictionary_entry__tree(this%first,dealloc=ldealloc)
    call delete(this%first%value,dealloc=ldealloc)
    deallocate(this%first)
    nullify(this%first)
    this%len = 0
  contains
    recursive subroutine del_dictionary_entry__tree(d,dealloc)
      type(dictionary_entry_), pointer :: d
      logical, intent(in) :: dealloc
      if ( associated(d) ) then
         if ( associated(d%next) ) then
            call del_dictionary_entry__tree(d%next,dealloc)
            call delete(d%next%value,dealloc=dealloc)
            deallocate(d%next)
            nullify(d%next)
         end if
      end if
    end subroutine del_dictionary_entry__tree
  end subroutine delete_
  subroutine pop_(val,this,key,dealloc)
    type(variable_t), intent(inout) :: val
    type(dictionary_t), intent(inout) :: this
    character(len=*), intent(in) :: key
    logical, intent(in), optional :: dealloc
    type(dictionary_entry_), pointer :: de, pr
    ! Here the default is to de-allocate
    ! even though we use the association feature
    ! Hence, we need a variable here
    logical :: ldealloc
    integer :: kh
    ldealloc = .true.
    if ( present(dealloc) ) ldealloc = dealloc
    ! if no keys are present, simply return
    if ( .not. associated(this%first) ) then
       this%len = 0
       call val_delete_request(val,dealloc=ldealloc)
       return
    end if
    pr => this%first
    if ( pr%key == key ) then
       this%first => pr%next
       call associate(val,pr%value,dealloc=ldealloc)
       ! Ensures that the encoding gets removed
       call nullify(pr%value)
       deallocate(pr)
       this%len = this%len - 1
       return
    end if
    kh = hash_val(key)
    de => pr%next
    do while ( associated(de) )
       ! Check if even exists
       if ( kh < de%hash ) exit
       if ( kh == de%hash ) then
          if ( de%key == key ) then
             pr%next => de%next
             call associate(val,de%value,dealloc=ldealloc)
             ! Ensures that the encoding gets removed
             call nullify(de%value)
             deallocate(de)
             this%len = this%len - 1
             exit
          end if
       end if
       pr => de
       de => de%next
    end do
  end subroutine pop_
  elemental subroutine nullify_key_(this,key)
    type(dictionary_t), intent(inout) :: this
    character(len=*), intent(in) :: key
    type(dictionary_entry_), pointer :: de, pr
    integer :: kh
    ! if no keys are present, simply return
    if ( .not. associated(this%first) ) then
       this%len = 0
       return
    end if
    pr => this%first
    if ( pr%key == key ) then
       this%first => pr%next
       ! Ensures that the encoding gets removed
       call nullify(pr%value)
       deallocate(pr)
       this%len = this%len - 1
       return
    end if
    kh = hash_val(key)
    de => pr%next
    do while ( associated(de) )
       ! Check if even exists
       if ( kh < de%hash ) exit
       if ( kh == de%hash ) then
          if ( de%key == key ) then
             pr%next => de%next
             ! Ensures that the encoding gets removed
             call nullify(de%value)
             deallocate(de)
             this%len = this%len - 1
             exit
          end if
       end if
       pr => de
       de => de%next
    end do
  end subroutine nullify_key_
  elemental subroutine nullify_(this)
    type(dictionary_t), intent(inout) :: this
    ! This will simply nullify the dictionary, thereby
    ! remove all references to all objects.
    nullify(this%first)
    this%len = 0
  end subroutine nullify_
  subroutine d_get_val(val,d,key,dealloc)
    type(variable_t), intent(inout) :: val
    type(dictionary_t), intent(inout) :: d
    character(len=*), intent(in), optional :: key
    logical, intent(in), optional :: dealloc
    type(dictionary_t) :: ld
    integer :: hash, lhash
    if ( .not. present(key) ) then
       if ( .not. (.empty. d) ) then
          call assign(val,d%first%value,dealloc=dealloc)
       else
          call val_delete_request(val,dealloc=dealloc)
       end if
       return
    end if
    hash = hash_val(key)
    ld = .first. d
    search: do while ( .not. (.empty. ld) )
       lhash = .hash. ld
       if ( hash > lhash ) then
          ! skip to next search
       else if ( hash < lhash ) then
          ! the key does not exist, delete if requested, else clean it
          call val_delete_request(val,dealloc=dealloc)
          exit search
       else if ( hash == lhash ) then
          if ( key .eq. .KEY. ld ) then
             call assign(val,ld%first%value,dealloc=dealloc)
             return
          end if
       end if
       ld = .next. ld
    end do search
  end subroutine d_get_val
  subroutine d_get_p_val(val,d,key,dealloc)
    type(variable_t), intent(inout) :: val
    type(dictionary_t), intent(inout) :: d
    character(len=*), intent(in), optional :: key
    logical, intent(in), optional :: dealloc
    type(dictionary_t) :: ld
    integer :: hash, lhash
    if ( .not. present(key) ) then
       if ( .not. (.empty. d) ) then
          call associate(val,d%first%value,dealloc=dealloc)
       else
          call val_delete_request(val,dealloc=dealloc)
       end if
       return
    end if
    hash = hash_val(key)
    ld = .first. d
    search: do while ( .not. (.empty. ld) )
       lhash = .hash. ld
       if ( hash > lhash ) then
          ! skip to next search
       else if ( hash < lhash ) then
          ! the key does not exist, delete if requested, else clean it
          call val_delete_request(val,dealloc=dealloc)
          exit search
       else if ( hash == lhash ) then
          if ( key .eq. .KEY. ld ) then
             call associate(val,ld%first%value,dealloc=dealloc)
             return
          end if
       end if
       ld = .next. ld
    end do search
  end subroutine d_get_p_val
  subroutine d_get_val_a_(val,d,key,dealloc)
    character(len=*), intent(out) :: val
    type(dictionary_t), intent(inout) :: d
    character(len=*), intent(in), optional :: key
    logical, intent(in), optional :: dealloc
    type(variable_t) :: v
    type(dictionary_t) :: ld
    integer :: hash, lhash
    val = ' '
    if ( .not. present(key) ) then
       if ( .not. (.empty. d) ) then
          call associate(v,d%first%value)
       end if
       return
    end if
    hash = hash_val(key)
    ld = .first. d
    search: do while ( .not. (.empty. ld) )
       lhash = .hash. ld
       if ( hash > lhash ) then
          ! skip to next search
       else if ( hash < lhash ) then
          exit search
       else if ( hash == lhash ) then
          if ( key .eq. .KEY. ld ) then
             call assign(val, ld%first%value)
             return
          end if
       end if
       ld = .next. ld
    end do search
  end subroutine d_get_val_a_
  function d_kv_a0_0(key,val) result(this)
    character(len=*), intent(in) :: key
    character(len=*), intent(in) :: val
    type(dictionary_t) :: this
    this = new_d_key(key)
    call assign(this%first%value,val)
  end function d_kv_a0_0
  function d_kv_var(key,val) result(this)
    character(len=*), intent(in) :: key
    type(variable_t), intent(in) :: val
    type(dictionary_t) :: this
    this = new_d_key(key)
    call assign(this%first%value,val)
  end function d_kv_var
  function d_kvp_var(key,val) result(this)
    character(len=*), intent(in) :: key
    type(variable_t), intent(in) :: val
    type(dictionary_t) :: this
    this = new_d_key(key)
    call associate(this%first%value,val)
  end function d_kvp_var
  function d_key_which(this,key) result(t)
    type(dictionary_t), intent(in) :: this
    character(len=*), optional, intent(in) :: key
    character(len=VARIABLE_TYPE_LENGTH) :: t
    type(dictionary_t) :: ld
    integer :: hash, lhash
    if ( present(key) ) then
       hash = hash_val(key)
       ld = .first. this
       search: do while ( .not. (.empty. ld) )
          lhash = .hash. ld
          if ( hash > lhash ) then
            ! skip to next search
          else if ( hash < lhash ) then
             t = '  '
             exit search
          else if ( hash == lhash ) then
             if ( key .eq. .KEY. ld ) then
                t = which(ld%first%value)
                return
             end if
          end if
          ld = .next. ld
       end do search
    else
       t = which(this%first%value)
    end if
  end function d_key_which
function d_kv_a1(key,val) result(this)
character(len=*), intent(in) :: key
character(len=1), intent(in), dimension(:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_a1
function d_kvp_a1(key, val) result(this)
character(len=*), intent(in) :: key
character(len=1), intent(in), dimension(:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_a1
subroutine d_get_val_a1(val,this,key,success)
character(len=1), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_a1
subroutine d_get_val_first_a1(val,this,success)
character(len=1), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_a1
subroutine d_get_p_a1(val,this,key,success)
character(len=1), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_a1
subroutine d_get_p_first_a1(val,this,success)
character(len=1), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_a1
function d_kv_s0(key,val) result(this)
character(len=*), intent(in) :: key
real(sp), intent(in) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_s0
function d_kvp_s0(key, val) result(this)
character(len=*), intent(in) :: key
real(sp), intent(in), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_s0
subroutine d_get_val_s0(val,this,key,success)
real(sp), intent(out) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_s0
subroutine d_get_val_first_s0(val,this,success)
real(sp), intent(out) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_s0
subroutine d_get_p_s0(val,this,key,success)
real(sp), pointer :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_s0
subroutine d_get_p_first_s0(val,this,success)
real(sp), pointer :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_s0
function d_kv_s1(key,val) result(this)
character(len=*), intent(in) :: key
real(sp), intent(in), dimension(:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_s1
function d_kvp_s1(key, val) result(this)
character(len=*), intent(in) :: key
real(sp), intent(in), dimension(:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_s1
subroutine d_get_val_s1(val,this,key,success)
real(sp), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_s1
subroutine d_get_val_first_s1(val,this,success)
real(sp), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_s1
subroutine d_get_p_s1(val,this,key,success)
real(sp), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_s1
subroutine d_get_p_first_s1(val,this,success)
real(sp), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_s1
function d_kv_s2(key,val) result(this)
character(len=*), intent(in) :: key
real(sp), intent(in), dimension(:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_s2
function d_kvp_s2(key, val) result(this)
character(len=*), intent(in) :: key
real(sp), intent(in), dimension(:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_s2
subroutine d_get_val_s2(val,this,key,success)
real(sp), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_s2
subroutine d_get_val_first_s2(val,this,success)
real(sp), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_s2
subroutine d_get_p_s2(val,this,key,success)
real(sp), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_s2
subroutine d_get_p_first_s2(val,this,success)
real(sp), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_s2
function d_kv_s3(key,val) result(this)
character(len=*), intent(in) :: key
real(sp), intent(in), dimension(:,:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_s3
function d_kvp_s3(key, val) result(this)
character(len=*), intent(in) :: key
real(sp), intent(in), dimension(:,:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_s3
subroutine d_get_val_s3(val,this,key,success)
real(sp), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_s3
subroutine d_get_val_first_s3(val,this,success)
real(sp), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_s3
subroutine d_get_p_s3(val,this,key,success)
real(sp), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_s3
subroutine d_get_p_first_s3(val,this,success)
real(sp), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_s3
function d_kv_d0(key,val) result(this)
character(len=*), intent(in) :: key
real(dp), intent(in) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_d0
function d_kvp_d0(key, val) result(this)
character(len=*), intent(in) :: key
real(dp), intent(in), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_d0
subroutine d_get_val_d0(val,this,key,success)
real(dp), intent(out) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_d0
subroutine d_get_val_first_d0(val,this,success)
real(dp), intent(out) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_d0
subroutine d_get_p_d0(val,this,key,success)
real(dp), pointer :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_d0
subroutine d_get_p_first_d0(val,this,success)
real(dp), pointer :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_d0
function d_kv_d1(key,val) result(this)
character(len=*), intent(in) :: key
real(dp), intent(in), dimension(:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_d1
function d_kvp_d1(key, val) result(this)
character(len=*), intent(in) :: key
real(dp), intent(in), dimension(:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_d1
subroutine d_get_val_d1(val,this,key,success)
real(dp), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_d1
subroutine d_get_val_first_d1(val,this,success)
real(dp), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_d1
subroutine d_get_p_d1(val,this,key,success)
real(dp), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_d1
subroutine d_get_p_first_d1(val,this,success)
real(dp), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_d1
function d_kv_d2(key,val) result(this)
character(len=*), intent(in) :: key
real(dp), intent(in), dimension(:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_d2
function d_kvp_d2(key, val) result(this)
character(len=*), intent(in) :: key
real(dp), intent(in), dimension(:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_d2
subroutine d_get_val_d2(val,this,key,success)
real(dp), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_d2
subroutine d_get_val_first_d2(val,this,success)
real(dp), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_d2
subroutine d_get_p_d2(val,this,key,success)
real(dp), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_d2
subroutine d_get_p_first_d2(val,this,success)
real(dp), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_d2
function d_kv_d3(key,val) result(this)
character(len=*), intent(in) :: key
real(dp), intent(in), dimension(:,:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_d3
function d_kvp_d3(key, val) result(this)
character(len=*), intent(in) :: key
real(dp), intent(in), dimension(:,:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_d3
subroutine d_get_val_d3(val,this,key,success)
real(dp), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_d3
subroutine d_get_val_first_d3(val,this,success)
real(dp), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_d3
subroutine d_get_p_d3(val,this,key,success)
real(dp), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_d3
subroutine d_get_p_first_d3(val,this,success)
real(dp), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_d3
function d_kv_c0(key,val) result(this)
character(len=*), intent(in) :: key
complex(sp), intent(in) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_c0
function d_kvp_c0(key, val) result(this)
character(len=*), intent(in) :: key
complex(sp), intent(in), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_c0
subroutine d_get_val_c0(val,this,key,success)
complex(sp), intent(out) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_c0
subroutine d_get_val_first_c0(val,this,success)
complex(sp), intent(out) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_c0
subroutine d_get_p_c0(val,this,key,success)
complex(sp), pointer :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_c0
subroutine d_get_p_first_c0(val,this,success)
complex(sp), pointer :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_c0
function d_kv_c1(key,val) result(this)
character(len=*), intent(in) :: key
complex(sp), intent(in), dimension(:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_c1
function d_kvp_c1(key, val) result(this)
character(len=*), intent(in) :: key
complex(sp), intent(in), dimension(:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_c1
subroutine d_get_val_c1(val,this,key,success)
complex(sp), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_c1
subroutine d_get_val_first_c1(val,this,success)
complex(sp), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_c1
subroutine d_get_p_c1(val,this,key,success)
complex(sp), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_c1
subroutine d_get_p_first_c1(val,this,success)
complex(sp), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_c1
function d_kv_c2(key,val) result(this)
character(len=*), intent(in) :: key
complex(sp), intent(in), dimension(:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_c2
function d_kvp_c2(key, val) result(this)
character(len=*), intent(in) :: key
complex(sp), intent(in), dimension(:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_c2
subroutine d_get_val_c2(val,this,key,success)
complex(sp), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_c2
subroutine d_get_val_first_c2(val,this,success)
complex(sp), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_c2
subroutine d_get_p_c2(val,this,key,success)
complex(sp), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_c2
subroutine d_get_p_first_c2(val,this,success)
complex(sp), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_c2
function d_kv_c3(key,val) result(this)
character(len=*), intent(in) :: key
complex(sp), intent(in), dimension(:,:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_c3
function d_kvp_c3(key, val) result(this)
character(len=*), intent(in) :: key
complex(sp), intent(in), dimension(:,:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_c3
subroutine d_get_val_c3(val,this,key,success)
complex(sp), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_c3
subroutine d_get_val_first_c3(val,this,success)
complex(sp), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_c3
subroutine d_get_p_c3(val,this,key,success)
complex(sp), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_c3
subroutine d_get_p_first_c3(val,this,success)
complex(sp), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_c3
function d_kv_z0(key,val) result(this)
character(len=*), intent(in) :: key
complex(dp), intent(in) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_z0
function d_kvp_z0(key, val) result(this)
character(len=*), intent(in) :: key
complex(dp), intent(in), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_z0
subroutine d_get_val_z0(val,this,key,success)
complex(dp), intent(out) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_z0
subroutine d_get_val_first_z0(val,this,success)
complex(dp), intent(out) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_z0
subroutine d_get_p_z0(val,this,key,success)
complex(dp), pointer :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_z0
subroutine d_get_p_first_z0(val,this,success)
complex(dp), pointer :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_z0
function d_kv_z1(key,val) result(this)
character(len=*), intent(in) :: key
complex(dp), intent(in), dimension(:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_z1
function d_kvp_z1(key, val) result(this)
character(len=*), intent(in) :: key
complex(dp), intent(in), dimension(:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_z1
subroutine d_get_val_z1(val,this,key,success)
complex(dp), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_z1
subroutine d_get_val_first_z1(val,this,success)
complex(dp), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_z1
subroutine d_get_p_z1(val,this,key,success)
complex(dp), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_z1
subroutine d_get_p_first_z1(val,this,success)
complex(dp), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_z1
function d_kv_z2(key,val) result(this)
character(len=*), intent(in) :: key
complex(dp), intent(in), dimension(:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_z2
function d_kvp_z2(key, val) result(this)
character(len=*), intent(in) :: key
complex(dp), intent(in), dimension(:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_z2
subroutine d_get_val_z2(val,this,key,success)
complex(dp), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_z2
subroutine d_get_val_first_z2(val,this,success)
complex(dp), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_z2
subroutine d_get_p_z2(val,this,key,success)
complex(dp), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_z2
subroutine d_get_p_first_z2(val,this,success)
complex(dp), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_z2
function d_kv_z3(key,val) result(this)
character(len=*), intent(in) :: key
complex(dp), intent(in), dimension(:,:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_z3
function d_kvp_z3(key, val) result(this)
character(len=*), intent(in) :: key
complex(dp), intent(in), dimension(:,:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_z3
subroutine d_get_val_z3(val,this,key,success)
complex(dp), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_z3
subroutine d_get_val_first_z3(val,this,success)
complex(dp), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_z3
subroutine d_get_p_z3(val,this,key,success)
complex(dp), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_z3
subroutine d_get_p_first_z3(val,this,success)
complex(dp), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_z3
function d_kv_b0(key,val) result(this)
character(len=*), intent(in) :: key
logical, intent(in) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_b0
function d_kvp_b0(key, val) result(this)
character(len=*), intent(in) :: key
logical, intent(in), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_b0
subroutine d_get_val_b0(val,this,key,success)
logical, intent(out) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_b0
subroutine d_get_val_first_b0(val,this,success)
logical, intent(out) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_b0
subroutine d_get_p_b0(val,this,key,success)
logical, pointer :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_b0
subroutine d_get_p_first_b0(val,this,success)
logical, pointer :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_b0
function d_kv_b1(key,val) result(this)
character(len=*), intent(in) :: key
logical, intent(in), dimension(:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_b1
function d_kvp_b1(key, val) result(this)
character(len=*), intent(in) :: key
logical, intent(in), dimension(:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_b1
subroutine d_get_val_b1(val,this,key,success)
logical, intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_b1
subroutine d_get_val_first_b1(val,this,success)
logical, intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_b1
subroutine d_get_p_b1(val,this,key,success)
logical, pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_b1
subroutine d_get_p_first_b1(val,this,success)
logical, pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_b1
function d_kv_b2(key,val) result(this)
character(len=*), intent(in) :: key
logical, intent(in), dimension(:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_b2
function d_kvp_b2(key, val) result(this)
character(len=*), intent(in) :: key
logical, intent(in), dimension(:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_b2
subroutine d_get_val_b2(val,this,key,success)
logical, intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_b2
subroutine d_get_val_first_b2(val,this,success)
logical, intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_b2
subroutine d_get_p_b2(val,this,key,success)
logical, pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_b2
subroutine d_get_p_first_b2(val,this,success)
logical, pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_b2
function d_kv_b3(key,val) result(this)
character(len=*), intent(in) :: key
logical, intent(in), dimension(:,:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_b3
function d_kvp_b3(key, val) result(this)
character(len=*), intent(in) :: key
logical, intent(in), dimension(:,:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_b3
subroutine d_get_val_b3(val,this,key,success)
logical, intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_b3
subroutine d_get_val_first_b3(val,this,success)
logical, intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_b3
subroutine d_get_p_b3(val,this,key,success)
logical, pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_b3
subroutine d_get_p_first_b3(val,this,success)
logical, pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_b3
function d_kv_h0(key,val) result(this)
character(len=*), intent(in) :: key
integer(ih), intent(in) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_h0
function d_kvp_h0(key, val) result(this)
character(len=*), intent(in) :: key
integer(ih), intent(in), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_h0
subroutine d_get_val_h0(val,this,key,success)
integer(ih), intent(out) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_h0
subroutine d_get_val_first_h0(val,this,success)
integer(ih), intent(out) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_h0
subroutine d_get_p_h0(val,this,key,success)
integer(ih), pointer :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_h0
subroutine d_get_p_first_h0(val,this,success)
integer(ih), pointer :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_h0
function d_kv_h1(key,val) result(this)
character(len=*), intent(in) :: key
integer(ih), intent(in), dimension(:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_h1
function d_kvp_h1(key, val) result(this)
character(len=*), intent(in) :: key
integer(ih), intent(in), dimension(:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_h1
subroutine d_get_val_h1(val,this,key,success)
integer(ih), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_h1
subroutine d_get_val_first_h1(val,this,success)
integer(ih), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_h1
subroutine d_get_p_h1(val,this,key,success)
integer(ih), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_h1
subroutine d_get_p_first_h1(val,this,success)
integer(ih), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_h1
function d_kv_h2(key,val) result(this)
character(len=*), intent(in) :: key
integer(ih), intent(in), dimension(:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_h2
function d_kvp_h2(key, val) result(this)
character(len=*), intent(in) :: key
integer(ih), intent(in), dimension(:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_h2
subroutine d_get_val_h2(val,this,key,success)
integer(ih), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_h2
subroutine d_get_val_first_h2(val,this,success)
integer(ih), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_h2
subroutine d_get_p_h2(val,this,key,success)
integer(ih), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_h2
subroutine d_get_p_first_h2(val,this,success)
integer(ih), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_h2
function d_kv_h3(key,val) result(this)
character(len=*), intent(in) :: key
integer(ih), intent(in), dimension(:,:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_h3
function d_kvp_h3(key, val) result(this)
character(len=*), intent(in) :: key
integer(ih), intent(in), dimension(:,:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_h3
subroutine d_get_val_h3(val,this,key,success)
integer(ih), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_h3
subroutine d_get_val_first_h3(val,this,success)
integer(ih), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_h3
subroutine d_get_p_h3(val,this,key,success)
integer(ih), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_h3
subroutine d_get_p_first_h3(val,this,success)
integer(ih), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_h3
function d_kv_i0(key,val) result(this)
character(len=*), intent(in) :: key
integer(is), intent(in) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_i0
function d_kvp_i0(key, val) result(this)
character(len=*), intent(in) :: key
integer(is), intent(in), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_i0
subroutine d_get_val_i0(val,this,key,success)
integer(is), intent(out) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_i0
subroutine d_get_val_first_i0(val,this,success)
integer(is), intent(out) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_i0
subroutine d_get_p_i0(val,this,key,success)
integer(is), pointer :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_i0
subroutine d_get_p_first_i0(val,this,success)
integer(is), pointer :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_i0
function d_kv_i1(key,val) result(this)
character(len=*), intent(in) :: key
integer(is), intent(in), dimension(:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_i1
function d_kvp_i1(key, val) result(this)
character(len=*), intent(in) :: key
integer(is), intent(in), dimension(:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_i1
subroutine d_get_val_i1(val,this,key,success)
integer(is), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_i1
subroutine d_get_val_first_i1(val,this,success)
integer(is), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_i1
subroutine d_get_p_i1(val,this,key,success)
integer(is), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_i1
subroutine d_get_p_first_i1(val,this,success)
integer(is), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_i1
function d_kv_i2(key,val) result(this)
character(len=*), intent(in) :: key
integer(is), intent(in), dimension(:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_i2
function d_kvp_i2(key, val) result(this)
character(len=*), intent(in) :: key
integer(is), intent(in), dimension(:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_i2
subroutine d_get_val_i2(val,this,key,success)
integer(is), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_i2
subroutine d_get_val_first_i2(val,this,success)
integer(is), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_i2
subroutine d_get_p_i2(val,this,key,success)
integer(is), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_i2
subroutine d_get_p_first_i2(val,this,success)
integer(is), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_i2
function d_kv_i3(key,val) result(this)
character(len=*), intent(in) :: key
integer(is), intent(in), dimension(:,:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_i3
function d_kvp_i3(key, val) result(this)
character(len=*), intent(in) :: key
integer(is), intent(in), dimension(:,:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_i3
subroutine d_get_val_i3(val,this,key,success)
integer(is), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_i3
subroutine d_get_val_first_i3(val,this,success)
integer(is), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_i3
subroutine d_get_p_i3(val,this,key,success)
integer(is), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_i3
subroutine d_get_p_first_i3(val,this,success)
integer(is), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_i3
function d_kv_l0(key,val) result(this)
character(len=*), intent(in) :: key
integer(il), intent(in) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_l0
function d_kvp_l0(key, val) result(this)
character(len=*), intent(in) :: key
integer(il), intent(in), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_l0
subroutine d_get_val_l0(val,this,key,success)
integer(il), intent(out) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_l0
subroutine d_get_val_first_l0(val,this,success)
integer(il), intent(out) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_l0
subroutine d_get_p_l0(val,this,key,success)
integer(il), pointer :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_l0
subroutine d_get_p_first_l0(val,this,success)
integer(il), pointer :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_l0
function d_kv_l1(key,val) result(this)
character(len=*), intent(in) :: key
integer(il), intent(in), dimension(:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_l1
function d_kvp_l1(key, val) result(this)
character(len=*), intent(in) :: key
integer(il), intent(in), dimension(:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_l1
subroutine d_get_val_l1(val,this,key,success)
integer(il), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_l1
subroutine d_get_val_first_l1(val,this,success)
integer(il), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_l1
subroutine d_get_p_l1(val,this,key,success)
integer(il), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_l1
subroutine d_get_p_first_l1(val,this,success)
integer(il), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_l1
function d_kv_l2(key,val) result(this)
character(len=*), intent(in) :: key
integer(il), intent(in), dimension(:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_l2
function d_kvp_l2(key, val) result(this)
character(len=*), intent(in) :: key
integer(il), intent(in), dimension(:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_l2
subroutine d_get_val_l2(val,this,key,success)
integer(il), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_l2
subroutine d_get_val_first_l2(val,this,success)
integer(il), intent(out), dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_l2
subroutine d_get_p_l2(val,this,key,success)
integer(il), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_l2
subroutine d_get_p_first_l2(val,this,success)
integer(il), pointer , dimension(:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_l2
function d_kv_l3(key,val) result(this)
character(len=*), intent(in) :: key
integer(il), intent(in), dimension(:,:,:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_l3
function d_kvp_l3(key, val) result(this)
character(len=*), intent(in) :: key
integer(il), intent(in), dimension(:,:,:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_l3
subroutine d_get_val_l3(val,this,key,success)
integer(il), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_l3
subroutine d_get_val_first_l3(val,this,success)
integer(il), intent(out), dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_l3
subroutine d_get_p_l3(val,this,key,success)
integer(il), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_l3
subroutine d_get_p_first_l3(val,this,success)
integer(il), pointer , dimension(:,:,:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_l3
function d_kv_cp0(key,val) result(this)
character(len=*), intent(in) :: key
type(c_ptr), intent(in) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_cp0
function d_kvp_cp0(key, val) result(this)
character(len=*), intent(in) :: key
type(c_ptr), intent(in), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_cp0
subroutine d_get_val_cp0(val,this,key,success)
type(c_ptr), intent(out) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_cp0
subroutine d_get_val_first_cp0(val,this,success)
type(c_ptr), intent(out) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_cp0
subroutine d_get_p_cp0(val,this,key,success)
type(c_ptr), pointer :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_cp0
subroutine d_get_p_first_cp0(val,this,success)
type(c_ptr), pointer :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_cp0
function d_kv_cp1(key,val) result(this)
character(len=*), intent(in) :: key
type(c_ptr), intent(in), dimension(:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_cp1
function d_kvp_cp1(key, val) result(this)
character(len=*), intent(in) :: key
type(c_ptr), intent(in), dimension(:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_cp1
subroutine d_get_val_cp1(val,this,key,success)
type(c_ptr), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_cp1
subroutine d_get_val_first_cp1(val,this,success)
type(c_ptr), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_cp1
subroutine d_get_p_cp1(val,this,key,success)
type(c_ptr), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_cp1
subroutine d_get_p_first_cp1(val,this,success)
type(c_ptr), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_cp1
function d_kv_fp0(key,val) result(this)
character(len=*), intent(in) :: key
type(c_funptr), intent(in) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_fp0
function d_kvp_fp0(key, val) result(this)
character(len=*), intent(in) :: key
type(c_funptr), intent(in), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_fp0
subroutine d_get_val_fp0(val,this,key,success)
type(c_funptr), intent(out) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_fp0
subroutine d_get_val_first_fp0(val,this,success)
type(c_funptr), intent(out) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_fp0
subroutine d_get_p_fp0(val,this,key,success)
type(c_funptr), pointer :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_fp0
subroutine d_get_p_first_fp0(val,this,success)
type(c_funptr), pointer :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_fp0
function d_kv_fp1(key,val) result(this)
character(len=*), intent(in) :: key
type(c_funptr), intent(in), dimension(:) :: val
type(dictionary_t) :: this
this = new_d_key(key)
call assign(this%first%value,val)
end function d_kv_fp1
function d_kvp_fp1(key, val) result(this)
character(len=*), intent(in) :: key
type(c_funptr), intent(in), dimension(:), target :: val
type(dictionary_t) :: this
this = new_d_key(key)
call associate(this%first%value,val)
end function d_kvp_fp1
subroutine d_get_val_fp1(val,this,key,success)
type(c_funptr), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call assign(val,v,success=success)
call nullify(v)
end subroutine d_get_val_fp1
subroutine d_get_val_first_fp1(val,this,success)
type(c_funptr), intent(out), dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call assign(val,this%first%value,success=success)
end subroutine d_get_val_first_fp1
subroutine d_get_p_fp1(val,this,key,success)
type(c_funptr), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
character(len=*), intent(in) :: key
logical, intent(out), optional :: success
type(variable_t) :: v
call associate(v,this,key=key)
call associate(val,v,success=success)
call nullify(v)
end subroutine d_get_p_fp1
subroutine d_get_p_first_fp1(val,this,success)
type(c_funptr), pointer , dimension(:) :: val
type(dictionary_t), intent(inout) :: this
logical, intent(out), optional :: success
call associate(val,this%first%value,success=success)
end subroutine d_get_p_first_fp1
  ! helper routines for often used stuff
  subroutine val_delete_request(val,dealloc)
    type(variable_t), intent(inout) :: val
    logical, intent(in), optional :: dealloc
    if ( present(dealloc) ) then
       if ( dealloc ) call delete(val)
    end if
    call nullify(val)
  end subroutine val_delete_request
  ! Create a routine for making the dictionary point to the data
  ! key.
  function d_kvp_dict(key,dic) result(this)
    character(len=*), intent(in) :: key
    type(dictionary_t), intent(in) :: dic
    type(dictionary_t) :: this
    type :: pdictionary_entry_
       type(dictionary_entry_), pointer :: d => null()
    end type pdictionary_entry_
    type(pdictionary_entry_) :: pd
    type(variable_t) :: v
    character(len=1) :: c(1)
    pd%d => dic%first
    call associate_type(v,transfer(pd,c))
    this = (key.kvp.v)
    call nullify(v)
  end function d_kvp_dict
  ! In case the value of the dictionary is a dictionary we can request that
  ! dictionary directly
  subroutine d_key2dict(dic,d,key,dealloc)
    type(dictionary_t), intent(inout) :: dic
    type(dictionary_t), intent(inout) :: d
    character(len=*), intent(in), optional :: key
    logical, intent(in), optional :: dealloc
    ! Retrieving a dictionary will NEVER
    ! be copying the entire dictionary.
    call d_get_p_dict(dic,d,key=key,dealloc=dealloc)
  end subroutine d_key2dict
  subroutine d_get_p_dict(dic,d,key,dealloc)
    type(dictionary_t), intent(inout) :: dic
    type(dictionary_t), intent(inout) :: d
    character(len=*), intent(in), optional :: key
    logical, intent(in), optional :: dealloc
    ! Instead of saving the data-type dict
    ! we save the first pointer.
    ! This will allow greater flexibility as the
    ! parent container can then be re-used with out
    ! worries.
    ! I.e.
    ! if one uses :
    ! type :: pdict
    ! type(dictionary_t), pointer :: d
    ! end type
    ! then the address of the "parenting" dictionary is saved,
    ! And hence, doing:
    ! dic1 = ('a'.kv.1)
    ! dic2 = ('dic1'.kvp.dic1)
    ! call nullify(dic1)
    ! dic1 = ('b'.kv.1)
    ! will make dic1 in dic2 contain ('b'.kv.1)
    ! Specifically because the address of the dic1 does not change.
    ! However, the dictionary_entry_ pointer is irrespective of parent locality.
    type :: pdictionary_entry_
       type(dictionary_entry_), pointer :: d => null()
    end type pdictionary_entry_
    type(pdictionary_entry_) :: pd
    type(dictionary_t) :: ld
    type(variable_t) :: v
    character(len=1), allocatable :: c(:)
    integer :: i
    logical :: ldealloc
    ldealloc = .false.
    if ( present(dealloc) ) ldealloc = dealloc
    if ( ldealloc ) then
       call delete(dic)
    else
       call nullify(dic)
    end if
    ! Retrieve the dictionary key
    call associate(v,d,key=key)
    if ( v%t .eq. '    ' ) then
       call nullify(v)
       return
    end if
    i = size_enc(v)
    allocate(c(i))
    call enc(v,c)
    pd = transfer(c,pd)
    deallocate(c)
    dic%first => pd%d
    call nullify(v)
    ! we need to re-count the number of entries in
    ! the dictionary_entry_ tree.
    ! Sadly, this is because we contain the dictionary_entry_
    ! type, and NOT the dict type :(
    ! However, it makes the programming style more
    ! intuitive (dependent on how you look at it)
    ld = .first. dic
    dic%len = 0
    do while ( .not. (.empty. ld) )
       dic%len = dic%len + 1
       ld = .next. ld
    end do
  end subroutine d_get_p_dict
end module dictionary