From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Date: 23 Sep 93 22:04:30 GMT From: news.bu.edu!inmet!spock!stt@decwrl.dec.com (Tucker Taft) Subject: Re: null unconstrained arrays vs generic formal types Message-ID: List-Id: In article <23SEP199311043613@bambam.gsfc.nasa.gov> nbssal@bambam.gsfc.nasa.gov (Stephe Leake) writes: >I've recently run across an problem with unconstrained arrays and generic >parameters, due to LRM 12.3.4(5). I use the following convention for index >types, to allow representing a null array: > > type ZERO_INDEX_TYPE is range 0 .. Index_Last; > subtype INDEX_TYPE is ZERO_INDEX_TYPE range 1 .. Index_Last; > type INDEX_ARRAY_ELEMENT_TYPE is array (INDEX_TYPE range <>) > of ELEMENT_TYPE; > >A generic array IO package looks like: > >with Text_IO; >generic > type ELEMENT_TYPE is range <>; > type INDEX_TYPE is (<>); > type INDEX_ARRAY_ELEMENT_TYPE is array (INDEX_TYPE range <>) > of ELEMENT_TYPE; > with procedure Element_Get > (Item : out ELEMENT_TYPE; Width : in Text_IO.FIELD); > with procedure Element_Put ( > Item : in ELEMENT_TYPE; > Width : in Text_IO.FIELD; > Base : in Text_IO.NUMBER_BASE); >package Unconstrained_Integer_1D is > procedure Get (Item : out INDEX_ARRAY_ELEMENT_TYPE; Last : out INDEX_TYPE) ; > procedure Put (Item : in INDEX_ARRAY_ELEMENT_TYPE); >end Unconstrained_Integer_1D; > >I would like to instantiate this: > > package Foo is new Unconstrained_Integer_1d > (... > INDEX_TYPE => ZERO_INDEX_TYPE, -- CONSTRAINT_ERROR! > INDEX_ARRAY_ELEMENT_TYPE => INDEX_ARRAY_ELEMENT_TYPE, > ... > ); > >Giving the Get procedure the parameter profile: > > procedure Get (Item : out INDEX_ARRAY_ELEMENT_TYPE; > Last : out ZERO_INDEX_TYPE); > >Then Last can be less than Item'first to indicate a null array. But this raise s >CONSTRAINT_ERROR, because INDEX_TYPE has different bounds than ZERO_INDEX_TYPE . > >One fix is to declare two different type parameters for the generic >package: > >generic > ... > type INDEX_TYPE is (<>); > type ZERO_INDEX_TYPE is (<>); > type INDEX_ARRAY_ELEMENT_TYPE is array (INDEX_TYPE range <>) > of ELEMENT_TYPE; > ... >package Unconstrained_Integer_1D is > procedure Get (Item : out INDEX_ARRAY_ELEMENT_TYPE; > Last : out ZERO_INDEX_TYPE); > ... >end Unconstrained_Integer_1D; > >But this does not express the convention that INDEX_TYPE is a subtype of >ZERO_INDEX_TYPE. > >So, does Ada 9x fix this by relaxing LRM 12.3.4(5)? Does anyone have an >alternate solution? In Ada 9X, one fix would be to define a subtype using the 'Base attribute. Hence: generic ... type Index_Subtype is (<>); -- Note the name change type Index_Array_Element_Type is array(Index_Subtype range <>) of Element_Type; ... package Unconstrained_Integer_1D is subtype Last_Index_Subtype is Index_Subtype'Base range Index_Subtype'Prev(Index_Subtype'First) .. Index_Subtype'Last; procedure Get(Item : out Index_Array_Element_Type; Last : out Last_Index_Subtype); ... I have changed the name of the formal type to "Index_Subtype" to reflect the fact that it is presumably a constrained subtype of its type. Note that in Ada 83, the 'Base attribute cannot be used in this way; 'Base may only be used as a prefix for other attributes in Ada 83. In Ada 9X 'Base is fully general for scalar types. Even simpler (and somewhat more general) than the above would be to just declare procedure Get as: ... procedure Get(Item : out Index_Array_Element_Type; Last : out Index_Subtype'Base); The advantage of this is that it works even if it so happens that Index_Subtype'First = Index_Subtype'Base'First. Hence, defining the subtype Last_Index_Subtype is probably more trouble than it is worth. >Stephen Leake NASA Goddard Robotics Lab >internet : nbssal@robots.gsfc.nasa.gov S. Tucker Taft stt@inmet.com Ada 9X Mapping/Revision Team Intermetrics, Inc. Cambridge, MA 02138