From: Maciej Sobczak on
On 20 Cze, 19:12, Stefan Bellon <bel...(a)software-erosion.org> wrote:

> Now you can do the following:
>
> function Get_Range
> return Integer_Range_Objects.Range_Type
> is
> begin
> return (42 .. 128 => <>);
> end Get_Range;
>
> And then:
>
> for I in Get_Range'Range loop
> Do_Something (I);
> end loop;
>
> It's not as elegant as I wished (because of the additional 'Range), but
> it is simple and light-weight enough to be usable.

As far as I can tell, it creates the physical array that might not be
necessarily optimized out by the compiler. You need to store it
somewhere.
It would be nicer to return a "range" that is not dependent on memory
constraints. See xrange in Python.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com
From: Stefan Bellon on
On Sun, 22 Jun, Maciej Sobczak wrote:
> On 20 Cze, 19:12, Stefan Bellon <bel...(a)software-erosion.org> wrote:

> > for I in Get_Range'Range loop
> > Do_Something (I);
> > end loop;
> >
> > It's not as elegant as I wished (because of the additional 'Range),
> > but it is simple and light-weight enough to be usable.
>
> As far as I can tell, it creates the physical array that might not be
> necessarily optimized out by the compiler. You need to store it
> somewhere.

You need to store the two words for First and Last (or First and
Length). And indeed, this is what GNAT does. The 'Size of the array
object returned is two words in size.

> It would be nicer to return a "range" that is not dependent on memory
> constraints. See xrange in Python.

I think you cannot get smaller than the two words. The question is
whether this optimisation (for 'Size use 0) can always be guaranteed.

--
Stefan Bellon

From: Maciej Sobczak on
On 22 Cze, 20:47, Stefan Bellon <bel...(a)software-erosion.org> wrote:

> You need to store the two words for First and Last (or First and
> Length). And indeed, this is what GNAT does. The 'Size of the array
> object returned is two words in size.

Now I have noticed the for Empty_Component'Size use 0 part. Sorry for
the confusion, but see below for more. :-)

> The question is
> whether this optimisation (for 'Size use 0) can always be guaranteed.

I have a better question: is it *legal*?

Consider 3.6/13:

"A one-dimensional array has a distinct component for each possible
index value."

What does it mean - "distinct"? Doesn't it exclude overlays?

What about "independent addressability" from 13.3? The text is a bit
dense, but I conclude that the 'Size attribute does not have to be
strictly obeyed by the implementation.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com
From: Stefan Bellon on
On Sun, 22 Jun, Maciej Sobczak wrote:

> What about "independent addressability" from 13.3? The text is a bit
> dense, but I conclude that the 'Size attribute does not have to be
> strictly obeyed by the implementation.

I don't think this applies here as the array components are not aliased
and thus there is no need for independent addressability. Perhaps the
compiler should allocate memory for each component as soon as "aliased"
is specified.

But in any case my "range objects" do not rely on the compiler not
allocating memory. This is just a nice and efficient side-effect of the
compiler implementation. So, even if the compiler implementation does
not have to optimise, the semantics of my "range objects" is guaranteed
and for the GNAT implementation it is even optimal concerning memory.

--
Stefan Bellon

From: Maciej Sobczak on
On 23 Cze, 11:47, Stefan Bellon <bel...(a)software-erosion.org> wrote:

> > What about "independent addressability" from 13.3?

> I don't think this applies here as the array components are not aliased

With my version of GNAT everything is stored at the same location when
"aliased" is added to components of the array.
I can see it by having *equal* access variables created from different
array indices:

with Ada.Text_IO;

procedure A is

type Empty_Record is null record;
for Empty_Record'Size use 0;

A : array (Integer range <>) of aliased Empty_Record := (1 .. 100
=> <>);

type Empty_Ptr is access all Empty_Record;
P1 : Empty_Ptr := A (1)'Access;
P2 : Empty_Ptr := A (2)'Access;

begin

if P1 = P2 then
Ada.Text_IO.Put_Line ("Equal access values.");
else
Ada.Text_IO.Put_Line ("Distinct access values.");
end if;

end;

Is it bug or feature?

> But in any case my "range objects" do not rely on the compiler not
> allocating memory.

Right, but they just expose an interesting compiler behavior.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com