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.
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
class(*), | public, | allocatable | :: | tmp |
subroutine set(this, content)
!! Author: Chris MacMackin
!! Date: December 2015
!!
!! 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 [[container: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.
!!
!! @Warning During the initial phase of writing unit tests for the
!! containers, I found that when content is class(container) then
!! ~5GB of memory would end up being allocated when allocating tmp.
!! After various experiments, I found that changing where tmp is
!! allocated, so that this is only done if it is not being allocated
!! to another container type, stopped this from happening. However,
!! I'm still not clear on exactly what the cause of the bug is
!! (similar things occasionally happened when DEallocating a
!! container) and suspect its origin is a compiler bug. As such, I'm
!! keeping this note here for information in case the issue ever
!! arises again.
!!
class(container), intent(out) :: this
class(*), intent(in) :: content
!! The value to be placed in the container
class(*), allocatable :: tmp
if (.not. allocated(this%storage)) allocate(this%storage(1))
if (same_type_as(this, content)) then
select type(content)
class is(container)
if (content%filled) then
this%filled = .true.
this%storage = content%storage
else
this%filled = .false.
deallocate(this%storage)
endif
return
end select
end if
allocate(tmp, source=content)
if (this%typeguard(tmp)) then
this%filled = .true.
this%storage = transfer(content, this%storage)
else
write(stderr,*) "ERROR: Can not assign given variable to this container"
#ifdef __GFORTRAN__
call backtrace
#endif
stop
end if
end subroutine set