comp.lang.ada
 help / color / mirror / Atom feed
From: Niklas Holsti <niklas.holsti@tidorum.invalid>
Subject: Re: Deleting elements from a Vector
Date: Mon, 20 Apr 2015 00:12:28 +0300
Date: 2015-04-20T00:12:28+03:00	[thread overview]
Message-ID: <cpik1tF25ipU1@mid.individual.net> (raw)
In-Reply-To: <lywq173ltl.fsf@pushface.org>

On 15-04-19 23:27 , Simon Wright wrote:
> I need to remove some of the elements from a vector, depending on the
> element. I have the code below, which works for GNAT, but which seems
> distinctly dodgy; in particular, it fails if the last Element is
> negative and therefore gets deleted.

Out of curiosity, how does it fail? Exception?

> The Booch Components have
>
>     procedure Delete_Item_At (It : in out Iterator) is abstract;
>
> (an Iterator is very similar to a Cursor) which is defined to leave the
> Iterator designating the 'next' Element (i.e., the one, is any, you
> would have reached by applying Next to the original Iterator). But I
> don't see any such promise for the Containers.

I could not find such promises. There is a promise that the cursor used 
to delete the element becomes No_Element, as the comment in your code 
(quoted below) says.

It seems that what you are doing is at least unspecified and may be 
erroneous:

- RM A.18.2(251/3) says that any other cursor that designates (or 
designated) the deleted element becomes invalid through the deletion.

- RM A.18.2(2522/2) says that any use of an invalid cursor in "=" or 
Has_Element has unspecified result, and using the cursor with any other 
subprogram from Containers.Vectors is erroneous execution.

So, after the V.Delete (D) in the code below, the cursor C is invalid, 
and on the next loop iteration the condition C /= Vectors.No_Element has 
unspecified result, and the possibly executed Vectors.Element (C) is 
erroneous execution. So don't do that :-)

> Is there a proper idiom for doing this job? Should I maybe go over the
> Vector in reverse order and use the version of Delete that uses the
> index?

Indeed that seems safer. Note also RM A.18.2(240/2..243/2) for the 
definition and properties of an "ambiguous" cursor. This also suggests 
traversing the vector in reverse index order.

> with Ada.Containers.Vectors;
> with Ada.Text_IO; use Ada.Text_IO;
> procedure Deleting_From_Queue is
>     package Vectors is new Ada.Containers.Vectors (Positive, Integer);
>     V : Vectors.Vector;
> begin
>     V.Append (1);
>     V.Append (-1);
>     V.Append (2);
>     V.Append (-2);
>     V.Append (3);
>     declare
>        C : Vectors.Cursor := V.First;
>        D : Vectors.Cursor;
>        use type Vectors.Cursor;
>     begin
>        while C /= Vectors.No_Element loop
>           if Vectors.Element (C) < 0 then
>              Put_Line ("deleting element " & Vectors.Element (C)'Img);
>              D := C;
>              V.Delete (D);  -- D -> No_Element
>           else
>              Put_Line ("skipping element " & Vectors.Element (C)'Img);
>              Vectors.Next (C);
>           end if;
>        end loop;
>     end;
>     Put_Line ("length now " & V.Length'Img);
> end Deleting_From_Queue;
>


-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

  parent reply	other threads:[~2015-04-19 21:12 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-19 20:27 Deleting elements from a Vector Simon Wright
2015-04-19 21:07 ` Jeffrey Carter
2015-04-19 21:12 ` Niklas Holsti [this message]
2015-04-20  7:56   ` Simon Wright
2015-04-20  8:39     ` Georg Bauhaus
2015-04-20 11:13       ` Simon Wright
2015-04-20  7:36 ` Dmitry A. Kazakov
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox