comp.lang.ada
 help / color / mirror / Atom feed
From: Blady <p.p11@orange.fr>
Subject: Re: Generalized Loop Iteration and User-Defined Indexing with more than two parameters.
Date: Fri, 6 Nov 2020 16:39:09 +0100	[thread overview]
Message-ID: <ro3qms$1vdh$1@gioia.aioe.org> (raw)
In-Reply-To: 86361qwvht.fsf@stephe-leake.org

Le 03/11/2020 à 12:05, Stephen Leake a écrit :
> Blady <p.p11@orange.fr> 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.

  reply	other threads:[~2020-11-06 15:39 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-01 18:41 Generalized Loop Iteration and User-Defined Indexing with more than two parameters Blady
2020-11-03 11:05 ` Stephen Leake
2020-11-06 15:39   ` Blady [this message]
2020-11-07  0:58     ` Randy Brukardt
2020-11-07 17:46       ` Blady
2020-11-10  1:45         ` Randy Brukardt
2020-11-07 23:54       ` Stephen Leake
replies disabled

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