Version 1.2 of acs/ac-00120.txt

Unformatted version of acs/ac-00120.txt version 1.2
Other versions for file acs/ac-00120.txt

!standard A.18(0/2)          05-10-24 AC95-00120/01
!class Amendment 05-10-24
!status received no action 05-10-24
!status received 05-10-02
!subject Bounded containers
!appendix

From: Martin Dowie
Date: Sunday, Octoher 2, 2005  1:12 PM

I didn't realize that changes were still being proposed/allowed at this
stage until Randy sent in the "extends" email. :-)

I have a suggestion that I hope will be fairly simple and hopefully
useful...

I think that we could extend the Ada.Containers.* hierarchy to include
"Bounded_" variants of each container type by defining that each bounded
package has exactly the same specification as the unbounded version,
except that the container type has a "(Max_Length : Count_Type)" constraint.

Insert/Append routines would raise a Constraint_Error if "Length
(Container) = Max_Length" (or, a "Length_Error : exception;" could be
added to Ada.Containers).

The only 'tricky' bit is what to with:

1) procedure Set_Length
Either check and raise exception or limit to Max_Length even if "Length
 > Container.Max_Length"?

2) each function "&" =>
   a) if Left or Right is the only container then simply check for space;
   b) if Left and Right are elements then return a Max_Length => 2
container;
   c) if Left and Right are containers then append as much of Right to a
new container with Max_Length of Left.Max_Length.

Alternatively for "&" they could return a new container of
Left.Max_Length + Right.Max_Length but that seems against the nature of
bounded things and not so much in keeping with bounded strings. I'm not
too fussed about what the 'actual' rules are/would be, I'm just pointing
out that these are the only things that would need any discussion.

Anyway, I hope I've shown that it would be /simple/ to double the size
of the Ada.Container.* hierarchy with very little effort (and by effort,
I mean 'text'! :-), in much the same way as "Wide_" packages are added
to the RM.

I have a sample "Ada.Containers.Bounded_Vectors" if anyone would like to
see such a beast.

p.s. My $0.02 would choose "check&raise" for what to do with
Set_Length/"&" subprograms, by the way ;-)

****************************************************************

From: Bob Duff
Date: Sunday, October 2, 2005  8:33 PM

> I didn't realize that changes were still being proposed/allowed at this
> stage until Randy sent in the "extends" email. :-)

I think Randy's suggestion was for Ada 201X, not Ada 2005.  ;-)

> I have a suggestion that I hope will be fairly simple and hopefully
> useful...
>
> I think that we could extend the Ada.Containers.* hierarchy to include
> "Bounded_" variants of each container type by defining that each bounded
> package has exactly the same specification as the unbounded version,
> except that the container type has a "(Max_Length : Count_Type)" constraint.

Hmm... If I say:

    X: Bounded_Whatever(Max_Length => 80);
    ...
    X := Y & Z;

where Length(Y) + Length(Z) <= 80, I would like it to work.
I don't know how to do that in Ada.

****************************************************************

From: Jeffrey Carter
Date: Sunday, October 2, 2005  10:04 PM

> I think that we could extend the Ada.Containers.* hierarchy to include
> "Bounded_" variants of each container type by defining that each bounded
> package has exactly the same specification as the unbounded version,
> except that the container type has a "(Max_Length : Count_Type)"
> constraint.

This doesn't work very well, because user-defined assignment doesn't handle
this kind of thing. That's why bounded strings have the limit as a generic
formal constant, not a discriminant on Bounded_String.

Somehow, I doubt anything is being considered for Ada 0X anymore. Randy said
his suggestion was for Ada 1X.

****************************************************************

From: Matthew Heaney
Date: Monday, October 3, 2005  9:05 AM

> I think that we could extend the Ada.Containers.* hierarchy to include
> "Bounded_" variants of each container type by defining that each bounded
> package has exactly the same specification as the unbounded version,
> except that the container type has a "(Max_Length : Count_Type)"
> constraint.

The container type would have to be limited, because of assignment behavior.

What you refer to as Max_Length above is really just capacity.

> 1) procedure Set_Length
> Either check and raise exception or limit to Max_Length even
 > if "Length > Container.Max_Length"?

Just raise CE.

> 2) each function "&" =>
>   a) if Left or Right is the only container then simply check for space;
>   b) if Left and Right are elements then return a Max_Length => 2
> container;
>   c) if Left and Right are containers then append as much of Right to a
> new container with Max_Length of Left.Max_Length.

No.  Operator "&" is gone, because the type has to be limited.

****************************************************************

From: Martin Dowie
Date: Monday, October 3, 2005  10:17 AM

I could live with either "Max_Length" or "Capacity".

Why would "&" have to go? They are present in "Bounded_String"-s...

Can you give me an example of the problems with assignment behaviour?
Because just now I'm sitting in front of something that seems to work
fine with everything I try and throw at it.

****************************************************************

From: Matthew Heaney
Date: Monday, October 3, 2005  10:30 AM

> Why would "&" have to go? They are present in "Bounded_String"-s...

Because there's nothing you can to do with the result, if the type is
limited.

Actually, I should take that back.  Operator "&" could become a
constructor-type function (aka "initializer"), since you would only be
able to use it during the declaration of the bounded contained object
(because the type is limited).

> Can you give me an example of the problems with assignment behaviour?
> Because just now I'm sitting in front of something that seems to work
> fine with everything I try and throw at it.

Assuming the type were non-limited:

declare
    C1 : CT (42);
    C2 : CT (1963);
begin
    C2 := C1;  -- raises CE
end;

(But maybe there were some changes in semantics for Ada 2005, such that
the assignment no longer raises CE.)

****************************************************************

From: Matthew Heaney
Date: Monday, October 3, 2005  11:29 AM

> Hmm... If I say:
>
>     X: Bounded_Whatever(Max_Length => 80);
>     ...
>     X := Y & Z;
>
> where Length(Y) + Length(Z) <= 80, I would like it to work.
> I don't know how to do that in Ada.

Hmmm... Why not?  If the discriminant of the result of Y & Z is the same
as X, then the assignment will succeed.  And the sum of the lengths can
be calculated in the implementation of "&".

Another issue wrt assignment of bounded forms is the (in)efficiency,
since there will be a bitwise copy of both the active and inactive
("free store") elements.

Martin: the Charles library has bounded list forms (having a clever
implementation of the free store, IMHO).  You can play around with those
if you want to get some more data...

****************************************************************

From: Martin Dowie
Date: Monday, October 3, 2005  11:50 AM

Thanks Matt - I'll take a look - is there an easy 'zipped' version of
the head, or do I need to download each file individually? (I've never
really used CVS)

And while I can't do:
declare
   C1 : CT (42);
   C2 : CT (1963);
begin
   C2 := C1;  -- raises CE
end;

I can do:
declare
   C1 : CT (42);
   C2 : CT (1963);
begin
   C2 := C2 & C1;  -- works fine
end;

****************************************************************

From: Bob Duff
Date: Monday, October 3, 2005  12:26 PM

> Hmmm... Why not?  If the discriminant of the result of Y & Z is the same
> as X, then the assignment will succeed.  And the sum of the lengths can
> be calculated in the implementation of "&".

I was thinking of this:

    type Bounded_Sequence(Max_Length: Natural) is
        record
            Elements: Element_Array(1..Max_Length);
            Length: Natural := 0;
        end record;

    X: Bounded_Sequence(Max_Length => 80);
    Y: Bounded_Sequence(Max_Length => 40);
    ...

Now, if Y.Length = 20, I would like to be able to say "X := Y",
since the length of Y is shorter than the Max_Length of X.
But that doesn't work.

Same issue for "X := Y & Z" -- the "&" operation can calculate the right
length for the result, but it can't calculate the right Max_Length.

As you pointed out in another message, this is why Bounded_Strings is
generic on the max length.  That means all objects of a given type will
have the same max length, thus trivially ensuring that, as you said
above, the max length "of the result of Y & Z is the same as X".

> Another issue wrt assignment of bounded forms is the (in)efficiency,
> since there will be a bitwise copy of both the active and inactive
> ("free store") elements.

Good point.  Of course that doesn't matter if the thing is limited,
and if it's limited, the issues about assignment and "&" go away.
In Ada 2005, limited is one good way to go.

In any case, it's not _trivial_ to add these bounded versions,
nor to decide on their exact semantics.  So I think it's unlikely that
they will be included in Ada 2005.  Go for 2015!

****************************************************************

From: Martin Dowie
Date: Monday, October 3, 2005  11:26 PM

>I think Randy's suggestion was for Ada 201X, not Ada 2005.  ;-)
>
>
Apologies for being a bit early with my Ada1Z proposal then! :-)


>Hmm... If I say:
>
>    X: Bounded_Whatever(Max_Length => 80);
>    ...
>    X := Y & Z;
>
>where Length(Y) + Length(Z) <= 80, I would like it to work.
>I don't know how to do that in Ada.
>
Ok, I'm confused by this one as my implementation seems to do the right
thing for this!...

Anyway, I guess all this can wait for the ISO IWA.

-- bounded_integer_vectors.ads
with Ada.Containers.Bounded_Vectors;

package Bounded_Integer_Vectors is
   new Ada.Containers.Bounded_Vectors (Natural, Integer);

-- test_biv.adb
with Ada.Containers; use Ada.Containers;
with Ada.Exceptions; use Ada.Exceptions;
with Ada.Text_IO;    use Ada.Text_IO;

with Bounded_Integer_Vectors; use Bounded_Integer_Vectors;

procedure Test_BIV is
   subtype Vector_3 is Vector (3);
   V1, V2, V3 : Vector_3;
begin
   Put_Line ("Length =>" & Count_Type'Image (V1.Length));
   V1.Append (1);
   Put_Line ("Length =>" & Count_Type'Image (V1.Length));
   V1.Append (3);
   Put_Line ("Length =>" & Count_Type'Image (V1.Length));
   V1.Append (6);
   Put_Line ("Length =>" & Count_Type'Image (V1.Length));
   begin
      V1.Append (10);
   exception
      when Error : others =>
         Put_Line ("!!! " & Exception_Message (Error));
   end;
   Put_Line ("Length =>" & Count_Type'Image (V1.Length));
   Put_Line ("Length =>" & Count_Type'Image (V3.Length));
   V3 := V1 & V2;
   Put_Line ("Length =>" & Count_Type'Image (V3.Length));
end Test_BIV;

-- result.txt
C:\Ada\Bounded_Containers\gps\obj\test_biv.exe
Length => 0
Length => 1
Length => 2
Length => 3
!!! Insert error, already full.
Length => 3
Length => 0
Length => 3

****************************************************************

From: Bob Duff
Date: Tuesday, October 4, 2005  12:01 PM

> Ok, I'm confused by this one as my implementation seems to do the right
> thing for this!...

>    subtype Vector_3 is Vector (3);
>    V1, V2, V3 : Vector_3;

Try it like this:

    V1, V2: Vector_3;
    V3: Vector(6);

6 is plenty big enough to store 3 characters, but the assignment
will raise Constraint_Error.

****************************************************************

From: Martin Dowie
Date: Tuesday, October 4, 2005  12:32 PM

Well, that depends on what I make "&" mean! :-)

   declare
      C1, C2 : Bounded_Integer_Vectors.Vector (3);
      C3     : Bounded_Integer_Vectors.Vector (6);
   begin
      C1.Append (1);
      C1.Append (3);
      C1.Append (7);
      C2.Append (11);
      C2.Append (13);
      C2.Append (17);
      C3 := C1 & C2;
      Put_Line ("+++ No exception raised");
      Put_Line ("Length =>" & Count_Type'Image (C3.Length));
   exception
      when Error : others =>
         Put_Line ("!!! " & Exception_Message (Error));
   end;

-- results.txt
+++ No exception raised
Length => 6

****************************************************************

From: Jeffrey Carter
Date: Tuesday, October 4, 2005  1:00 PM

>   Well, that depends on what I make "&" mean! :-)

Sure, but the point is that there's no way to make

A := B & C;

work for any A, B, & C such that

Length (B) + Length (C) <= A.Max_Length.

Indeed, if you can make it work for your example and for

A : Vector ( 7);
B : Vector (10);
C : Vector (23);

Length (B) = 3
Length (C) = 3

I'll be impressed.

I suspect this discussion should be moved from Ada-Comment.

****************************************************************

Questions? Ask the ACAA Technical Agent