!==========================================================================
! Operazioni primitive sulle code.
! La coda e' accessibile mediante due puntatori: al primo ed ultimo
! elemento rispettivamente.
! Per semplicita' si assume una coda di interi.
!==========================================================================
MODULE Primitive_Coda
  USE Primitive_Lista, ONLY: Cella, Stampa, Primo, Test_coda_vuota => Null
!   Associa il Modulo Primitive_Lista, utilizzando solo alcune definizioni.
!   Il simbolo "=>" consente di cambiare nome ad una definizione:
!   la funzione "Null" qui si chiamera' "Test_coda_vuota".
  IMPLICIT NONE

CONTAINS
!-----------------------------------------------------------------------
  SUBROUTINE In_coda(p,u,e)
!   Inserimento dell'elemento e in coda.
!-----------------------------------------------------------------------
    TYPE(Cella),POINTER:: p,u    ! Puntatori al primo ed ultimo elemento
    INTEGER,INTENT(IN) :: e      ! Valore da inserire
    IF (Test_coda_vuota(p)) THEN !! Coda vuota
      ALLOCATE(p)                !  Alloca il primo elemento
      u => p                     !  ed associalo anche ad u
    ELSE                         !! Coda non vuota
      ALLOCATE(u%next)           !  Alloca un nuovo elemento in coda
      u => u%next                !  ed associalo anche ad u
    END IF                       !! Nuovo elem. allocato, ma non definito
    u%val = e                    !  Assegna al nuovo elem. il suo valore
    NULLIFY(u%next)              !  Termina la coda
    RETURN
  END SUBROUTINE In_coda

!-----------------------------------------------------------------------
  SUBROUTINE Out_coda(p,u)
! Elimina un elemento dalla coda.
!-----------------------------------------------------------------------
    TYPE(Cella),POINTER:: p,u    ! Puntatori al primo ed ultimo elemento
    TYPE(Cella),POINTER:: aux    ! Puntatore ausiliario
    IF (Test_coda_vuota(p)) THEN !! Coda vuota
      WRITE(*,*) "Coda vuota: operazione non applicabile"
    ELSE                         !! Coda non vuota
      aux => p                   !  Non perdere di vista il primo elem.
      p => p%next                !  Avanza il puntatore iniziale
      IF (.NOT.ASSOCIATED(p)) THEN!! La coda ha un solo elemento
        NULLIFY(u)               !  Ora non piu'!
      END IF
      DEALLOCATE(aux)            !  Disalloca l'ex primo elemento
    END IF
    RETURN
  END SUBROUTINE Out_coda
END MODULE Primitive_Coda
