An abstract derived type which contains data. This type can be
used for a sort of unlimited polymorphism. It is extended to
create different classes capable of holding particular
data-types. Extensions must implement the procedure
typeguard in order to provide the ability to
transfer data out of the container and into a variable. Assuming
that you are creating a concrete class called
example_container
, this should be implemented as follows:
module example_container_mod use abstract_container_mod implicit none private type example integer, public :: i end type example type, extends(container) :: example_container contains private procedure :: typeguard => example_guard end type example_container contains logical function example_guard(this, lhs) result(ret) class(example_container), intent(in) :: this class(*), intent(inout) :: lhs select type(lhs) type is(example) lhs = transfer(this%contents(), lhs) ret = .true. class default ret = .false. end select end function example_guard end module example_container_mod
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
integer(kind=i1), | private, | dimension(:), allocatable | :: | storage | Variable in which to place data contents |
||
logical, | private | :: | filled | = | .false. |
|
Performs the actual transfer of the container's contents to another variable.
Retrieves the contents of the container, in the form of an integer array.
Returns whether contents have been assigned to the container
Sets the contents of the container.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(container), | intent(out) | :: | this | |||
class(*), | intent(in) | :: | content | The value to be placed in the container |
Sets the contents of the storage array to value passed. The type
of the variable provided must be the same as the container
variable is designed to accept (as determined by the
concrete type implementation of the typeguard
method in the extension) or be of the same type of container.
Otherwise an error message will be printed and the program will
exit. If gfortran
was used to compile then a backtrace will
also be printed.
Assigns container contents to another variable.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(*), | intent(inout) | :: | lhs | The variable which the container contents will be assigned to. |
||
class(container), | intent(in) | :: | rhs | The container variable. |
Transfers the contents of the container to another variable.
If the other variable is another container of the same type
then the contents will be transferred. If the other variable is
the same type as the contents of the container (as determined
by the typeguard routine provided for that
concrete type extension) then it will be given the value held by
the container. Otherwise, an error message will be printed and
the program stopped. If compiled with gfortran
then a backtrace
will also be printed. In the event that the container was never
set to a value, then this also constitutes an error.
Check whether two containers have the same contents.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(container), | intent(in) | :: | lhs | |||
class(container), | intent(in) | :: | rhs |
Checks whether two containers are of the same type and are storing the same contents.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(*), | intent(inout) | :: | lhs | The variable which the container contents will be assigned to. |
||
class(container), | intent(in) | :: | rhs | The container variable. |
Transfers the contents of the container to another variable.
If the other variable is another container of the same type
then the contents will be transferred. If the other variable is
the same type as the contents of the container (as determined
by the typeguard routine provided for that
concrete type extension) then it will be given the value held by
the container. Otherwise, an error message will be printed and
the program stopped. If compiled with gfortran
then a backtrace
will also be printed. In the event that the container was never
set to a value, then this also constitutes an error.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(container), | intent(in) | :: | lhs | |||
class(container), | intent(in) | :: | rhs |
Checks whether two containers are of the same type and are storing the same contents.
type, public, abstract :: container
!! Author: Chris MacMackin
!! Date: December 2015
!! Display: Public
!! Private
!!
!! An abstract derived type which contains data. This type can be
!! used for a sort of unlimited polymorphism. It is extended to
!! create different classes capable of holding particular
!! data-types. Extensions must implement the procedure
!! [[container:typeguard]] in order to provide the ability to
!! transfer data out of the container and into a variable. Assuming
!! that you are creating a concrete class called
!! `example_container`, this should be implemented as follows:
!!
!!```fortran
!! module example_container_mod
!!
!! use abstract_container_mod
!! implicit none
!! private
!!
!! type example
!! integer, public :: i
!! end type example
!!
!! type, extends(container) :: example_container
!! contains
!! private
!! procedure :: typeguard => example_guard
!! end type example_container
!!
!! contains
!!
!! logical function example_guard(this, lhs) result(ret)
!! class(example_container), intent(in) :: this
!! class(*), intent(inout) :: lhs
!! select type(lhs)
!! type is(example)
!! lhs = transfer(this%contents(), lhs)
!! ret = .true.
!! class default
!! ret = .false.
!! end select
!! end function example_guard
!!
!! end module example_container_mod
!!```
private
integer(i1), dimension(:), allocatable :: storage
!! Variable in which to place data contents
logical :: filled = .false.
!! `.true.` if container is set, `.false.` otherwise
contains
private
procedure(guard), deferred :: typeguard
!! Performs the actual transfer of the container's contents to
!! another variable.
procedure, public :: contents
!! Retrieves the contents of the container, in the form of an
!! integer array.
procedure, public :: is_filled
!! Returns whether contents have been assigned to the container
procedure, public :: set
!! Sets the contents of the container.
procedure, pass(rhs) :: assign_container
!! Assigns container contents to another variable.
procedure :: is_equal
!! Check whether two containers have the same contents.
generic, public :: assignment(=) => assign_container
generic, public :: operator(==) => is_equal
end type container