!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 Extending a primitive routine
!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.
****************************************************************