with Unchecked_Deallocation;
package body Listas_Secuenciales is
procedure Libera is new Unchecked_Deallocation(Nodo_Lista, TNodo_Lista);
-- El procedimiento Insertar, inserta el elemento indicado por el
-- segundo parámetro en la lista indicada por el primero. Si el
-- elemento a insertar ya se encuentra en la lista, lo sustituirá
-- por el nuevo si el tercer parámetro tiene el valor True o lanzará
-- la excepción Error_Repetido si tiene el valor False. Los elementos
-- en la lista estarán organizados secuencialmente según el orden de llegada,
-- salvo en caso de sustitución que se mantiene la posición original. El
-- elemento recién insertado se convierte en el actual a efectos de acceso. Si,
-- cuando se intenta insertar, la lista está llena, se lanza la excepción
-- predefinida Constraint_Error y la lista queda como estaba.
procedure Insertar(Lis: in out Lista; ELista: in ElementoLista; NoExiste: in Boolean) is
begin
if Lis.Tamaño = 0 then
Lis.Actual:= Lis.Inicio;
Lis.Fin:= Lis.Inicio;
Lis.Tamaño := Lis.Tamaño + 1;
END IF;
IF lis.tamaño /= 0 THEN
if Lis.Tamaño /= Lis.TamañoMaximo then
if NoExiste = True then
Lis.Actual:= Lis.ELista;
else
raise Error_Repetido;
end if;
else
raise Constraint_Error;
end if;
end if;
end Insertar;
-- El procedimiento Inicial, designa como actual al elemento
-- más antiguo de la lista. Si la lista está vacía el actual
-- queda indefinido.
procedure Inicio(Lis: in out Lista) is
begin
if Lis.Tamaño = 0 then
Lis.Actual:= Lis.Inicio;
end if;
end Inicio;
-- El procedimiento Siguiente, prepara la lista para
-- acceder al elemento siguiente al actual, según el
-- orden secuencial de la misma. Si actual ya está
-- en el último elemento, queda indefinido. Si la
-- lista está vacía o el actual está indefinido, actual
-- queda indefinido.
procedure Siguiente(Lis: in out Lista) is
begin
if Lis.Tamaño /= 0 then
if Lis.Actual /= Lis.Fin then
Lis.Actual:= Nodo_Lista.sig;
else
Lis.Actual:= null;
end if;
else
Lis.Actual:= null;
end if;
end Siguiente;
-- la Función Examinar devuelve el elemento actual
-- de la lista. Si el elemento actual está indefinido
-- se lanzará la excepción Constraint_Error.
function Examinar(Lis: in Lista)return Lista is
begin
if Lis.Actual /= null then
return Lis.Actual;
else
raise Constraint_Error;
end if;
end Examinar;
-- La función Fin_Lista, devuelve True si actual está indefinido.
function Fin_Lista(Lis: in Lista)return boolean is
begin
if Lis.Actual = null then
return True;
else
return False;
end if;
end Fin_Lista;
-- El procedimiento Extraer, elimina de la lista el
-- elemento actual. Si actual está indefinido no se
-- producirá ningún efecto apreciable. Tras la
-- extracción, actual debe quedar situado en el
-- elemento siguiente al extraído; si el elemento
-- que se extrae es el último de la lista, actual
-- queda indefinido.
procedure Extraer(Lis: in out Lista) is
Aux: Nodo_Lista;
begin
if Lis.Actual /= null then
if Lis.Actual /= Lis.Fin then
Aux:= Nodo_Lista.sig;
Libera(Lis.Actual);
Lis.Actual:= Aux;
Lis.Tamaño := Lis.Tamaño - 1;
end if;
if Lis.Actual = Lis.Fin then
Libera(Lis.Actual);
Lis.Actual:= Null;
Lis.Tamaño := Lis.Tamaño - 1;
end if;
end if;
end Extraer;
end Listas_Secuenciales;