Clicky

Fortran Wiki
opover

!  @(#) Example of overloading operators in Fortran
!
!  The following MODULE  allows for using the syntax
!     L1 == L2
!  where L1 and L2 are LOGICAL 
!  as an alternative to 
!     L1 .EQV. L2
!  (or the function call
!     BOOLEAN_EQUAL (L1, L2)) 
!  or
!     L1 .BOOLEAN_EQUAL. L2
!  for that matter); and likewise allows
!     L1 /= L2
!  as equivalent to
!     L1 .neqv. L2
! 
! This is a simplistic example. Two significant real-world examples of
! operator overloading to look for use operator overloading to provide
! modules that allow many existing Fortran routines to be used with almost
! no source file changes to produce versions using arbitrary precision
! arithmetic, or to provide cumulative error bounds on floating-point
! calculations.
!
! THOSE features would make interesting additions to the Fortran standard.
!
! The other purpose of this example is to point out that 
!    L1 == L2   !! should be L1 .eqv. L2
! and 
!    L1 /= L2   !! should be L1 .neqv. L2
! should NOT work by default; but often do (probably because the compiler
! silently converts LOGICAL to INTEGER when a LOGICAL appears where a
! numeric value is required?). If you can comment out the USE statement
! below and still run this example, your compiler supports this 
! non-standard (but intuitive-looking) syntax. Using it makes your code
! much less portable. 
!
!-----------------------------------------------------
MODULE logical_ops
!-----------------------------------------------------
   INTERFACE OPERATOR ( == )
      MODULE PROCEDURE boolean_equal
   END INTERFACE OPERATOR ( == )
!-----------------------------------------------------
   INTERFACE OPERATOR ( /= )
      MODULE PROCEDURE boolean_notequal
   END INTERFACE OPERATOR ( /= )
!-----------------------------------------------------
CONTAINS
!-----------------------------------------------------
LOGICAL FUNCTION boolean_equal(logical_val1,logical_val2)
   IMPLICIT NONE
   LOGICAL, INTENT (IN) :: logical_val1 
   LOGICAL, INTENT (IN) :: logical_val2 

   IF (logical_val1 .EQV. logical_val2 )THEN
     boolean_equal=.TRUE.
   ELSE
     boolean_equal=.FALSE.
   ENDIF

END FUNCTION boolean_equal
!-----------------------------------------------------
LOGICAL FUNCTION boolean_notequal(logical_val1,logical_val2)
   IMPLICIT NONE
   LOGICAL, INTENT (IN) :: logical_val1 
   LOGICAL, INTENT (IN) :: logical_val2 

   IF (logical_val1 .EQV. logical_val2 )THEN
     boolean_notequal=.FALSE.
   ELSE
     boolean_notequal=.TRUE.
   ENDIF

END FUNCTION boolean_notequal
!-----------------------------------------------------
END MODULE logical_ops
!-----------------------------------------------------

PROGRAM testit

   USE logical_ops

   IF (.TRUE. .EQV. .TRUE. )THEN      ! standard
      WRITE(*,*)'hello world .eqv.'
   ENDIF

   IF (.TRUE. .NEQV. .FALSE. )THEN    ! standard
      WRITE(*,*)'hello world .neqv.'
   ENDIF

   IF (.TRUE. == .TRUE. )THEN         ! using overloaded operator 
      WRITE(*,*)'hello world =='
   ENDIF

   IF (.TRUE. /= .FALSE. )THEN        ! using overloaded operator 
      WRITE(*,*)'hello world /='
   ENDIF

END PROGRAM testit

category: code