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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,40db5229aec061c0 X-Google-Attributes: gid103376,public From: Matthew Heaney Subject: Re: access to controlled types Date: 1999/02/20 Message-ID: #1/1 X-Deja-AN: 446373535 Sender: matt@mheaney.ni.net References: <918079635.219550@outpost1.roc.accglobal.net> <918223958.430528@outpost1.roc.accglobal.net> NNTP-Posting-Date: Sat, 20 Feb 1999 03:48:13 PDT Newsgroups: comp.lang.ada Date: 1999-02-20T00:00:00+00:00 List-Id: Matthew Heaney writes: > "Terry J. Westley" writes: > > > You have a good point. I'll think about it a bit. The specific > > situation is that TASH supports Tcl lists which are heterogenous. > > > > So, when you fetch an element out of the list, it could be an > > integer, a float, a string, or another list. > > > Can your list return a discriminated object? Something like the code > below. Actually, I thought of another way to do this, that doesn't require a List_Item type in the spec. Function Get_Head can just return the different types (float, integer, string, list) directly, without the intermediate type. If you know you have just floats, say, then you don't even have to bother calling the Get_Item_Kind query function. I don't really know if this is what you had in mind. But if you want a reference-counted list, then a private non-limited list type, implemented as deriving from Controlled, is the way to go. This is one example of the fact that you do not have to expose access types in the spec. Access types are only for implementing abstractions, and can thus be hidden from clients. (There is one exception to this rule. See my post about the Interpreter pattern in the patterns archive at the ACM, which uses an access type as a "handle," to point to a limited and indefinite type.) with Ada.Finalization; package Lists2 is type List_Type is private; type List_Item_Kind is (Float_List_Item, Integer_List_Item, String_List_Item, List_List_Item); function Get_Item_Kind (List : List_Type) return List_Item_Kind; function Get_Head (List : List_Type) return Float; function Get_Head (List : List_Type) return Integer; function Get_Head (List : List_Type) return String; function Get_Head (List : List_Type) return List_Type; private type Node_Type; type Node_Access is access Node_Type; type List_Type is new Ada.Finalization.Controlled with record Head : Node_Access; end record; procedure Adjust (List : in out List_Type); procedure Finalize (List : in out List_Type); end Lists2; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; package body Lists2 is type List_Item (Kind : List_Item_Kind := List_Item_Kind'First) is record case Kind is when Float_List_Item => F : Float; when Integer_List_Item => I : Integer; when String_List_Item => S : Unbounded_String; when List_List_Item => L : List_Type; end case; end record; type Node_Type is record Item : List_Item; Ref_Count : Natural := 0; Next : List_Type; -- or Node_Access? end record; function Get_Item_Kind (List : List_Type) return List_Item_Kind is begin return List.Head.Item.Kind; end; function Get_Head (List : List_Type) return Float is begin return List.Head.Item.F; end; function Get_Head (List : List_Type) return Integer is begin return List.Head.Item.I; end; function Get_Head (List : List_Type) return String is begin return To_String (List.Head.Item.S); end; function Get_Head (List : List_Type) return List_Type is begin return List.Head.Item.L; end; procedure Adjust (List : in out List_Type) is begin null; -- adjust ref count end; procedure Finalize (List : in out List_Type) is begin null; -- adjust ref count end; end Lists2;