!--------------------------------------------------------------------------------------------------!
! Copyright (C) by the DBCSR developers group - All rights reserved                                !
! This file is part of the DBCSR library.                                                          !
!                                                                                                  !
! For information on the license, see the LICENSE file.                                            !
! For further information please visit https://dbcsr.cp2k.org                                      !
! SPDX-License-Identifier: GPL-2.0+                                                                !
!--------------------------------------------------------------------------------------------------!

MODULE dbcsr_kinds
   !! Defines the basic variable types
   !! @note
   !! Data type definitions; tested on:
   !! - IBM AIX xlf90
   !! - SGI IRIX  f90
   !! - CRAY T3E  f90
   !! - DEC ALPHA f90
   !! - NAG_F90
   !! - SUN
   !! - HITACHI

   IMPLICIT NONE

   PRIVATE
   PUBLIC :: sp, dp, print_kind_info, dp_size, sp_size, int_size
   PUBLIC :: int_1, int_4, int_8, int_1_size, int_2_size, int_4_size, int_8_size
   PUBLIC :: real_4, real_8, real_4_size, real_8_size
   PUBLIC :: default_string_length, default_path_length, max_line_length

   INTEGER, PARAMETER :: sp = SELECTED_REAL_KIND(6, 30)
   INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(14, 200)
   ! we rely on this (libraries) but do not check this
   INTEGER, PARAMETER :: dp_size = 8, &
                         int_size = BIT_SIZE(0)/8, &
                         sp_size = 4

   INTEGER, PARAMETER :: real_4 = SELECTED_REAL_KIND(6, 30)
   INTEGER, PARAMETER :: real_8 = SELECTED_REAL_KIND(14, 200)
   INTEGER, PARAMETER :: real_4_size = 4
   INTEGER, PARAMETER :: real_8_size = 8

   INTEGER, PARAMETER :: int_1 = SELECTED_INT_KIND(2)
   INTEGER, PARAMETER :: int_1_size = BIT_SIZE(INT(0, int_1))/8

   INTEGER, PARAMETER :: int_2 = SELECTED_INT_KIND(4)
   INTEGER, PARAMETER :: int_2_size = BIT_SIZE(INT(0, int_2))/8

   INTEGER, PARAMETER :: int_4 = SELECTED_INT_KIND(5)
   INTEGER, PARAMETER :: int_4_size = BIT_SIZE(INT(0, int_4))/8

   INTEGER, PARAMETER :: int_8 = SELECTED_INT_KIND(10)
   INTEGER, PARAMETER :: int_8_size = BIT_SIZE(INT(0, int_8))/8

   INTEGER, PARAMETER :: default_string_length = 80
   INTEGER, PARAMETER :: default_path_length = 1024
   INTEGER, PARAMETER :: max_line_length = 2*default_path_length
   CHARACTER(LEN=1), PARAMETER, PUBLIC :: default_blank_character(2) = (/" ", CHAR(9)/)

CONTAINS

   SUBROUTINE print_kind_info(iw)
      !! Print informations about the used data types.

      INTEGER, INTENT(IN)                                :: iw

      WRITE (iw, '( /, T2, A )') 'DATA TYPE INFORMATION:'

      WRITE (iw, '( /,T2,A,T79,A,2(/,T2,A,T75,I6),3(/,T2,A,T67,E14.8) )') &
         'REAL: Data type name:', 'dp', '      Kind value:', KIND(0.0_dp), &
         '      Precision:', PRECISION(0.0_dp), &
         '      Smallest non-negligible quantity relative to 1:', &
         EPSILON(0.0_dp), &
         '      Smallest positive number:', TINY(0.0_dp), &
         '      Largest representable number:', HUGE(0.0_dp)
      WRITE (iw, '( /,T2,A,T79,A,2(/,T2,A,T75,I6),3(/,T2,A,T67,E14.8) )') &
         '      Data type name:', 'sp', '      Kind value:', KIND(0.0_sp), &
         '      Precision:', PRECISION(0.0_sp), &
         '      Smallest non-negligible quantity relative to 1:', &
         EPSILON(0.0_sp), &
         '      Smallest positive number:', TINY(0.0_sp), &
         '      Largest representable number:', HUGE(0.0_sp)
      WRITE (iw, '( /,T2,A,T72,A,4(/,T2,A,T61,I20) )') &
         'INTEGER: Data type name:', '(default)', '         Kind value:', &
         KIND(0), &
         '         Bit size:', BIT_SIZE(0), &
         '         Largest representable number:', HUGE(0)
      WRITE (iw, '( /,T2,A,T72,A,/,T2,A,T75,I6,/ )') &
         'LOGICAL: Data type name:', '(default)', &
         '         Kind value:', KIND(.TRUE.)
      WRITE (iw, '( /,T2,A,T72,A,/,T2,A,T75,I6,/ )') &
         'CHARACTER: Data type name:', '(default)', &
         '           Kind value:', KIND('C')

   END SUBROUTINE print_kind_info

END MODULE dbcsr_kinds

