! This automatically generated Fortran wrapper file allows codes
! written in Fortran to be called directly from C and translates all
! C-style arguments into expected Fortran-style arguments (with
! assumed size, local type declarations, etc.).


SUBROUTINE C_TEST_STANDARD(SING_IN, SING_OUT, ARRAY_IN_DIM_1, ARRAY_IN, ARRAY_OUT_DIM_1, ARRAY_OUT, KNOWN_ARRAY_OUT_DIM_1, KNOWN_AR&
&RAY_OUT, KNOWN_MATRIX_OUT_DIM_1, KNOWN_MATRIX_OUT_DIM_2, KNOWN_MATRIX_OUT, OPT_SING_IN_PRESENT, OPT_SING_IN, OPT_SING_OUT_PRESENT,&
& OPT_SING_OUT) BIND(C)
  USE ISO_FORTRAN_ENV , ONLY : REAL128
  USE ISO_FORTRAN_ENV , ONLY : REAL128
  IMPLICIT NONE
  COMPLEX(KIND=REAL128), INTENT(IN) :: SING_IN
  COMPLEX(KIND=REAL128), INTENT(OUT) :: SING_OUT
  INTEGER, INTENT(IN) :: ARRAY_IN_DIM_1
  COMPLEX(KIND=REAL128), INTENT(IN), DIMENSION(ARRAY_IN_DIM_1) :: ARRAY_IN
  INTEGER, INTENT(IN) :: ARRAY_OUT_DIM_1
  COMPLEX(KIND=REAL128), INTENT(OUT), DIMENSION(ARRAY_OUT_DIM_1) :: ARRAY_OUT
  INTEGER, INTENT(IN) :: KNOWN_ARRAY_OUT_DIM_1
  COMPLEX(KIND=REAL128), INTENT(OUT), DIMENSION(KNOWN_ARRAY_OUT_DIM_1) :: KNOWN_ARRAY_OUT
  INTEGER, INTENT(IN) :: KNOWN_MATRIX_OUT_DIM_1
  INTEGER, INTENT(IN) :: KNOWN_MATRIX_OUT_DIM_2
  COMPLEX(KIND=REAL128), INTENT(OUT), DIMENSION(KNOWN_MATRIX_OUT_DIM_1,KNOWN_MATRIX_OUT_DIM_2) :: KNOWN_MATRIX_OUT
  LOGICAL, INTENT(IN) :: OPT_SING_IN_PRESENT
  COMPLEX(KIND=REAL128), INTENT(IN) :: OPT_SING_IN
  LOGICAL, INTENT(IN) :: OPT_SING_OUT_PRESENT
  COMPLEX(KIND=REAL128), INTENT(OUT) :: OPT_SING_OUT

  INTERFACE
    SUBROUTINE TEST_STANDARD(SING_IN, SING_OUT, ARRAY_IN, ARRAY_OUT, KNOWN_ARRAY_OUT, KNOWN_MATRIX_OUT, OPT_SING_IN, OPT_SING_OUT)
      ! Test the basic functionaly of the 'COMPLEX' type and its
      ! interoperability with Python. This includes, inputs, outputs,
      ! array inputs with known and unknown size, optional inputs, and
      ! optional outputs.
      USE ISO_FORTRAN_ENV , ONLY : REAL128
      USE ISO_FORTRAN_ENV , ONLY : REAL128
      IMPLICIT NONE
      COMPLEX(KIND=REAL128), INTENT(IN) :: SING_IN
      COMPLEX(KIND=REAL128), INTENT(OUT) :: SING_OUT
      COMPLEX(KIND=REAL128), INTENT(IN), DIMENSION(:) :: ARRAY_IN
      COMPLEX(KIND=REAL128), INTENT(OUT), DIMENSION(:) :: ARRAY_OUT
      COMPLEX(KIND=REAL128), INTENT(OUT), DIMENSION(SIZE(ARRAY_OUT)) :: KNOWN_ARRAY_OUT
      COMPLEX(KIND=REAL128), INTENT(OUT), DIMENSION(3,SIZE(ARRAY_OUT)) :: KNOWN_MATRIX_OUT
      COMPLEX(KIND=REAL128), INTENT(IN), OPTIONAL :: OPT_SING_IN
      COMPLEX(KIND=REAL128), INTENT(OUT), OPTIONAL :: OPT_SING_OUT
    END SUBROUTINE TEST_STANDARD
  END INTERFACE

  IF (OPT_SING_IN_PRESENT) THEN
    IF (OPT_SING_OUT_PRESENT) THEN
      CALL TEST_STANDARD(SING_IN=SING_IN, SING_OUT=SING_OUT, ARRAY_IN=ARRAY_IN, ARRAY_OUT=ARRAY_OUT, KNOWN_ARRAY_OUT=KNOWN_ARRAY_OU&
&T, KNOWN_MATRIX_OUT=KNOWN_MATRIX_OUT, OPT_SING_IN=OPT_SING_IN, OPT_SING_OUT=OPT_SING_OUT)
    ELSE
      CALL TEST_STANDARD(SING_IN=SING_IN, SING_OUT=SING_OUT, ARRAY_IN=ARRAY_IN, ARRAY_OUT=ARRAY_OUT, KNOWN_ARRAY_OUT=KNOWN_ARRAY_OU&
&T, KNOWN_MATRIX_OUT=KNOWN_MATRIX_OUT, OPT_SING_IN=OPT_SING_IN)
    END IF
  ELSE
    IF (OPT_SING_OUT_PRESENT) THEN
      CALL TEST_STANDARD(SING_IN=SING_IN, SING_OUT=SING_OUT, ARRAY_IN=ARRAY_IN, ARRAY_OUT=ARRAY_OUT, KNOWN_ARRAY_OUT=KNOWN_ARRAY_OU&
&T, KNOWN_MATRIX_OUT=KNOWN_MATRIX_OUT, OPT_SING_OUT=OPT_SING_OUT)
    ELSE
      CALL TEST_STANDARD(SING_IN=SING_IN, SING_OUT=SING_OUT, ARRAY_IN=ARRAY_IN, ARRAY_OUT=ARRAY_OUT, KNOWN_ARRAY_OUT=KNOWN_ARRAY_OU&
&T, KNOWN_MATRIX_OUT=KNOWN_MATRIX_OUT)
    END IF
  END IF
END SUBROUTINE C_TEST_STANDARD


SUBROUTINE C_TEST_EXTENDED(OPT_ARRAY_IN_PRESENT, OPT_ARRAY_IN_DIM_1, OPT_ARRAY_IN, KNOWN_OPT_ARRAY_OUT_PRESENT, KNOWN_OPT_ARRAY_OUT&
&_DIM_1, KNOWN_OPT_ARRAY_OUT, OPT_ALLOC_ARRAY_OUT_PRESENT, OPT_ALLOC_ARRAY_OUT_DIM_1, OPT_ALLOC_ARRAY_OUT, N, ALLOC_ARRAY_OUT_DIM_1&
&, ALLOC_ARRAY_OUT) BIND(C)
  USE ISO_FORTRAN_ENV , ONLY : REAL128
  USE ISO_FORTRAN_ENV, ONLY: INT64
  IMPLICIT NONE
  LOGICAL, INTENT(IN) :: OPT_ARRAY_IN_PRESENT
  INTEGER, INTENT(IN) :: OPT_ARRAY_IN_DIM_1
  COMPLEX(KIND=REAL128), INTENT(IN), DIMENSION(OPT_ARRAY_IN_DIM_1) :: OPT_ARRAY_IN
  LOGICAL, INTENT(IN) :: KNOWN_OPT_ARRAY_OUT_PRESENT
  INTEGER, INTENT(IN) :: KNOWN_OPT_ARRAY_OUT_DIM_1
  COMPLEX(KIND=REAL128), INTENT(OUT), DIMENSION(KNOWN_OPT_ARRAY_OUT_DIM_1) :: KNOWN_OPT_ARRAY_OUT
  LOGICAL, INTENT(IN) :: OPT_ALLOC_ARRAY_OUT_PRESENT
  INTEGER, INTENT(OUT) :: OPT_ALLOC_ARRAY_OUT_DIM_1
  COMPLEX(KIND=REAL128), ALLOCATABLE, SAVE, DIMENSION(:) :: OPT_ALLOC_ARRAY_OUT_LOCAL
  INTEGER(KIND=INT64), INTENT(OUT) :: OPT_ALLOC_ARRAY_OUT
  INTEGER, INTENT(IN) :: N
  INTEGER, INTENT(OUT) :: ALLOC_ARRAY_OUT_DIM_1
  COMPLEX(KIND=REAL128), ALLOCATABLE, SAVE, DIMENSION(:) :: ALLOC_ARRAY_OUT_LOCAL
  INTEGER(KIND=INT64), INTENT(OUT) :: ALLOC_ARRAY_OUT

  INTERFACE
    FUNCTION TEST_EXTENDED(OPT_ARRAY_IN, KNOWN_OPT_ARRAY_OUT, OPT_ALLOC_ARRAY_OUT, N) RESULT(ALLOC_ARRAY_OUT)
      ! Test the extended functionaly of the 'COMPLEX' type and its
      ! interoperability with Python. This includes, optional array
      ! inputs, optional array outputs, and allocatable array outputs.
      USE ISO_FORTRAN_ENV , ONLY : REAL128
      IMPLICIT NONE
      COMPLEX(KIND=REAL128), INTENT(IN), OPTIONAL, DIMENSION(:) :: OPT_ARRAY_IN
      COMPLEX(KIND=REAL128), INTENT(OUT), OPTIONAL, DIMENSION(3) :: KNOWN_OPT_ARRAY_OUT
      COMPLEX(KIND=REAL128), INTENT(OUT), OPTIONAL, ALLOCATABLE, DIMENSION(:) :: OPT_ALLOC_ARRAY_OUT
      INTEGER, INTENT(IN) :: N
      COMPLEX(KIND=REAL128), ALLOCATABLE, DIMENSION(:) :: ALLOC_ARRAY_OUT
    END FUNCTION TEST_EXTENDED
  END INTERFACE

  IF (OPT_ARRAY_IN_PRESENT) THEN
    IF (KNOWN_OPT_ARRAY_OUT_PRESENT) THEN
      IF (OPT_ALLOC_ARRAY_OUT_PRESENT) THEN
        ALLOC_ARRAY_OUT_LOCAL = TEST_EXTENDED(N=N, OPT_ARRAY_IN=OPT_ARRAY_IN, KNOWN_OPT_ARRAY_OUT=KNOWN_OPT_ARRAY_OUT, OPT_ALLOC_AR&
&RAY_OUT=OPT_ALLOC_ARRAY_OUT_LOCAL)
        OPT_ALLOC_ARRAY_OUT_DIM_1 = SIZE(OPT_ALLOC_ARRAY_OUT_LOCAL,1)
        OPT_ALLOC_ARRAY_OUT = LOC(OPT_ALLOC_ARRAY_OUT_LOCAL(1))
      ELSE
        ALLOC_ARRAY_OUT_LOCAL = TEST_EXTENDED(N=N, OPT_ARRAY_IN=OPT_ARRAY_IN, KNOWN_OPT_ARRAY_OUT=KNOWN_OPT_ARRAY_OUT)
        OPT_ALLOC_ARRAY_OUT_DIM_1 = 0
      END IF
    ELSE
      IF (OPT_ALLOC_ARRAY_OUT_PRESENT) THEN
        ALLOC_ARRAY_OUT_LOCAL = TEST_EXTENDED(N=N, OPT_ARRAY_IN=OPT_ARRAY_IN, OPT_ALLOC_ARRAY_OUT=OPT_ALLOC_ARRAY_OUT_LOCAL)
        OPT_ALLOC_ARRAY_OUT_DIM_1 = SIZE(OPT_ALLOC_ARRAY_OUT_LOCAL,1)
        OPT_ALLOC_ARRAY_OUT = LOC(OPT_ALLOC_ARRAY_OUT_LOCAL(1))
      ELSE
        ALLOC_ARRAY_OUT_LOCAL = TEST_EXTENDED(N=N, OPT_ARRAY_IN=OPT_ARRAY_IN)
        OPT_ALLOC_ARRAY_OUT_DIM_1 = 0
      END IF
    END IF
  ELSE
    IF (KNOWN_OPT_ARRAY_OUT_PRESENT) THEN
      IF (OPT_ALLOC_ARRAY_OUT_PRESENT) THEN
        ALLOC_ARRAY_OUT_LOCAL = TEST_EXTENDED(N=N, KNOWN_OPT_ARRAY_OUT=KNOWN_OPT_ARRAY_OUT, OPT_ALLOC_ARRAY_OUT=OPT_ALLOC_ARRAY_OUT&
&_LOCAL)
        OPT_ALLOC_ARRAY_OUT_DIM_1 = SIZE(OPT_ALLOC_ARRAY_OUT_LOCAL,1)
        OPT_ALLOC_ARRAY_OUT = LOC(OPT_ALLOC_ARRAY_OUT_LOCAL(1))
      ELSE
        ALLOC_ARRAY_OUT_LOCAL = TEST_EXTENDED(N=N, KNOWN_OPT_ARRAY_OUT=KNOWN_OPT_ARRAY_OUT)
        OPT_ALLOC_ARRAY_OUT_DIM_1 = 0
      END IF
    ELSE
      IF (OPT_ALLOC_ARRAY_OUT_PRESENT) THEN
        ALLOC_ARRAY_OUT_LOCAL = TEST_EXTENDED(N=N, OPT_ALLOC_ARRAY_OUT=OPT_ALLOC_ARRAY_OUT_LOCAL)
        OPT_ALLOC_ARRAY_OUT_DIM_1 = SIZE(OPT_ALLOC_ARRAY_OUT_LOCAL,1)
        OPT_ALLOC_ARRAY_OUT = LOC(OPT_ALLOC_ARRAY_OUT_LOCAL(1))
      ELSE
        ALLOC_ARRAY_OUT_LOCAL = TEST_EXTENDED(N=N)
        OPT_ALLOC_ARRAY_OUT_DIM_1 = 0
      END IF
    END IF
  END IF
  
  ALLOC_ARRAY_OUT_DIM_1 = SIZE(ALLOC_ARRAY_OUT_LOCAL,1)
  ALLOC_ARRAY_OUT = LOC(ALLOC_ARRAY_OUT_LOCAL(1))
END SUBROUTINE C_TEST_EXTENDED

