* how to delete from Ada.Containers.Doubly_Linked_Lists
@ 2014-08-18 18:51 Björn Lundin
2014-08-18 19:57 ` Jeffrey Carter
0 siblings, 1 reply; 3+ messages in thread
From: Björn Lundin @ 2014-08-18 18:51 UTC (permalink / raw)
Hi,
I try to get aquinted with Ada.Containers.Doubly_Linked_Lists,
which I feel may replace a homebrew list class we
use at work.
Especailly the 'for of' notation
seems nice to have.
But How do I delete an item in the list
while looping it?
I've got a sample below,
but I fell it is clumpsy.
How should a nice solution look like ?
/Björn
with Text_Io;
with Ada.Containers.Doubly_Linked_Lists;
procedure Test_List is
type Example_Type is record
A :Integer := 0;
B: Integer := 0;
end record;
procedure To_String(E : Example_Type) is
begin
Text_io.Put_Line(E.A'Img & E.B'Img);
end To_String;
begin
Text_io.Put_Line("start Ada.Containers.Doubly_Linked_Lists; ");
declare
Data : Example_Type;
package Example_Pkg is new
Ada.Containers.Doubly_Linked_Lists(Example_Type);
List : Example_Pkg.List;
begin
Text_io.Put_Line("insert 5 elements at tail, ");
for i in 1..5 loop
Data := (A => i, B => 2 * i);
List.Append(Data);
end loop;
for i of List loop
To_String(i);
end loop;
Text_io.Put_Line("Update in place");
for i of List loop
I.A := 5*I.A;
I.B := 50*I.B;
end loop;
for i of List loop
To_String(i);
end loop;
Text_io.Put_Line("delete if I.a = 15");
for c in List.Iterate loop
declare
i : Example_Type := Example_Pkg.Element(C);
begin
if I.A = 15 then
List.Delete(C); <-- program_error raised
end if;
end ;
end loop;
--works but clumplsy
declare
C_Save : Example_Pkg.Cursor;
begin
for c in List.Iterate loop
declare
i : Example_Type := Example_Pkg.Element(C);
begin
if I.A = 15 then
C_Save := C;
exit;
end if;
end ;
end loop;
List.Delete(C_Save);
end;
for i of List loop
To_String(i);
end loop;
Text_io.Put_Line("done");
end;
end Test_List;
sample run:
insert 5 elements at tail,
1 2
2 4
3 6
4 8
5 10
Update in place
5 100
10 200
15 300
20 400
25 500
delete if I.a = 15
Execution terminated by unhandled exception
Exception name: PROGRAM_ERROR
Message: attempt to tamper with cursors (list is busy)
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: how to delete from Ada.Containers.Doubly_Linked_Lists
2014-08-18 18:51 how to delete from Ada.Containers.Doubly_Linked_Lists Björn Lundin
@ 2014-08-18 19:57 ` Jeffrey Carter
2014-08-19 8:56 ` Björn Lundin
0 siblings, 1 reply; 3+ messages in thread
From: Jeffrey Carter @ 2014-08-18 19:57 UTC (permalink / raw)
On 08/18/2014 11:51 AM, Björn Lundin wrote:
>
>
> I've got a sample below,
> but I fell it is clumpsy.
> How should a nice solution look like ?
You probably ought to read about "tampering with cursors" in the ARM (A.18.3).
In your case, iterating over the list needs the list to remain unchanged until
iteration finishes. Deleting during iteration would violate this.
This restriction is intended for safety, and sometimes seems onerous. I've had
to iterate over one data structure, storing cursors in another data structure,
then iterate over the 2nd data structure to delete using the stored cursors.
You can delete during iteration if you don't invoke an Iterate subprogram:
declare
C : Example_Pkg.Cursor := List.First;
Next : Example_Pkg.Cursor;
use type Example_Pkg.Cursor;
begin
loop
exit when C = Example_Pkg.No_Element;
declare
I : constant Example_Type := Example_Pkg.Element (C);
begin
if I.A /= 15 then
Example_Pkg.Next (Position => C);
else
Next := Example_Pkg.Next (C);
List.Delete (Position => C);
C := Next;
end if;
end ;
end loop;
end;
--
Jeff Carter
"You a big nose have it."
Never Give a Sucker an Even Break
107
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: how to delete from Ada.Containers.Doubly_Linked_Lists
2014-08-18 19:57 ` Jeffrey Carter
@ 2014-08-19 8:56 ` Björn Lundin
0 siblings, 0 replies; 3+ messages in thread
From: Björn Lundin @ 2014-08-19 8:56 UTC (permalink / raw)
On 2014-08-18 21:57, Jeffrey Carter wrote:
> On 08/18/2014 11:51 AM, Björn Lundin wrote:
>> How should a nice solution look like ?
>
> You probably ought to read about "tampering with cursors" in the ARM (A.18.3).
> In your case, iterating over the list needs the list to remain unchanged until
> iteration finishes. Deleting during iteration would violate this.
Hmm, yes I see that now.
> This restriction is intended for safety, and sometimes seems onerous.
That was my suspicion
> I've had
> to iterate over one data structure, storing cursors in another data structure,
> then iterate over the 2nd data structure to delete using the stored cursors.
Yes, basically what my last sample did - saving the cursor 'c' into
'C_Save' and delete outside the loop. That is what I thought was
inelegant/clumpsy
> You can delete during iteration if you don't invoke an Iterate subprogram:
Still a bit inelegant, but thanks for the example.
It is way better that mine.
/Björn
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-08-19 8:56 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-18 18:51 how to delete from Ada.Containers.Doubly_Linked_Lists Björn Lundin
2014-08-18 19:57 ` Jeffrey Carter
2014-08-19 8:56 ` Björn Lundin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox