Project

General

Profile

self_object.F90 Source File

Source Code

!>
!! Provides the base object defining basic operations used in containers
!!
module self_object

    implicit none

    type, abstract, public :: object
    contains
        procedure(is_equal_function), deferred :: is_equal
        procedure(to_string_function), deferred :: to_string
        generic :: operator(==) => is_equal
    end type object

    abstract interface
        recursive logical function is_equal_function(this, that)
            import object
            class(object), intent(in) :: this
            class(*), intent(in) :: that
        end function is_equal_function

        recursive function to_string_function(this)
            import object
            class(object), intent(in) :: this
            character(:), allocatable :: to_string_function
        end function to_string_function
    end interface

contains

    recursive function object_equal(this, that) result(equal)
        class(*), intent(in) :: this
        class(*), intent(in) :: that
        logical :: equal

#ifdef __GFORTRAN__
        character(1), allocatable :: mold(:)
#endif

        equal = .false.

        select type(this)

            class is (object)
                equal = this == that

            type is (character(*))
                select type(that)
                    type is (character(*))
                        equal = this == that
                end select

            type is (logical)
                select type(that)
                    type is (logical)
                        equal = this .eqv. that
                end select

            type is (integer)
                select type(that)
                    type is (integer)
                        equal = this == that
                end select

            type is (real)
                select type(that)
                    type is (real)
                        equal = this == that
                end select

            type is (double precision)
                select type(that)
                    type is (double precision)
                        equal = this == that
                end select

            class default
#ifdef __GFORTRAN__
                equal = all(transfer(this, mold) == transfer(that, mold))
#else
                write(0, '(*(g0))') 'Sorry: comparison of arbitrary types not &
                    &supported due to compiler deficiencies'
#endif

        end select

    end function object_equal

    recursive function object_pointer_string(this) result(string)
        class(*), pointer, intent(in) :: this
        character(:), allocatable :: string
        if(associated(this)) then
            string = object_string(this)
        else
            string = '<NULL>'
        end if
    end function object_pointer_string

    recursive function object_string(this) result(string)
        class(*), intent(in) :: this
        character(:), allocatable :: string

        select type(this)
            class is (object)
                string = this%to_string()
            type is (integer)
                string = repeat(' ', 11)
                write(string, '(I0)') this
                string = trim(string)
            type is (real)
                string = repeat(' ', 100)
                write(string, '(G0)') this
                string = trim(string)
            type is (character(*))
                string = "'"//trim(this)//"'"
            type is (logical)
                string = repeat(' ',1)
                write(string, '(L1)') this
            class default
                string = '<UNKNOWN TYPE>'
        end select
    end function object_string

end module self_object

© 2016
self was developed by
Documentation generated by FORD