From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,330ec86e1824a689 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2002-08-28 17:37:45 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!nntp-server.caltech.edu!attla2!ip.att.net!attbi_feed3!attbi_feed4!attbi.com!sccrnsc03.POSTED!not-for-mail From: tmoran@acm.org Newsgroups: comp.lang.ada Subject: Re: Run-Time Type Assignment References: X-Newsreader: Tom's custom newsreader Message-ID: <3jcb9.276121$UU1.47943@sccrnsc03> NNTP-Posting-Host: 12.234.13.56 X-Complaints-To: abuse@attbi.com X-Trace: sccrnsc03 1030574399 12.234.13.56 (Wed, 28 Aug 2002 22:39:59 GMT) NNTP-Posting-Date: Wed, 28 Aug 2002 22:39:59 GMT Organization: AT&T Broadband Date: Thu, 29 Aug 2002 00:37:41 GMT Xref: archiver1.google.com comp.lang.ada:28536 Date: 2002-08-29T00:37:41+00:00 List-Id: > type Level_One is new Base_Type with record >... > type Level_Two is new Level_One with record >... > type Level_Three is new Level_Two with record Seems the most straightforward to me. But in Bob Leif said: > I do not know how to select a subtype of a class at run-time. function Read_Whatever return Base_Type'class is begin -- read and find out what kind of record you have, then return it if figured_out_its_Level_One then declare Result : Level_One; begin -- fill Result with info return Result; end; elsif figured_out_its_Level_Two then declare Result : Level_Two; begin -- fill Result with info return Result; end; ... end Read_Whatever; One way to handle the different subtypes is procedure Process is Data : Base_Type'class := Read_Whatever; begin -- process the Level_One info that's always present if Data in Level_One then return;end if; -- that's all in this case -- now process the Level_Two stuff that's present in this case if Data in Level_Two then return;end if; -- that's all -- now process the Level_Three stuff that must be present in this case ... or, more in OO style: procedure Process(Data : in Level_One) is ... procedure Process(Data : in Level_Two) is ... procedure Process(Data : in Level_Three) is ... and then declare Data : Base_Type'class := Read_Whatever; begin Process(Base_Type'class(Data)); -- call the appropriate Process routine end; Since these things are different sizes, you can't put them in an array, all of whose elements must be the same size. But you can put in access values. type Base_Type_Access is access Base_Type'class; Everything : array(1 .. 1_000_000) of Base_Type_Access; Count : Natural := 0; while not EOF loop Count := Count+1; Everything(Count) := new Base_Type'class'(Read_Whatever); end loop; -- Now Everything(1 .. Count) contains pointers to the records. -- The records are stored on the heap, each taking only as -- much room as it needs. for i in 1 .. Count loop -- for each record, Process(Base_Type'class(Everything(i).all)); -- do appropriate Process end loop; --- Code not tested!