comp.lang.ada
 help / color / mirror / Atom feed
From: Jacob Sparre Andersen <sparre@nbi.dk>
Subject: Re: working with diferent instances of the same generic interface
Date: Thu, 10 Sep 2015 14:22:56 +0200
Date: 2015-09-10T14:22:56+02:00	[thread overview]
Message-ID: <87egi65uqn.fsf@adaheads.sparre-andersen.dk> (raw)
In-Reply-To: adaff0f1-2522-42ad-b51b-78952da33e9c@googlegroups.com

Aitor Alcrudo Sangros wrote:

> Hi, I'm not really specifically tring to make that code work as
> is. What I want to know is how can I work with different instances of
> the same generic interface, doing things like iterating over a
> collection of them. This is a minimal example of how I am
> (unsuccessfully ) tring to do so. Anyway this code compiles, then has
> a runtime exception.

Your problem is that you instantiate the same package much too often.
Here is a working "solution":

package Intro is
      type Data_type is interface;

      generic
         type Readable_Data is abstract new Data_type with private;
      package Readable is
         type    Readable_Element is interface;
         subtype Readable_Class   is Readable_Element'Class ;
         function Get_Values (this : Readable_Element ) return Readable_Data'Class
                           is abstract;
      end Readable;

      type state is (OK,KO);

      generic
         with package Readable_Reporting is new Readable(<>);
         use Readable_Reporting ;
      package Reporting is
         type    Reporting_Element is interface and Readable_Element ;
         subtype Reporting_Class   is Reporting_Element'Class;
         function Report (This :Reporting_Element  ) return state is Abstract;
         overriding function Get_Values (this : Reporting_Element ) return
           Readable_Data'Class is abstract;
      end Reporting;
   end Intro;
with Intro;

package Instantiations is
   package Readable_Basic  is new Intro.Readable  (Intro.Data_Type);
   package Reporting_Basic is new Intro.Reporting (Readable_Basic);
end Instantiations;
with Intro,
     Instantiations;

package A is
   type SomeData is new Intro.Data_type with record
      a :float;
   end record;

   package Readable_Some  renames Instantiations.Readable_Basic;
   package Reporting_Some renames Instantiations.Reporting_Basic;

   type Element_type_A is
     new Readable_Some.Readable_Element and Reporting_Some.Reporting_Element
     with
      record
         data : SomeData := SomeData'(a => 0.0 );
      end record;

   subtype Element_type_A_Class is Element_type_A'Class;
   overriding function Report(This : Element_Type_A ) return Intro.state is ( Intro.KO);

   overriding
   function Get_Values (this : Element_type_A ) return Intro.Data_Type'Class is
      (this.data);
end A;
with Intro,
     Instantiations;

package B is
   type OtherData is new Intro.Data_type with record
      a :float;
   end record;

   package Readable_Other  renames Instantiations.Readable_Basic;
   package Reporting_Other renames Instantiations.Reporting_Basic;

   type Element_type_B is new Readable_Other.Readable_Element
     and Reporting_Other.Reporting_Element
     with record
        data :OtherData;
   end record;
   subtype Element_type_B_Class is Element_type_B'Class;
   function Get_Values (this : Element_type_B ) return Intro.Data_Type'Class is
      (this.data);
      function Report(This : Element_type_B ) return Intro.state is ( Intro.KO);
end B;
with Ada.Containers.Indefinite_Vectors;

with Intro,
     Instantiations;

package Manager is
   package Reporting_Basic renames Instantiations.Reporting_Basic;
   use Reporting_Basic;

   package Element_Vector is new
     Ada.Containers.Indefinite_Vectors
     (Index_Type   => Natural,
      Element_Type => Reporting_Basic.Reporting_Class);
   use Element_Vector;

   type Manager is tagged record
      elements :  Element_Vector.Vector;
   end record;
   procedure Add_Element(this : in out Manager ;
                         Element : in Reporting_Class );
end Manager;

   package body Manager is
      procedure Add_Element(this : in out Manager ;
                            Element : in Reporting_Class ) is
      begin
         this.elements.Append(Element);
      end Add_Element;
   end Manager;
with Ada.Text_IO;

with A, B, Manager;

procedure Test is
   Man      : Manager.Manager;
   Elm1_ptr : A.Element_Type_A_Class := A.Element_Type_A'(Data => (A => 1.0));
   Elm2_ptr : B.Element_Type_B_Class := B.Element_Type_B'(Data => (A => 2.0));
begin
   Man.Add_Element (Manager.Reporting_basic.Reporting_Class(Elm1_ptr));
   Ada.Text_IO.Put_Line ("1 worked.");

   Man.Add_Element (Manager.Reporting_basic.Reporting_Class(Elm2_ptr));
   Ada.Text_IO.Put_Line ("2 worked.");
end Test;

Notice how there's no need for access types.

Greetings,

Jacob
-- 
"Universities are not part of the nation's security organisation,
 they are not the nation's research laboratory either: they are
 the nation's universities."                     -- E.W. Dijkstra

      parent reply	other threads:[~2015-09-10 12:22 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-08 15:10 working with diferent instances of the same generic interface Aitor Alcrudo Sangros
2015-09-08 17:11 ` G.B.
2015-09-09  6:38 ` Jacob Sparre Andersen
2015-09-09 11:08   ` Aitor Alcrudo Sangros
2015-09-09 12:17     ` Egil H H
2015-09-09 12:41       ` Aitor Alcrudo Sangros
2015-09-09 13:10         ` Egil H H
2015-09-09 14:50           ` Aitor Alcrudo Sangros
2015-09-09 16:48             ` Egil H H
2015-09-09 19:04               ` Aitor Alcrudo Sangros
2015-09-09 19:16                 ` Dmitry A. Kazakov
2015-10-01 16:45                   ` Aitor Alcrudo Sangros
2015-10-01 19:29                     ` Dmitry A. Kazakov
2015-10-01 20:09                       ` Randy Brukardt
2015-09-13 18:22             ` Florian Weimer
2015-09-10 12:22     ` Jacob Sparre Andersen [this message]
replies disabled

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