From mboxrd@z Thu Jan 1 00:00:00 1970
X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on
ip-172-31-74-118.ec2.internal
X-Spam-Level:
X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00,FREEMAIL_FROM
autolearn=ham autolearn_force=no version=3.4.5-pre1
Path: eternal-september.org!reader02.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED.j1cmyFOIqnSpYf1NFre2bA.user.gioia.aioe.org!not-for-mail
From: Blady
Newsgroups: comp.lang.ada
Subject: Re: Generalized Loop Iteration and User-Defined Indexing with more
than two parameters.
Date: Fri, 6 Nov 2020 16:39:09 +0100
Organization: Aioe.org NNTP Server
Message-ID:
References: <86361qwvht.fsf@stephe-leake.org>
NNTP-Posting-Host: j1cmyFOIqnSpYf1NFre2bA.user.gioia.aioe.org
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Complaints-To: abuse@aioe.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:68.0)
Gecko/20100101 Thunderbird/68.12.1
X-Notice: Filtered by postfilter v. 0.9.2
Content-Language: en-US
Xref: reader02.eternal-september.org comp.lang.ada:60558
List-Id:
Le 03/11/2020 à 12:05, Stephen Leake a écrit :
> Blady writes:
>
>> Hello,
>>
>> Let's take the following container with constant indexing for iteration:
>>
>> 6. type UXString is tagged private with
>> 7. Constant_Indexing => Get,
>> 8. Iterable => (First => First, Next => Next,
>> Has_Element => Has_Element, Element => Get);
>
>> 11. function Get (Self : UXString; Index : Positive;
>> Substitute : in Character) return Character;
>
> Hmm. Aspect "Iterable" is not defined by Ada. It is defined by GNAT. The
> gnat reference manual says:
>
> * The value of `Element' is a primitive operation of the container
> type that takes both a container and a cursor and yields an
> `Element_Type', which must be a type declared in the container
> package or visible from it. For example:
>
> function Get_Element (Cont : Container; Position : Cursor) return Element_Type;
>
> So it should have complained that your "Element => Get" is illegal.
>
>> What is the correct usage?
>
> An iterator 'Element' function can take only two parameters; the same is
> true for standard Ada generalized iterators.
>
> A Constant_Indexing function can take more than two parameters, but you
> can only use it by indexing a container object directly (see LRM 4.1.6),
>
> A : UXString;
>
> for Position in A.First .. A.Last loop
>
> Foo := A (Position, Substitute => 'C');
> ...
Hello,
Thanks Stephen, I hadn't noticed that Iterate aspect was a GNAT specific
aspect. I've borrowed it from GNATColl XString type.
Thus, I turn my program in a more Ada way:
type UXString is tagged private with
Default_Iterator => Iterate,
Iterator_Element => Character,
Constant_Indexing => Get;
type Cursor is private;
function Get (Self : UXString; Position : Cursor) return Character;
function Has_Element (Position : Cursor) return Boolean;
package UXString_Iterators is new Ada.Iterator_Interfaces
(Cursor, Has_Element);
function Iterate (Self : UXString) return
UXString_Iterators.Forward_Iterator'Class;
...
for I in S1.Iterate loop
C := S1 (I);
F := S1 (I) = 'h';
Put_Line (Character'pos (C)'img & F'img);
end loop;
for CC of S2 loop
C := CC;
Put_Line (Character'pos (C)'img);
end loop;
Ada RM 5.5.1 "User-Defined Iterator Types" says:
"The Constant_Indexing aspect (if any) of an iterable container type T
shall denote exactly one function with the following properties:
...
if there are more than two parameters, the additional parameters all
have default expressions."
So I defines:
function Get (Self : UXString; Position : Cursor; Substitute : in
Character := '&') return Character;
and then:
for I in S1.Iterate loop
C := S1 (I, '@');
F := S1 (I) = 'h';
Put_Line (Character'pos (C)'img & F'img);
end loop;
for CC of S2 loop
C := CC;
Put_Line (Character'pos (C)'img);
end loop;
However, I have 3 questions about iteration:
1) When using Default_Iterator aspect, both Iterator_Element and
Constant_Indexing have to be defined also.
If I understand why Constant_Indexing at least has to be defined, what
is the purpose of Iterator_Element?
2) In Ada.Iterator_Interfaces, why Has_Element is a generic formal
parameter instead of an abstract function of Forward_Iterator interface?
As:
function Has_Element
(Object : Forward_Iterator;
Position : Cursor) return Boolean is abstract;
The current way requires that Cursor type has the container reference
embedded and cannot be a simple index type.
3) Couldn't be the additional parameters of the Constant_Indexing
function without parameters defaults and a for ... of form as one of the
followings?
function Get (Self : UXString; Position : Cursor; Substitute : in
Character) return Character;
...
for CC of S2 ('@') loop
C := CC;
Put_Line (Character'pos (C)'img);
end loop;
or less preferable:
for CC of S2 loop
C := CC ('@');
Put_Line (Character'pos (C)'img);
end loop;
Thanks for your answers, Pascal.