set Subroutine

private subroutine set(this, content)

Arguments

Type IntentOptional AttributesName
class(container), intent(out) :: this
class(*), intent(in) :: content

The value to be placed in the container

Description

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.


Variables

TypeVisibility AttributesNameInitial
class(*), public, allocatable:: tmp

Source Code

  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