comp.lang.ada
 help / color / mirror / Atom feed
From: AdaMagica <christ-usch.grein@t-online.de>
Subject: Generalized Iterators
Date: Tue, 29 Dec 2015 03:50:54 -0800 (PST)
Date: 2015-12-29T03:50:54-08:00	[thread overview]
Message-ID: <aea9159f-c02c-4a08-915a-504227424bd9@googlegroups.com> (raw)

I'm experiencing problems with generalized iterators. The code below is reduced
to the minimum in order to be compilable and show the problem. Note that the
body of Circularly_Linked_Lists is not given since not needed to produce the
problem.

The code follows strictly the examples given in the Ada 2012 Rationale.
Expecially the function Iterate is defined thus:

  function Iterate (CLL: not null access Circularly_Linked_List)
    return Forward_Iterator'Class;

This produces the compiler message (GNAT GPL 2015)

  for Cursor in List.Iterate loop
ausprobieren.adb:15:21: expect object that implements iterator interface

Note that the aspects Default_Iterator and Iterator_Element are not needed as
long as the loop above uses "in" rather than "of".

If the function Iterate is replaced by (note the place of the attribute Class)

  function Iterate (CLL: not null access Circularly_Linked_List'Class)
    return Forward_Iterator;

the loop works as expected. When I then add the aspects Default_Iterator
and Iterator_Element and try to use the "of" loop, I get

  for Int of List loop
ausprobieren.adb:19:14: expected an access type with designated type "Circularly_Linked_List'Class" defined at circularly_linked_lists.ads:9, instance at line 8
ausprobieren.adb:19:14: found private type "Circularly_Linked_List" defined at circularly_linked_lists.ads:9, instance at line 8
ausprobieren.adb:19:14:   ==> in call to "Iterate" at circularly_linked_lists.ads:32, instance at line 8
ausprobieren.adb:19:14:   ==> in call to "Iterate" at circularly_linked_lists.ads:32, instance at line 8
ausprobieren.adb:19:19: invalid prefix in selected component "I280b"
    Put_Line (Integer'Image (Int));
  end loop;

I can understand this since Iterate has the list as an access parameter,
and the compiler tries to construct the "in" loop from the default iterator.
But also this does not work:

  for Int of List'Access loop

Is this a problem of GNAT or is there anything I just don't see?

Also in Ada.Containers.Doubly_Linked_Lists, Iterate is defined like so with
the Class attribute at the iterator:

   function Iterate (Container : List)
      return List_Iterator_Interfaces.Reversible_Iterator'Class;

Code below:
------------------------
with Ada.Iterator_Interfaces;

generic

  type Element_Type is private;

package Circularly_Linked_Lists is

  type Circularly_Linked_List is tagged private
    with -- Default_Iterator  => Iterate,
         -- Iterator_Element  => Element_Type,
         Variable_Indexing => Acc;

  type Accessor (Elem: not null access Element_Type) is limited null record
    with Implicit_Dereference => Elem;

  type Cursor is private;

  function Has_Element (Position: Cursor) return Boolean;

  function Acc (CLL     : in out Circularly_Linked_List;
                Position: in     Cursor) return Accessor;

  package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, Has_Element);

  type Forward_Iterator (CLL: not null access Circularly_Linked_List) is new Iterator_Interfaces.Forward_Iterator with null record;

  overriding function First (Object  : Forward_Iterator) return Cursor;
  overriding function Next  (Object  : Forward_Iterator;
                             Position: Cursor          ) return Cursor;

--function Iterate (CLL: not null access Circularly_Linked_List'Class) return Forward_Iterator;
  function Iterate (CLL: not null access Circularly_Linked_List      ) return Forward_Iterator'Class;

private

  type CLL_Ptr is access all Circularly_Linked_List;

  type Cursor is record
    Current: CLL_Ptr;
  end record;

  type Circularly_Linked_List is tagged record
    Next, Prev: CLL_Ptr;
  end record;

end Circularly_Linked_Lists;
with Ada.Text_IO;
use  Ada.Text_IO;

with Circularly_Linked_Lists;

procedure Ausprobieren is

  package Lists is new Circularly_Linked_Lists (Integer);
  use Lists;

  List: aliased Circularly_Linked_List;

begin

  for Cursor in List.Iterate loop
    Put_Line (Integer'Image (List (Cursor)));
  end loop;

end Ausprobieren;


             reply	other threads:[~2015-12-29 11:50 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-29 11:50 AdaMagica [this message]
2015-12-29 22:12 ` Generalized Iterators Randy Brukardt
2015-12-31 10:33   ` AdaMagica
2016-01-05  1:54 ` Lucretia
replies disabled

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