!> @defgroup FH5 Fortran Library (H5) Interface
!!
!! @see H5, C-API
!!
!! @see @ref H5_UG, User Guide
!!

!> @ingroup FH5
!!
!! @brief This module provides fortran specific helper functions for the HDF library.
!
! PURPOSE
!  This module is used to pass C stubs for H5 Fortran APIs. The C stubs are
!  packed into arrays in H5_f.c and these arrays are then passed to Fortran.
!
! NOTES
!  The size of the C arrays in H5_f.c has to match the values of the variables
!  declared as PARAMETER, hence if the size of an array in H5_f.c is changed
!  then the PARAMETER of that corresponding array in Fortran must also be changed.
!
!
! COPYRIGHT
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
!   Copyright by The HDF Group.                                               *
!   All rights reserved.                                                      *
!                                                                             *
!   This file is part of HDF5.  The full HDF5 copyright notice, including     *
!   terms governing use, modification, and redistribution, is contained in    *
!   the COPYING file, which can be found at the root of the source code       *
!   distribution tree, or in https://www.hdfgroup.org/licenses.               *
!   If you do not have access to either file, you may request a copy from     *
!   help@hdfgroup.org.                                                        *
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
!
! NOTES
!       _____ __  __ _____   ____  _____ _______       _   _ _______
!      |_   _|  \/  |  __ \ / __ \|  __ \__   __|/\   | \ | |__   __|
! ****   | | | \  / | |__) | |  | | |__) | | |  /  \  |  \| |  | |    ****
! ****   | | | |\/| |  ___/| |  | |  _  /  | | / /\ \ | . ` |  | |    ****
! ****  _| |_| |  | | |    | |__| | | \ \  | |/ ____ \| |\  |  | |    ****
!      |_____|_|  |_|_|     \____/|_|  \_\ |_/_/    \_\_| \_|  |_|
!
!  If you add a new function you must add the function name to the
!  Windows dll file 'hdf5_fortrandll.def.in' in the fortran/src directory.
!  This is needed for Windows based operating systems.
!

#include <H5config_f.inc>

MODULE H5LIB

  USE H5GLOBAL
  IMPLICIT NONE

  PRIVATE
  !
  ! H5F flags declaration
  !
  INTEGER, PARAMETER :: H5F_FLAGS_LEN = 30
  INTEGER, DIMENSION(1:H5F_FLAGS_LEN) :: H5F_flags
  !
  ! H5generic flags declaration
  !
  INTEGER, PARAMETER :: H5generic_FLAGS_LEN = 9
  INTEGER, DIMENSION(1:H5generic_FLAGS_LEN) :: H5generic_flags

  INTEGER, PARAMETER :: H5generic_haddr_FLAGS_LEN = 1
  INTEGER(HADDR_T), DIMENSION(1:H5generic_haddr_FLAGS_LEN) :: H5generic_haddr_flags
  !
  ! H5G flags declaration
  !
  INTEGER, PARAMETER :: H5G_FLAGS_LEN = 12
  INTEGER, DIMENSION(1:H5G_FLAGS_LEN) :: H5G_flags
  !
  ! H5D flags declaration
  !
  INTEGER, PARAMETER :: H5D_FLAGS_LEN = 60
  INTEGER, DIMENSION(1:H5D_FLAGS_LEN) :: H5D_flags
  INTEGER, PARAMETER :: H5D_SIZE_FLAGS_LEN = 2
  INTEGER(SIZE_T), DIMENSION(1:H5D_SIZE_FLAGS_LEN) :: H5D_size_flags
  !
  ! H5E flags declaration
  !
  INTEGER, PARAMETER :: H5E_FLAGS_LEN = 4
  INTEGER, DIMENSION(1:H5E_FLAGS_LEN) :: H5E_flags
  INTEGER, PARAMETER :: H5E_HID_FLAGS_LEN = 1
  INTEGER(HID_T), DIMENSION(1:H5E_HID_FLAGS_LEN) :: H5E_hid_flags
  !
  ! H5ES flags declaration
  !
  INTEGER, PARAMETER :: H5ES_FLAGS_LEN = 4
  INTEGER, DIMENSION(1:H5ES_FLAGS_LEN) :: H5ES_flags
  INTEGER, PARAMETER :: H5ES_HID_FLAGS_LEN = 1
  INTEGER(HID_T), DIMENSION(1:H5ES_HID_FLAGS_LEN) :: H5ES_hid_flags
  !
  ! H5FD flags declaration
  !
  INTEGER, PARAMETER :: H5FD_FLAGS_LEN = 22
  INTEGER, DIMENSION(1:H5FD_FLAGS_LEN) :: H5FD_flags
  !
  ! H5FD file drivers flags declaration
  !
  INTEGER, PARAMETER :: H5FD_HID_FLAGS_LEN = 9
  INTEGER(HID_T), DIMENSION(1:H5FD_HID_FLAGS_LEN) :: H5FD_hid_flags
  !
  ! H5I flags declaration
  !
  INTEGER, PARAMETER :: H5I_FLAGS_LEN = 17
  INTEGER, DIMENSION(1:H5I_FLAGS_LEN) :: H5I_flags
  !
  ! H5L flags declaration
  !
  INTEGER, PARAMETER :: H5L_FLAGS_LEN = 6
  INTEGER, DIMENSION(1:H5L_FLAGS_LEN) :: H5L_flags
  !
  ! H5O flags declaration
  !
  INTEGER, PARAMETER :: H5O_FLAGS_LEN = 33
  INTEGER, DIMENSION(1:H5O_FLAGS_LEN) :: H5O_flags
  !
  ! H5P flags declaration
  !
  INTEGER, PARAMETER :: H5P_FLAGS_LEN = 18
  INTEGER(HID_T), DIMENSION(1:H5P_FLAGS_LEN) :: H5P_flags
  !
  ! H5P integers flags declaration
  !
  INTEGER, PARAMETER :: H5P_FLAGS_INT_LEN = 2
  INTEGER, DIMENSION(1:H5P_FLAGS_INT_LEN) :: H5P_flags_int
  !
  ! H5R flags declaration
  !
  INTEGER, PARAMETER :: H5R_FLAGS_LEN = 9
  INTEGER, DIMENSION(1:H5R_FLAGS_LEN) :: H5R_flags
  !
  ! H5S flags declaration
  !
  INTEGER, PARAMETER :: H5S_FLAGS_LEN = 20
  INTEGER, DIMENSION(1:H5S_FLAGS_LEN) :: H5S_flags
  INTEGER, PARAMETER :: H5S_HSIZE_FLAGS_LEN = 1
  INTEGER(HSIZE_T), DIMENSION(1:H5S_HSIZE_FLAGS_LEN) :: H5S_hsize_flags
  INTEGER, PARAMETER :: H5S_HID_FLAGS_LEN = 3
  INTEGER(HSIZE_T), DIMENSION(1:H5S_HID_FLAGS_LEN)   :: H5S_hid_flags
  !
  ! H5T flags declaration
  !
  INTEGER, PARAMETER :: H5T_FLAGS_LEN = 35
  INTEGER, DIMENSION(1:H5T_FLAGS_LEN) :: H5T_flags
  !
  ! H5VL flags declaration
  !
  INTEGER, PARAMETER :: H5VL_FLAGS_LEN = 3
  INTEGER, DIMENSION(1:H5VL_FLAGS_LEN) :: H5VL_flags
  INTEGER, PARAMETER :: H5VL_INT64_FLAGS_LEN = 46
  INTEGER(C_INT64_T), DIMENSION(1:H5VL_INT64_FLAGS_LEN) :: H5VL_int64_flags

  !
  ! H5Z flags declaration
  !
  INTEGER, PARAMETER :: H5Z_FLAGS_LEN = 20
  INTEGER, DIMENSION(1:H5Z_FLAGS_LEN) :: H5Z_flags
  !
  ! H5 Library flags declaration
  !
  INTEGER, PARAMETER :: H5LIB_FLAGS_LEN =  2
  INTEGER, DIMENSION(1:H5LIB_FLAGS_LEN) :: H5LIB_flags

  PUBLIC :: h5open_f, h5close_f, h5get_libversion_f, h5dont_atexit_f, h5kind_to_type, h5offsetof, h5gmtime
  PUBLIC :: h5garbage_collect_f, h5check_version_f, h5get_free_list_sizes_f

CONTAINS
!>
!! \ingroup FH5
!!
!! \brief Initializes HDF5 Fortran interface.
!!
!! \param error \fortran_error
!!
  SUBROUTINE h5open_f(error)
    USE H5F, ONLY : h5fget_obj_count_f, H5OPEN_NUM_OBJ
    IMPLICIT NONE
    INTEGER, INTENT(OUT) :: error
    INTEGER(SIZE_T) :: H5OPEN_NUM_OBJ_LOC = 0
    INTERFACE

       INTEGER FUNCTION h5init_types_c(p_types, f_types, i_types) &
            BIND(C,NAME='h5init_types_c')
         IMPORT :: HID_T
         IMPORT :: PREDEF_TYPES_LEN, FLOATING_TYPES_LEN, INTEGER_TYPES_LEN
         IMPLICIT NONE
         INTEGER(HID_T), DIMENSION(1:PREDEF_TYPES_LEN)   :: p_types
         INTEGER(HID_T), DIMENSION(1:FLOATING_TYPES_LEN) :: f_types
         INTEGER(HID_T), DIMENSION(1:INTEGER_TYPES_LEN)  :: i_types
       END FUNCTION h5init_types_c

       INTEGER FUNCTION h5init_flags_c(i_H5D_flags, &
            i_H5D_size_flags,&
            i_H5E_flags, &
            i_H5E_hid_flags, &
            i_H5ES_flags, &
            i_H5ES_hid_flags, &
            i_H5F_flags, &
            i_H5FD_flags, &
            i_H5FD_hid_flags, &
            i_H5G_flags, &
            i_H5I_flags, &
            i_H5L_flags, &
            i_H5O_flags, &
            i_H5P_flags, &
            i_H5P_flags_int, &
            i_H5R_flags, &
            i_H5S_flags, &
            i_H5S_hid_flags, &
            i_H5S_hsize_flags, &
            i_H5T_flags, &
            i_H5VL_flags, &
            i_H5VL_int64_flags, &
            i_H5Z_flags, &
            i_H5generic_flags, &
            i_H5generic_haddr_flags) &
            BIND(C,NAME='h5init_flags_c')
         IMPORT :: HID_T, SIZE_T, HSIZE_T, HADDR_T, C_INT64_T
         IMPORT :: H5D_FLAGS_LEN, H5D_SIZE_FLAGS_LEN, &
              H5E_FLAGS_LEN, H5E_HID_FLAGS_LEN, &
              H5ES_FLAGS_LEN, H5ES_HID_FLAGS_LEN, &
              H5F_FLAGS_LEN, H5G_FLAGS_LEN, H5FD_FLAGS_LEN, &
              H5FD_HID_FLAGS_LEN, H5I_FLAGS_LEN, H5L_FLAGS_LEN, &
              H5O_FLAGS_LEN, H5P_FLAGS_LEN, H5P_FLAGS_INT_LEN, &
              H5R_FLAGS_LEN, H5S_FLAGS_LEN, H5S_HID_FLAGS_LEN, H5S_HSIZE_FLAGS_LEN, &
              H5T_FLAGS_LEN, H5VL_FLAGS_LEN, H5VL_INT64_FLAGS_LEN, &
              H5Z_FLAGS_LEN, H5generic_FLAGS_LEN, H5generic_haddr_FLAGS_LEN
         IMPLICIT NONE
         INTEGER           , DIMENSION(1:H5D_FLAGS_LEN)             :: i_H5D_flags
         INTEGER(SIZE_T)   , DIMENSION(1:H5D_SIZE_FLAGS_LEN)        :: i_H5D_size_flags
         INTEGER           , DIMENSION(1:H5E_FLAGS_LEN)             :: i_H5E_flags
         INTEGER(HID_T)    , DIMENSION(1:H5E_HID_FLAGS_LEN)         :: i_H5E_hid_flags
         INTEGER           , DIMENSION(1:H5ES_FLAGS_LEN)            :: i_H5ES_flags
         INTEGER(HID_T)    , DIMENSION(1:H5ES_HID_FLAGS_LEN)        :: i_H5ES_hid_flags
         INTEGER           , DIMENSION(1:H5F_FLAGS_LEN)             :: i_H5F_flags
         INTEGER           , DIMENSION(1:H5G_FLAGS_LEN)             :: i_H5G_flags
         INTEGER           , DIMENSION(1:H5FD_FLAGS_LEN)            :: i_H5FD_flags
         INTEGER(HID_T)    , DIMENSION(1:H5FD_HID_FLAGS_LEN)        :: i_H5FD_hid_flags
         INTEGER           , DIMENSION(1:H5I_FLAGS_LEN)             :: i_H5I_flags
         INTEGER           , DIMENSION(1:H5L_FLAGS_LEN)             :: i_H5L_flags
         INTEGER           , DIMENSION(1:H5O_FLAGS_LEN)             :: i_H5O_flags
         INTEGER(HID_T)    , DIMENSION(1:H5P_FLAGS_LEN)             :: i_H5P_flags
         INTEGER           , DIMENSION(1:H5P_FLAGS_INT_LEN)         :: i_H5P_flags_int
         INTEGER           , DIMENSION(1:H5R_FLAGS_LEN)             :: i_H5R_flags
         INTEGER           , DIMENSION(1:H5S_FLAGS_LEN)             :: i_H5S_flags
         INTEGER(HID_T)    , DIMENSION(1:H5S_HID_FLAGS_LEN)         :: i_H5S_hid_flags
         INTEGER(HSIZE_T)  , DIMENSION(1:H5S_HSIZE_FLAGS_LEN)       :: i_H5S_hsize_flags
         INTEGER           , DIMENSION(1:H5T_FLAGS_LEN)             :: i_H5T_flags
         INTEGER           , DIMENSION(1:H5VL_FLAGS_LEN)            :: i_H5VL_flags
         INTEGER(C_INT64_T), DIMENSION(1:H5VL_INT64_FLAGS_LEN)      :: i_H5VL_int64_flags
         INTEGER           , DIMENSION(1:H5Z_FLAGS_LEN)             :: i_H5Z_flags
         INTEGER           , DIMENSION(1:H5generic_FLAGS_LEN)       :: i_H5generic_flags
         INTEGER(HADDR_T)  , DIMENSION(1:H5generic_haddr_FLAGS_LEN) :: i_H5generic_haddr_flags
       END FUNCTION h5init_flags_c

       INTEGER FUNCTION h5init1_flags_c( i_H5LIB_flags ) &
            BIND(C,NAME='h5init1_flags_c')
         IMPORT :: H5LIB_FLAGS_LEN
         IMPLICIT NONE
         INTEGER, DIMENSION(1:H5LIB_FLAGS_LEN) :: i_H5LIB_flags
       END FUNCTION h5init1_flags_c

    END INTERFACE
    error = 0
    ! Check if H5open_f has already been called. If so, skip doing it again.
    IF(H5OPEN_NUM_OBJ .NE. 0) RETURN

    error = h5init_types_c(predef_types, floating_types, integer_types)

    H5T_NATIVE_INTEGER_KIND(1:5)  = predef_types(1:5)
    H5T_NATIVE_INTEGER            = predef_types(6)
    H5T_NATIVE_REAL               = predef_types(7)
    H5T_NATIVE_DOUBLE             = predef_types(8)
    H5T_NATIVE_CHARACTER          = predef_types(9)
    H5T_STD_REF_OBJ               = predef_types(10)
    H5T_STD_REF_DSETREG           = predef_types(11)
    H5T_NATIVE_REAL_C_FLOAT       = predef_types(12)
    H5T_NATIVE_REAL_C_DOUBLE      = predef_types(13)
    H5T_NATIVE_REAL_C_LONG_DOUBLE = predef_types(14)
    H5T_NATIVE_B8                 = predef_types(15)
    H5T_NATIVE_B16                = predef_types(16)
    H5T_NATIVE_B32                = predef_types(17)
    H5T_NATIVE_B64                = predef_types(18)
    H5T_NATIVE_FLOAT_128          = predef_types(19)

    H5T_IEEE_F32BE = floating_types(1)
    H5T_IEEE_F32LE = floating_types(2)
    H5T_IEEE_F64BE = floating_types(3)
    H5T_IEEE_F64LE = floating_types(4)

    H5T_STD_I8BE   = integer_types(1)
    H5T_STD_I8LE   = integer_types(2)
    H5T_STD_I16BE  = integer_types(3)
    H5T_STD_I16LE  = integer_types(4)
    H5T_STD_I32BE  = integer_types(5)
    H5T_STD_I32LE  = integer_types(6)
    H5T_STD_I64BE  = integer_types(7)
    H5T_STD_I64LE  = integer_types(8)
    H5T_STD_U8BE   = integer_types(9)
    H5T_STD_U8LE   = integer_types(10)
    H5T_STD_U16BE  = integer_types(11)
    H5T_STD_U16LE  = integer_types(12)
    H5T_STD_U32BE  = integer_types(13)
    H5T_STD_U32LE  = integer_types(14)
    H5T_STD_U64BE  = integer_types(15)
    H5T_STD_U64LE  = integer_types(16)
    H5T_STRING     = integer_types(17)
    H5T_STD_B8BE   = integer_types(18)
    H5T_STD_B8LE   = integer_types(19)
    H5T_STD_B16BE  = integer_types(20)
    H5T_STD_B16LE  = integer_types(21)
    H5T_STD_B32BE  = integer_types(22)
    H5T_STD_B32LE  = integer_types(23)
    H5T_STD_B64BE  = integer_types(24)
    H5T_STD_B64LE  = integer_types(25)
    H5T_FORTRAN_S1 = integer_types(26)
    H5T_C_S1       = integer_types(27)
    H5T_STD_REF    = integer_types(28)

    error = error + h5init_flags_c(H5D_flags, &
         H5D_size_flags, &
         H5E_flags, &
         H5E_hid_flags, &
         H5ES_flags, &
         H5ES_hid_flags, &
         H5F_flags, &
         H5FD_flags, &
         H5FD_hid_flags, &
         H5G_flags, &
         H5I_flags, &
         H5L_flags, &
         H5O_flags, &
         H5P_flags, &
         H5P_flags_int, &
         H5R_flags, &
         H5S_flags, &
         H5S_hid_flags, &
         H5S_hsize_flags, &
         H5T_flags, &
         H5VL_flags, &
         H5VL_int64_flags, &
         H5Z_flags, &
         H5generic_flags,&
         H5generic_haddr_flags)
    !
    ! H5F flags
    !
    H5F_ACC_RDWR_F                 = H5F_flags(1)
    H5F_ACC_RDONLY_F               = H5F_flags(2)
    H5F_ACC_TRUNC_F                = H5F_flags(3)
    H5F_ACC_EXCL_F                 = H5F_flags(4)
    H5F_ACC_DEBUG_F                = H5F_flags(5)
    H5F_SCOPE_LOCAL_F              = H5F_flags(6)
    H5F_SCOPE_GLOBAL_F             = H5F_flags(7)
    H5F_CLOSE_DEFAULT_F            = H5F_flags(8)
    H5F_CLOSE_WEAK_F               = H5F_flags(9)
    H5F_CLOSE_SEMI_F               = H5F_flags(10)
    H5F_CLOSE_STRONG_F             = H5F_flags(11)
    H5F_OBJ_FILE_F                 = H5F_flags(12)
    H5F_OBJ_DATASET_F              = H5F_flags(13)
    H5F_OBJ_GROUP_F                = H5F_flags(14)
    H5F_OBJ_DATATYPE_F             = H5F_flags(15)
    H5F_OBJ_ALL_F                  = H5F_flags(16)
    H5F_LIBVER_EARLIEST_F          = H5F_flags(17)
    H5F_LIBVER_LATEST_F            = H5F_flags(18)
    H5F_LIBVER_ERROR_F             = H5F_flags(19)
    H5F_LIBVER_NBOUNDS_F           = H5F_flags(20)
    H5F_UNLIMITED_F                = H5F_flags(21)
    H5F_FSPACE_STRATEGY_FSM_AGGR_F = H5F_flags(22)
    H5F_FSPACE_STRATEGY_PAGE_F     = H5F_flags(23)
    H5F_FSPACE_STRATEGY_AGGR_F     = H5F_flags(24)
    H5F_FSPACE_STRATEGY_NONE_F     = H5F_flags(25)
    H5F_FSPACE_STRATEGY_NTYPES_F   = H5F_flags(26)
    H5F_LIBVER_V18_F               = H5F_flags(27)
    H5F_LIBVER_V110_F              = H5F_flags(28)
    H5F_LIBVER_V112_F              = H5F_flags(29)
    H5F_LIBVER_V114_F              = H5F_flags(30)
    !
    ! H5generic flags
    !
    H5_INDEX_UNKNOWN_F   = H5generic_flags(1)
    H5_INDEX_NAME_F      = H5generic_flags(2)
    H5_INDEX_CRT_ORDER_F = H5generic_flags(3)
    H5_INDEX_N_F         = H5generic_flags(4)
    H5_ITER_UNKNOWN_F    = H5generic_flags(5)
    H5_ITER_INC_F        = H5generic_flags(6)
    H5_ITER_DEC_F        = H5generic_flags(7)
    H5_ITER_NATIVE_F     = H5generic_flags(8)
    H5_ITER_N_F          = H5generic_flags(9)

    HADDR_UNDEF_F = H5generic_haddr_flags(1)
    !
    ! H5G flags
    !
    H5G_UNKNOWN_F                   = H5G_flags(1)
    H5G_GROUP_F                     = H5G_flags(2)
    H5G_DATASET_F                   = H5G_flags(3)
    H5G_TYPE_F                      = H5G_flags(4)
    H5G_SAME_LOC_F                  = H5G_flags(5)
    H5G_LINK_ERROR_F                = H5G_flags(6)
    H5G_LINK_HARD_F                 = H5G_flags(7)
    H5G_LINK_SOFT_F                 = H5G_flags(8)
    H5G_STORAGE_TYPE_UNKNOWN_F      = H5G_flags(9)
    H5G_STORAGE_TYPE_SYMBOL_TABLE_F = H5G_flags(10)
    H5G_STORAGE_TYPE_COMPACT_F      = H5G_flags(11)
    H5G_STORAGE_TYPE_DENSE_F        = H5G_flags(12)
    !
    ! H5D flags
    !
    H5D_COMPACT_F                   = H5D_flags(1)
    H5D_CONTIGUOUS_F                = H5D_flags(2)
    H5D_CHUNKED_F                   = H5D_flags(3)
    H5D_ALLOC_TIME_ERROR_F          = H5D_flags(4)
    H5D_ALLOC_TIME_DEFAULT_F        = H5D_flags(5)
    H5D_ALLOC_TIME_EARLY_F          = H5D_flags(6)
    H5D_ALLOC_TIME_LATE_F           = H5D_flags(7)
    H5D_ALLOC_TIME_INCR_F           = H5D_flags(8)
    H5D_SPACE_STS_ERROR_F           = H5D_flags(9)
    H5D_SPACE_STS_NOT_ALLOCATED_F   = H5D_flags(10)
    H5D_SPACE_STS_PART_ALLOCATED_F  = H5D_flags(11)
    H5D_SPACE_STS_ALLOCATED_F       = H5D_flags(12)
    H5D_FILL_TIME_ERROR_F           = H5D_flags(13)
    H5D_FILL_TIME_ALLOC_F           = H5D_flags(14)
    H5D_FILL_TIME_NEVER_F           = H5D_flags(15)
    H5D_FILL_VALUE_ERROR_F          = H5D_flags(16)
    H5D_FILL_VALUE_UNDEFINED_F      = H5D_flags(17)
    H5D_FILL_VALUE_DEFAULT_F        = H5D_flags(18)
    H5D_FILL_VALUE_USER_DEFINED_F   = H5D_flags(19)
    H5D_CHUNK_CACHE_W0_DFLT_F       = H5D_flags(20)
    H5D_MPIO_NO_COLLECTIVE_F        = H5D_flags(21)
    H5D_MPIO_CHUNK_INDEPENDENT_F    = H5D_flags(22)
    H5D_MPIO_CHUNK_COLLECTIVE_F     = H5D_flags(23)
    H5D_MPIO_CHUNK_MIXED_F          = H5D_flags(24)
    H5D_MPIO_CONTIG_COLLECTIVE_F    = H5D_flags(25)
    H5D_VDS_ERROR_F                 = H5D_flags(26)
    H5D_VDS_FIRST_MISSING_F         = H5D_flags(27)
    H5D_VDS_LAST_AVAILABLE_F        = H5D_flags(28)
    H5D_VIRTUAL_F                   = H5D_flags(29)
    H5D_SELECTION_IO_MODE_DEFAULT_F = H5D_flags(30)
    H5D_SELECTION_IO_MODE_OFF_F     = H5D_flags(31)
    H5D_SELECTION_IO_MODE_ON_F      = H5D_flags(32)
    H5D_MPIO_COLLECTIVE_F                               = H5D_flags(33)
    H5D_MPIO_SET_INDEPENDENT_F                          = H5D_flags(34)
    H5D_MPIO_DATATYPE_CONVERSION_F                      = H5D_flags(35)
    H5D_MPIO_DATA_TRANSFORMS_F                          = H5D_flags(36)
    H5D_MPIO_MPI_OPT_TYPES_ENV_VAR_DISABLED_F           = H5D_flags(37)
    H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES_F          = H5D_flags(38)
    H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_F        = H5D_flags(39)
    H5D_MPIO_PARALLEL_FILTERED_WRITES_DISABLED_F        = H5D_flags(40)
    H5D_MPIO_ERROR_WHILE_CHECKING_COLLECTIVE_POSSIBLE_F = H5D_flags(41)
    H5D_MPIO_NO_SELECTION_IO_F                          = H5D_flags(42)
    H5D_MPIO_NO_COLLECTIVE_MAX_CAUSE_F                  = H5D_flags(43)
    H5D_SEL_IO_DISABLE_BY_API_F                         = H5D_flags(44)
    H5D_SEL_IO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_F      = H5D_flags(45)
    H5D_SEL_IO_CONTIGUOUS_SIEVE_BUFFER_F                = H5D_flags(46)
    H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB_F           = H5D_flags(47)
    H5D_SEL_IO_PAGE_BUFFER_F                            = H5D_flags(48)
    H5D_SEL_IO_DATASET_FILTER_F                         = H5D_flags(49)
    H5D_SEL_IO_CHUNK_CACHE_F                            = H5D_flags(50)
    H5D_SEL_IO_TCONV_BUF_TOO_SMALL_F                    = H5D_flags(51)
    H5D_SEL_IO_BKG_BUF_TOO_SMALL_F                      = H5D_flags(52)
    H5D_SEL_IO_DEFAULT_OFF_F                            = H5D_flags(53)
    H5D_MPIO_NO_SELECTION_IO_CAUSES_F                   = H5D_flags(54)
    H5D_MPIO_NO_CHUNK_OPTIMIZATION_F                    = H5D_flags(55)
    H5D_MPIO_LINK_CHUNK_F                               = H5D_flags(56)
    H5D_MPIO_MULTI_CHUNK_F                              = H5D_flags(57)
    H5D_SCALAR_IO_F                                     = H5D_flags(58)
    H5D_VECTOR_IO_F                                     = H5D_flags(59)
    H5D_SELECTION_IO_F                                  = H5D_flags(60)

    H5D_CHUNK_CACHE_NSLOTS_DFLT_F = H5D_size_flags(1)
    H5D_CHUNK_CACHE_NBYTES_DFLT_F = H5D_size_flags(2)
    !
    ! H5E flags
    !
    H5E_DEFAULT_F = H5E_hid_flags(1)

    H5E_MAJOR_F         = H5E_flags(1)
    H5E_MINOR_F         = H5E_flags(2)
    H5E_WALK_UPWARD_F   = H5E_flags(3)
    H5E_WALK_DOWNWARD_F = H5E_flags(4)
    !
    ! H5ES flags
    !
    H5ES_NONE_F = H5ES_hid_flags(1)

    H5ES_STATUS_IN_PROGRESS_F = INT(H5ES_flags(1))
    H5ES_STATUS_SUCCEED_F     = INT(H5ES_flags(2))
    H5ES_STATUS_CANCELED_F    = INT(H5ES_flags(3))
    H5ES_STATUS_FAIL_F        = INT(H5ES_flags(4))

    H5ES_WAIT_FOREVER_F = HUGE(0_C_INT64_T)
    H5ES_WAIT_NONE_F    = 0_C_INT64_T

    !
    ! H5FD flags
    !
    H5FD_MPIO_INDEPENDENT_F               = H5FD_flags(1)
    H5FD_MPIO_COLLECTIVE_F                = H5FD_flags(2)
    H5FD_MEM_NOLIST_F                     = H5FD_flags(3)
    H5FD_MEM_DEFAULT_F                    = H5FD_flags(4)
    H5FD_MEM_SUPER_F                      = H5FD_flags(5)
    H5FD_MEM_BTREE_F                      = H5FD_flags(6)
    H5FD_MEM_DRAW_F                       = H5FD_flags(7)
    H5FD_MEM_GHEAP_F                      = H5FD_flags(8)
    H5FD_MEM_LHEAP_F                      = H5FD_flags(9)
    H5FD_MEM_OHDR_F                       = H5FD_flags(10)
    H5FD_MEM_NTYPES_F                     = H5FD_flags(11)
    H5FD_SUBFILING_CURR_FAPL_VERSION_F    = H5FD_flags(12)
    H5FD_SUBFILING_FAPL_MAGIC_F           = H5FD_flags(13)
    H5FD_SUBFILING_DEFAULT_STRIPE_COUNT_F = H5FD_flags(14)
    H5FD_IOC_FAPL_MAGIC_F                 = H5FD_flags(15)
    H5FD_IOC_CURR_FAPL_VERSION_F          = H5FD_flags(16)
    H5FD_IOC_DEFAULT_THREAD_POOL_SIZE_F   = H5FD_flags(17)
    SELECT_IOC_ONE_PER_NODE_F             = H5FD_flags(18)
    SELECT_IOC_EVERY_NTH_RANK_F           = H5FD_flags(19)
    SELECT_IOC_WITH_CONFIG_F              = H5FD_flags(20)
    SELECT_IOC_TOTAL_F                    = H5FD_flags(21)
    IOC_SELECTION_OPTIONS_F               = H5FD_flags(22)

    !
    ! H5FD file driver flags
    !
    H5FD_CORE_F      = H5FD_hid_flags(1)
    H5FD_FAMILY_F    = H5FD_hid_flags(2)
    H5FD_LOG_F       = H5FD_hid_flags(3)
    H5FD_MPIO_F      = H5FD_hid_flags(4)
    H5FD_MULTI_F     = H5FD_hid_flags(5)
    H5FD_SEC2_F      = H5FD_hid_flags(6)
    H5FD_STDIO_F     = H5FD_hid_flags(7)
    H5FD_SUBFILING_F = H5FD_hid_flags(8)
    H5FD_SUBFILING_DEFAULT_STRIPE_SIZE_F = H5FD_hid_flags(9)
    !
    ! H5I flags declaration
    !
    H5I_FILE_F        = H5I_flags(1)
    H5I_GROUP_F       = H5I_flags(2)
    H5I_DATATYPE_F    = H5I_flags(3)
    H5I_DATASPACE_F   = H5I_flags(4)
    H5I_DATASET_F     = H5I_flags(5)
    H5I_ATTR_F        = H5I_flags(6)
    H5I_BADID_F       = H5I_flags(7)
    H5I_UNINIT_F      = H5I_flags(8)
    H5I_VFL_F         = H5I_flags(9)
    H5I_VOL_F         = H5I_flags(10)
    H5I_GENPROP_CLS_F = H5I_flags(11)
    H5I_GENPROP_LST_F = H5I_flags(12)
    H5I_ERROR_CLASS_F = H5I_flags(13)
    H5I_ERROR_MSG_F   = H5I_flags(14)
    H5I_ERROR_STACK_F = H5I_flags(15)
    H5I_NTYPES_F      = H5I_flags(16)
    H5I_INVALID_HID_F = H5I_flags(17)
    !
    ! H5L flags
    !
    H5L_TYPE_ERROR_F        = H5L_flags(1)
    H5L_TYPE_HARD_F         = H5L_flags(2)
    H5L_TYPE_SOFT_F         = H5L_flags(3)
    H5L_TYPE_EXTERNAL_F     = H5L_flags(4)
    H5L_SAME_LOC_F          = H5L_flags(5)
    H5L_LINK_CLASS_T_VERS_F = H5L_flags(6)
    !
    ! H5O flags
    !
    H5O_COPY_SHALLOW_HIERARCHY_F   = h5o_flags(1)
    H5O_COPY_EXPAND_SOFT_LINK_F    = h5o_flags(2)
    H5O_COPY_EXPAND_EXT_LINK_F     = h5o_flags(3)
    H5O_COPY_EXPAND_REFERENCE_F    = h5o_flags(4)
    H5O_COPY_WITHOUT_ATTR_FLAG_F   = h5o_flags(5)
    H5O_COPY_PRESERVE_NULL_FLAG_F  = h5o_flags(6)
    H5O_COPY_ALL_F                 = h5o_flags(7)
    H5O_SHMESG_NONE_FLAG_F         = h5o_flags(8)
    H5O_SHMESG_SDSPACE_FLAG_F      = h5o_flags(9)
    H5O_SHMESG_DTYPE_FLAG_F        = h5o_flags(10)
    H5O_SHMESG_FILL_FLAG_F         = h5o_flags(11)
    H5O_SHMESG_PLINE_FLAG_F        = h5o_flags(12)
    H5O_SHMESG_ATTR_FLAG_F         = h5o_flags(13)
    H5O_SHMESG_ALL_FLAG_F          = h5o_flags(14)
    H5O_HDR_CHUNK0_SIZE_F          = h5o_flags(15)
    H5O_HDR_ATTR_CRT_ORDER_TRACK_F = h5o_flags(16)
    H5O_HDR_ATTR_CRT_ORDER_INDEX_F = h5o_flags(17)
    H5O_HDR_ATTR_STORE_PHASE_CHA_F = h5o_flags(18)
    H5O_HDR_STORE_TIMES_F          = h5o_flags(19)
    H5O_HDR_ALL_FLAGS_F            = h5o_flags(20)
    H5O_SHMESG_MAX_NINDEXES_F      = h5o_flags(21)
    H5O_SHMESG_MAX_LIST_SIZE_F     = h5o_flags(22)
    H5O_TYPE_UNKNOWN_F             = h5o_flags(23)
    H5O_TYPE_GROUP_F               = h5o_flags(24)
    H5O_TYPE_DATASET_F             = h5o_flags(25)
    H5O_TYPE_NAMED_DATATYPE_F      = h5o_flags(26)
    H5O_TYPE_NTYPES_F              = h5o_flags(27)
    H5O_INFO_ALL_F                 = h5o_flags(28)
    H5O_INFO_BASIC_F               = h5o_flags(29)
    H5O_INFO_TIME_F                = h5o_flags(30)
    H5O_INFO_NUM_ATTRS_F           = h5o_flags(31)
    H5O_INFO_HDR_F                 = h5o_flags(32)
    H5O_INFO_META_SIZE_F           = h5o_flags(33)
    !
    ! H5P flags
    !
    H5P_FILE_CREATE_F      = H5P_flags(1)
    H5P_FILE_ACCESS_F      = H5P_flags(2)
    H5P_DATASET_CREATE_F   = H5P_flags(3)
    H5P_DATASET_XFER_F     = H5P_flags(4)
    H5P_FILE_MOUNT_F       = H5P_flags(5)
    H5P_DEFAULT_F          = H5P_flags(6)
    H5P_ROOT_F             = H5P_flags(7)
    H5P_OBJECT_CREATE_F    = H5P_flags(8)
    H5P_DATASET_ACCESS_F   = H5P_flags(9)
    H5P_GROUP_CREATE_F     = H5P_flags(10)
    H5P_GROUP_ACCESS_F     = H5P_flags(11)
    H5P_DATATYPE_CREATE_F  = H5P_flags(12)
    H5P_DATATYPE_ACCESS_F  = H5P_flags(13)
    H5P_STRING_CREATE_F    = H5P_flags(14)
    H5P_ATTRIBUTE_CREATE_F = H5P_flags(15)
    H5P_OBJECT_COPY_F      = H5P_flags(16)
    H5P_LINK_CREATE_F      = H5P_flags(17)
    H5P_LINK_ACCESS_F      = H5P_flags(18)
    !
    ! H5P integers flags
    !
    H5P_CRT_ORDER_INDEXED_F = H5P_flags_int(1)
    H5P_CRT_ORDER_TRACKED_F = H5P_flags_int(2)
    !
    ! H5R flags
    !
    H5R_OBJECT_F          = H5R_flags(1)
    H5R_DATASET_REGION_F  = H5R_flags(2)
    H5R_BADTYPE_F         = H5R_flags(3)
    H5R_OBJECT1_F         = H5R_flags(4)
    H5R_DATASET_REGION1_F = H5R_flags(5)
    H5R_OBJECT2_F         = H5R_flags(6)
    H5R_DATASET_REGION2_F = H5R_flags(7)
    H5R_ATTR_F            = H5R_flags(8)
    H5R_MAXTYPE_F         = H5R_flags(9)
    !
    ! H5S flags
    !
    H5S_ALL_F   = H5S_hid_flags(1)
    H5S_BLOCK_F = H5S_hid_flags(2)
    H5S_PLIST_F = H5S_hid_flags(3)

    H5S_UNLIMITED_F = H5S_hsize_flags(1)

    H5S_SCALAR_F         = H5S_flags(1)
    H5S_SIMPLE_F         = H5S_flags(2)
    H5S_NULL_F           = H5S_flags(3)
    H5S_SELECT_SET_F     = H5S_flags(4)
    H5S_SELECT_OR_F      = H5S_flags(5)
    H5S_SELECT_NOOP_F    = H5S_flags(6)
    H5S_SELECT_AND_F     = H5S_flags(7)
    H5S_SELECT_XOR_F     = H5S_flags(8)
    H5S_SELECT_NOTB_F    = H5S_flags(9)
    H5S_SELECT_NOTA_F    = H5S_flags(10)
    H5S_SELECT_APPEND_F  = H5S_flags(11)
    H5S_SELECT_PREPEND_F = H5S_flags(12)
    H5S_SELECT_INVALID_F = H5S_flags(13)
    H5S_SEL_ERROR_F      = H5S_flags(14)
    H5S_SEL_NONE_F       = H5S_flags(15)
    H5S_SEL_POINTS_F     = H5S_flags(16)
    H5S_SEL_HYPERSLABS_F = H5S_flags(17)
    H5S_SEL_ALL_F        = H5S_flags(18)
    H5S_SEL_ITER_GET_SEQ_LIST_SORTED_F  = H5S_flags(19)
    H5S_SEL_ITER_SHARE_WITH_DATASPACE_F = H5S_flags(20)
    !
    ! H5T flags declaration
    !
    H5T_NO_CLASS_F       = H5T_flags(1)
    H5T_INTEGER_F        = H5T_flags(2)
    H5T_FLOAT_F          = H5T_flags(3)
    H5T_TIME_F           = H5T_flags(4)
    H5T_STRING_F         = H5T_flags(5)
    H5T_BITFIELD_F       = H5T_flags(6)
    H5T_OPAQUE_F         = H5T_flags(7)
    H5T_COMPOUND_F       = H5T_flags(8)
    H5T_REFERENCE_F      = H5T_flags(9)
    H5T_ENUM_F           = H5T_flags(10)
    H5T_ORDER_LE_F       = H5T_flags(11)
    H5T_ORDER_BE_F       = H5T_flags(12)
    H5T_ORDER_MIXED_F    = H5T_flags(13)
    H5T_ORDER_VAX_F      = H5T_flags(14)
    H5T_ORDER_NONE_F     = H5T_flags(15)
    H5T_PAD_ZERO_F       = H5T_flags(16)
    H5T_PAD_ONE_F        = H5T_flags(17)
    H5T_PAD_BACKGROUND_F = H5T_flags(18)
    H5T_PAD_ERROR_F      = H5T_flags(19)
    H5T_SGN_NONE_F       = H5T_flags(20)
    H5T_SGN_2_F          = H5T_flags(21)
    H5T_SGN_ERROR_F      = H5T_flags(22)
    H5T_NORM_IMPLIED_F   = H5T_flags(23)
    H5T_NORM_MSBSET_F    = H5T_flags(24)
    H5T_NORM_NONE_F      = H5T_flags(25)
    H5T_CSET_ASCII_F     = H5T_flags(26)
    H5T_CSET_UTF8_F      = H5T_flags(27)
    H5T_STR_NULLTERM_F   = H5T_flags(28)
    H5T_STR_NULLPAD_F    = H5T_flags(29)
    H5T_STR_SPACEPAD_F   = H5T_flags(30)
    H5T_STR_ERROR_F      = H5T_flags(31)
    H5T_VLEN_F           = H5T_flags(32)
    H5T_ARRAY_F          = H5T_flags(33)
    H5T_DIR_ASCEND_F     = H5T_flags(34)
    H5T_DIR_DESCEND_F    = H5T_flags(35)
    !
    ! H5VL flags
    !
    H5VL_VERSION_F   = H5VL_flags(1)
    H5_VOL_INVALID_F = H5VL_flags(2)
    H5_VOL_NATIVE_F  = H5VL_flags(3)

    H5VL_CAP_FLAG_NONE_F             = H5VL_int64_flags(1)
    H5VL_CAP_FLAG_THREADSAFE_F       = H5VL_int64_flags(2)
    H5VL_CAP_FLAG_ASYNC_F            = H5VL_int64_flags(3)
    H5VL_CAP_FLAG_NATIVE_FILES_F     = H5VL_int64_flags(4)
    H5VL_CAP_FLAG_ATTR_BASIC_F       = H5VL_int64_flags(5)
    H5VL_CAP_FLAG_ATTR_MORE_F        = H5VL_int64_flags(6)
    H5VL_CAP_FLAG_DATASET_BASIC_F    = H5VL_int64_flags(7)
    H5VL_CAP_FLAG_DATASET_MORE_F     = H5VL_int64_flags(8)
    H5VL_CAP_FLAG_FILE_BASIC_F       = H5VL_int64_flags(9)
    H5VL_CAP_FLAG_FILE_MORE_F        = H5VL_int64_flags(10)
    H5VL_CAP_FLAG_GROUP_BASIC_F      = H5VL_int64_flags(11)
    H5VL_CAP_FLAG_GROUP_MORE_F       = H5VL_int64_flags(12)
    H5VL_CAP_FLAG_LINK_BASIC_F       = H5VL_int64_flags(13)
    H5VL_CAP_FLAG_LINK_MORE_F        = H5VL_int64_flags(14)
    H5VL_CAP_FLAG_MAP_BASIC_F        = H5VL_int64_flags(15)
    H5VL_CAP_FLAG_MAP_MORE_F         = H5VL_int64_flags(16)
    H5VL_CAP_FLAG_OBJECT_BASIC_F     = H5VL_int64_flags(17)
    H5VL_CAP_FLAG_OBJECT_MORE_F      = H5VL_int64_flags(18)
    H5VL_CAP_FLAG_REF_BASIC_F        = H5VL_int64_flags(19)
    H5VL_CAP_FLAG_REF_MORE_F         = H5VL_int64_flags(20)
    H5VL_CAP_FLAG_OBJ_REF_F          = H5VL_int64_flags(21)
    H5VL_CAP_FLAG_REG_REF_F          = H5VL_int64_flags(22)
    H5VL_CAP_FLAG_ATTR_REF_F         = H5VL_int64_flags(23)
    H5VL_CAP_FLAG_STORED_DATATYPES_F = H5VL_int64_flags(24)
    H5VL_CAP_FLAG_CREATION_ORDER_F   = H5VL_int64_flags(25)
    H5VL_CAP_FLAG_ITERATE_F          = H5VL_int64_flags(26)
    H5VL_CAP_FLAG_STORAGE_SIZE_F     = H5VL_int64_flags(27)
    H5VL_CAP_FLAG_BY_IDX_F           = H5VL_int64_flags(28)
    H5VL_CAP_FLAG_GET_PLIST_F        = H5VL_int64_flags(29)
    H5VL_CAP_FLAG_FLUSH_REFRESH_F    = H5VL_int64_flags(30)
    H5VL_CAP_FLAG_EXTERNAL_LINKS_F   = H5VL_int64_flags(31)
    H5VL_CAP_FLAG_HARD_LINKS_F       = H5VL_int64_flags(32)
    H5VL_CAP_FLAG_SOFT_LINKS_F       = H5VL_int64_flags(33)
    H5VL_CAP_FLAG_UD_LINKS_F         = H5VL_int64_flags(34)
    H5VL_CAP_FLAG_TRACK_TIMES_F      = H5VL_int64_flags(35)
    H5VL_CAP_FLAG_MOUNT_F            = H5VL_int64_flags(36)
    H5VL_CAP_FLAG_FILTERS_F          = H5VL_int64_flags(37)
    H5VL_CAP_FLAG_FILL_VALUES_F      = H5VL_int64_flags(38)

    H5VL_OPT_QUERY_SUPPORTED_F       = H5VL_int64_flags(39)
    H5VL_OPT_QUERY_READ_DATA_F       = H5VL_int64_flags(40)
    H5VL_OPT_QUERY_WRITE_DATA_F      = H5VL_int64_flags(41)
    H5VL_OPT_QUERY_QUERY_METADATA_F  = H5VL_int64_flags(42)
    H5VL_OPT_QUERY_MODIFY_METADATA_F = H5VL_int64_flags(43)
    H5VL_OPT_QUERY_COLLECTIVE_F      = H5VL_int64_flags(44)
    H5VL_OPT_QUERY_NO_ASYNC_F        = H5VL_int64_flags(45)
    H5VL_OPT_QUERY_MULTI_OBJ_F       = H5VL_int64_flags(46)

    !
    ! H5Z flags
    !
    H5Z_FILTER_ERROR_F           = H5Z_flags(1)
    H5Z_FILTER_NONE_F            = H5Z_flags(2)
    H5Z_FILTER_DEFLATE_F         = H5Z_flags(3)
    H5Z_FILTER_SHUFFLE_F         = H5Z_flags(4)
    H5Z_FILTER_FLETCHER32_F      = H5Z_flags(5)
    H5Z_ERROR_EDC_F              = H5Z_flags(6)
    H5Z_DISABLE_EDC_F            = H5Z_flags(7)
    H5Z_ENABLE_EDC_F             = H5Z_flags(8)
    H5Z_NO_EDC_F                 = H5Z_flags(9)
    H5Z_FILTER_SZIP_F            = H5Z_flags(10)
    H5Z_FLAG_OPTIONAL_F          = H5Z_flags(11)
    H5Z_FILTER_ENCODE_ENABLED_F  = H5Z_flags(12)
    H5Z_FILTER_DECODE_ENABLED_F  = H5Z_flags(13)
    H5Z_FILTER_ALL_F             = H5Z_flags(14)
    H5Z_FILTER_NBIT_F            = H5Z_flags(15)
    H5Z_FILTER_SCALEOFFSET_F     = H5Z_flags(16)
    H5Z_SO_FLOAT_DSCALE_F        = H5Z_flags(17)
    H5Z_SO_FLOAT_ESCALE_F        = H5Z_flags(18)
    H5Z_SO_INT_F                 = H5Z_flags(19)
    H5Z_SO_INT_MINBITS_DEFAULT_F = H5Z_flags(20)

    error = error + h5init1_flags_c(H5LIB_flags)
    !
    ! H5 Library flags
    !
    H5_SZIP_EC_OM_F = H5LIB_flags(1)
    H5_SZIP_NN_OM_F = H5LIB_flags(2)

    CALL h5fget_obj_count_f(INT(H5F_OBJ_ALL_F,HID_T), H5F_OBJ_ALL_F, H5OPEN_NUM_OBJ_LOC,  error)

    H5OPEN_NUM_OBJ = H5OPEN_NUM_OBJ_LOC

  END SUBROUTINE h5open_f

!>
!! \ingroup FH5
!!
!! \brief Closes HDF5 Fortran interface.
!!
!! \param error \fortran_error
!!
  SUBROUTINE h5close_f(error)
    USE H5F, ONLY : h5fget_obj_count_f, H5OPEN_NUM_OBJ
    IMPLICIT NONE
    INTEGER, INTENT(OUT) :: error
    INTERFACE
       INTEGER FUNCTION h5close_types_c(p_types, P_TYPES_LEN, &
            f_types, F_TYPES_LEN, &
            i_types, I_TYPES_LEN ) &
            BIND(C,NAME='h5close_types_c')
         IMPORT :: HID_T
         INTEGER :: P_TYPES_LEN
         INTEGER :: F_TYPES_LEN
         INTEGER :: I_TYPES_LEN
         INTEGER(HID_T), DIMENSION(1:P_TYPES_LEN) :: p_types
         INTEGER(HID_T), DIMENSION(1:F_TYPES_LEN) :: f_types
         INTEGER(HID_T), DIMENSION(1:I_TYPES_LEN) :: i_types
       END FUNCTION h5close_types_c
    END INTERFACE

    ! Check if h5close_f has already been called. Skip doing it again.
    IF(H5OPEN_NUM_OBJ .EQ. 0) RETURN

    error = h5close_types_c(predef_types, PREDEF_TYPES_LEN, &
         floating_types, FLOATING_TYPES_LEN, &
         integer_types, INTEGER_TYPES_LEN )

    ! Reset the number of open objects from h5open_f to zero
    CALL h5fget_obj_count_f(INT(H5F_OBJ_ALL_F,HID_T), H5F_OBJ_ALL_F, H5OPEN_NUM_OBJ,  error)

  END SUBROUTINE h5close_f

!>
!! \ingroup FH5
!!
!! \brief Returns the HDF5 LIbrary release number
!!
!! \param majnum  Major version of the library.
!! \param minnum  Minor version of the library.
!! \param relnum  Release version of the library.
!! \param error   \fortran_error
!!
!! See C API: @ref H5get_libversion()
!!
  SUBROUTINE h5get_libversion_f(majnum, minnum, relnum, error)
    IMPLICIT NONE
    INTEGER, INTENT(OUT) :: majnum, minnum, relnum, error
    INTERFACE
       INTEGER FUNCTION h5get_libversion_c(majnum, minnum, relnum) &
            BIND(C,NAME='h5get_libversion_c')
         IMPLICIT NONE
         INTEGER, INTENT(OUT) :: majnum, minnum, relnum
       END FUNCTION h5get_libversion_c
    END INTERFACE

    error = h5get_libversion_c(majnum, minnum, relnum)

  END SUBROUTINE h5get_libversion_f

!>
!! \ingroup FH5
!!
!! \brief Verifies that library versions are consistent.
!!
!! \param majnum Major version of the library.
!! \param minnum Minor version of the library.
!! \param relnum Release version of the library.
!! \param error  \fortran_error
!!
!! See C API: @ref H5check_version()
!!
  SUBROUTINE h5check_version_f(majnum, minnum, relnum, error)
    IMPLICIT NONE
    INTEGER, INTENT(IN)  :: majnum, minnum, relnum
    INTEGER, INTENT(OUT) :: error
    INTERFACE
       INTEGER FUNCTION h5check_version_c(majnum, minnum, relnum) &
            BIND(C,NAME='h5check_version_c')
         IMPLICIT NONE
         INTEGER, INTENT(IN) :: majnum, minnum, relnum
       END FUNCTION h5check_version_c
    END INTERFACE

    error = h5check_version_c(majnum, minnum, relnum)

  END SUBROUTINE h5check_version_f
!>
!! \ingroup FH5
!!
!! \brief Garbage collects on all free-lists of all types.
!!
!! \param error \fortran_error
!!
!! See C API: @ref H5garbage_collect()
!!
  SUBROUTINE h5garbage_collect_f(error)
    IMPLICIT NONE
    INTEGER, INTENT(OUT) :: error
    INTERFACE
       INTEGER FUNCTION h5garbage_collect_c() BIND(C,NAME='h5garbage_collect_c')
         IMPLICIT NONE
       END FUNCTION h5garbage_collect_c
    END INTERFACE

    error = h5garbage_collect_c()

  END SUBROUTINE h5garbage_collect_f
!>
!! \ingroup FH5
!!
!! \brief Instructs library not to install atexit cleanup routine.
!!
!! \param error \fortran_error
!!
!! See C API: @ref H5dont_atexit()
!!
  SUBROUTINE h5dont_atexit_f(error)
    IMPLICIT NONE
    INTEGER, INTENT(OUT) :: error
    INTERFACE
       INTEGER FUNCTION h5dont_atexit_c() BIND(C,NAME='h5dont_atexit_c')
         IMPLICIT NONE
       END FUNCTION h5dont_atexit_c
    END INTERFACE

    error = h5dont_atexit_c()

  END SUBROUTINE h5dont_atexit_f

!>
!! \ingroup FH5
!! \brief Gets the current size of the free lists used to manage memory
!!
!! \param reg_size The current size of all "regular" free list memory used
!! \param arr_size The current size of all "array" free list memory used
!! \param blk_size The current size of all "block" free list memory used
!! \param fac_size The current size of all "factory" free list memory used
!! \param error \fortran_error
!!
!! See C API: @ref H5get_free_list_sizes()
!!
  SUBROUTINE h5get_free_list_sizes_f(reg_size, arr_size, blk_size, fac_size, error)
    IMPLICIT NONE
    INTEGER(C_SIZE_T), INTENT(OUT) :: reg_size
    INTEGER(C_SIZE_T), INTENT(OUT) :: arr_size
    INTEGER(C_SIZE_T), INTENT(OUT) :: blk_size
    INTEGER(C_SIZE_T), INTENT(OUT) :: fac_size
    INTEGER, INTENT(OUT) :: error

    INTERFACE
       INTEGER(C_INT) FUNCTION H5get_free_list_sizes(reg_size, arr_size, blk_size, fac_size) BIND(C,NAME='H5get_free_list_sizes')
         IMPORT :: C_INT, C_SIZE_T
         IMPLICIT NONE
         INTEGER(C_SIZE_T), INTENT(OUT) :: reg_size
         INTEGER(C_SIZE_T), INTENT(OUT) :: arr_size
         INTEGER(C_SIZE_T), INTENT(OUT) :: blk_size
         INTEGER(C_SIZE_T), INTENT(OUT) :: fac_size
       END FUNCTION H5get_free_list_sizes
    END INTERFACE

    error = INT(H5get_free_list_sizes(reg_size, arr_size, blk_size, fac_size))

  END SUBROUTINE h5get_free_list_sizes_f

!>
!! \ingroup FH5
!!
!! \brief Converts the KIND to the correct HDF type
!!
!! \param ikind Fortran KIND parameter
!! \param flag Whether KIND is of type INTEGER or REAL:
!!             \li H5_INTEGER_KIND - integer
!!             \li H5_REAL_KIND    - real
!! \result h5_type Returns the type.
!!
  INTEGER(HID_T) FUNCTION h5kind_to_type(ikind, flag) RESULT(h5_type)
    USE ISO_C_BINDING
    IMPLICIT NONE
    INTEGER, INTENT(IN) :: ikind
    INTEGER, INTENT(IN) :: flag
    INTEGER :: i

!#if H5_HAVE_Fortran_INTEGER_SIZEOF_16!=0
!    ! (1) The array index assumes INTEGER*16 the last integer in the series, and
!    ! (2) it should map to INTEGER*16 on most modern processors
!    H5T_NATIVE_INTEGER_KIND(H5_FORTRAN_NUM_INTEGER_KINDS)=SELECTED_INT_KIND(36)
!#endif

    h5_type = -1
    IF(flag.EQ.H5_INTEGER_KIND)THEN
       do_kind: DO i = 1, H5_FORTRAN_NUM_INTEGER_KINDS
          IF(ikind.EQ.Fortran_INTEGER_AVAIL_KINDS(i))THEN
             h5_type = H5T_NATIVE_INTEGER_KIND(i)
             EXIT do_kind
          ENDIF
       END DO do_kind
    ELSE IF(flag.EQ.H5_REAL_KIND)THEN
       IF(ikind.EQ.KIND(1.0_C_FLOAT))THEN
          h5_type = H5T_NATIVE_REAL_C_FLOAT
       ELSE IF(ikind.EQ.KIND(1.0_C_DOUBLE))THEN
          h5_type = H5T_NATIVE_REAL_C_DOUBLE
#if H5_FORTRAN_C_LONG_DOUBLE_IS_UNIQUE!=0
       ELSE IF(ikind.EQ.KIND(1.0_C_LONG_DOUBLE))THEN
          h5_type = H5T_NATIVE_REAL_C_LONG_DOUBLE
#endif
#if H5_PAC_FC_MAX_REAL_PRECISION > 28
#ifdef H5_HAVE_FLOAT128
       ELSE
          h5_type = H5T_NATIVE_FLOAT_128
#endif
#endif
       ENDIF
    ENDIF

  END FUNCTION h5kind_to_type

!>
!! \ingroup FH5
!!
!! \brief Computes the offset in memory
!!
!! \param start  Starting pointer address
!! \param end    Ending pointer address
!!
!! \result offset Offset of a member within the derived type.
!!
  FUNCTION h5offsetof(start,end) RESULT(offset)
    IMPLICIT NONE
    INTEGER(SIZE_T) :: offset
    TYPE(C_PTR), VALUE, INTENT(IN) :: start, end
    INTEGER(C_INTPTR_T) :: int_address_start, int_address_end
    int_address_start = TRANSFER(start, int_address_start)
    int_address_end   = TRANSFER(end  , int_address_end  )

    offset = int_address_end - int_address_start

  END FUNCTION h5offsetof

!>
!! \ingroup FH5
!!
!! \brief Convert time_t structure (C) to Fortran DATE AND TIME storage format.
!!
!! \param stdtime_t Object of type time_t that contains a time value
!! \result datetime  A date/time array using Fortran conventions:
!!                  \li datetime(1) = year
!!                  \li datetime(2) = month
!!                  \li datetime(3) = day
!!                  \li datetime(4) = 0 ! time is expressed as UTC (or GMT timezone)
!!                  \li datetime(5) = hour
!!                  \li datetime(6) = minute
!!                  \li datetime(7) = second
!!                  \li datetime(8) = millisecond -- not available, assigned - HUGE(0)
!!
  FUNCTION h5gmtime(stdtime_t) RESULT(datetime)
    IMPLICIT NONE
    INTEGER(KIND=TIME_T), INTENT(IN) :: stdtime_t
    INTEGER, DIMENSION(1:8) :: datetime
    TYPE(C_PTR) :: cptr
    INTEGER(C_INT), DIMENSION(:), POINTER :: c_time

    INTERFACE
       FUNCTION gmtime(stdtime_t) BIND(C, NAME='gmtime')
         IMPORT :: TIME_T, C_PTR
         IMPLICIT NONE
         INTEGER(KIND=TIME_T) :: stdtime_t
         TYPE(C_PTR) :: gmtime
       END FUNCTION gmtime
    END INTERFACE

    cptr = gmtime(stdtime_t)
    CALL C_F_POINTER(cptr, c_time, [9])

    datetime(1) = INT(c_time(6)+1900) ! year starts at 1900
    datetime(2) = INT(c_time(5)+1)    ! month starts at 0 in C
    datetime(3) = INT(c_time(4))      ! day
    datetime(4) = 0                   ! time is expressed as UTC (or GMT timezone)
    datetime(5) = INT(c_time(3))      ! hour
    datetime(6) = INT(c_time(2))      ! minute
    datetime(7) = INT(c_time(1))      ! second
    datetime(8) = -32767              ! millisecond is not available, assign it -HUGE(0)

  END FUNCTION h5gmtime

END MODULE H5LIB
