!generic procedures
!a subroutine to compare  any data type int,real,string,composite data
!use of interface

module generic_comp
type:: vect
    real::x,y
end type

interface comp_data_type_indep
    module procedure comp_i
    module procedure comp_r
    module procedure comp_s
    module procedure comp_v
end interface

contains

subroutine comp_i(i,j,flag)
integer,intent(in)::i,j
logical,intent(out)::flag
     flag = i > j 
end subroutine comp_i

subroutine comp_r(x,y,flag)
real,intent(in)::x,y
logical,intent(out)::flag
    flag = x > y
end subroutine comp_r

subroutine comp_s(s1,s2,flag)
character(len=*),intent(in)::s1,s2
logical,intent(out)::flag
integer :: len1,len2,i
integer :: tmp1,tmp2
    len1 = len_trim(s1)    
    len2 = len_trim(s2)
    
    i=1
    do 
        tmp1 = ichar(s1(i:i))
        tmp2 = ichar(s2(i:i))
        if( tmp1 /= tmp2 ) then
            if(tmp1 < tmp2) then
              flag = .false.
            else 
              flag = .true.
            end if
            exit
        end if
            if (i==len1) then
           flag = .false.
           exit
        end if
        if(i == len2) then
           flag = .true.
           exit
        end if
        i = i+1
    end do

end subroutine comp_s

subroutine comp_v(v1,v2,flag)
type(vect),intent(in)::v1,v2
logical,intent(out)::flag
real :: d1,d2
    d1= ( (v1%x)**2 ) + ( (v1%y)**2 )
    d2= ( (v2%x)**2 ) + ( (v2%y)**2 )
        flag = d1 > d2
end subroutine comp_v
end module


program generic_comp_test
use generic_comp
implicit none

integer:: i,j
real:: x,y
logical :: flag_i,flag_r,flag_s,flag_v
character(len=10)::str1,str2
type(vect)::v1,v2

write(*,'("Give integers i,j")')
read *, i,j
write(*,'("Give reals x,y")')
read *, x,y
write(*,'("Give strings str1,str2")')
read *, str1,str2
write(*,'("Give vectors v1,v2")')
call read_vect(v1)
call read_vect(v2)
 
call comp_data_type_indep(i,j,flag_i)
call comp_data_type_indep(x,y,flag_r)
call comp_data_type_indep(str1,str2,flag_s)
call comp_data_type_indep(v1,v2,flag_v)

write (*,*) "Integers comparison ",flag_i
write (*,*) "Real values comparison ",flag_r 
write (*,*)  "Strings Comparison ",flag_s 
write (*,*) "Vectors comparison ",flag_v


contains

subroutine read_vect(v)
type(vect),intent(out)::v
    read *, v%x,v%y
end subroutine

subroutine print_vect(v)
type(vect),intent(in)::v
    write(*,40) v%x,v%y
    40 format("Vector addition result=",f5.2,"i+",f5.2,"j")
end subroutine
end program

