erickson@cs.nps.navy.mil (David Erickson) (08/02/90)
Is there any way to define "=" for a limited private type which is an access type (which may be null)? The problem arises trying to test for null without producing an infinitely recursive definition. The only solution that I am aware of is to use UNCHECKED_CONVERSION to retype the access type during the test for null, but this is a hack. Is there a cleaner solution? Thanks - Dave Erickson
mackey@scs.fiu.edu (08/02/90)
In article <1152@cs.nps.navy.mil> erickson@cs.nps.navy.mil (David Erickson) writes: >Is there any way to define "=" for a limited private type which is an >access type (which may be null)? The problem arises trying to test for >null without producing an infinitely recursive definition. > >The only solution that I am aware of is to use UNCHECKED_CONVERSION to >retype the access type during the test for null, but this is a hack. >Is there a cleaner solution? > >Thanks - > > Dave Erickson The easiest way to solve this problem is not to say type blurg is limited private ... type blurg is access widget; at all. Instead, say: type blurg is limited private ... type blurg_pointer is access widget; type blurg is record value : blurg_pointer; end record; Then, when you want to deal with the procedure call "=" which compares blurgs, you use the record. Inside the body of the package, you qualify the object with the .value field and you then get the "=" which compares the pointers themselves. The client of this package of course can not get to this function. .
NCOHEN@IBM.COM ("Norman H. Cohen") (08/02/90)
Ref: INFO-ADA Digest Volume 90 Issue 148 (Wed, Aug 1, 1990) Item #2 David Erickson asks: >Is there any way to define "=" for a limited private type which is an >access type (which may be null)? The problem arises trying to test for >null without producing an infinitely recursive definition. You can define an access type in the private part corresponding to the internal view of the type as a pointer. The full type declaration for the limited private type should derive from this type. The redefinition of equality in the package spec will apply only to the derived type, not to the parent. Thus two views of the same data structure are available in the package body, one corresponding to a pointer view and one corresponding to the abstraction for which "=" has been redefined. The two views are embodied by two different types, each with a version of "=" appropriate to that view. The package body can convert between the two types, using not Unchecked_Conversion, but conversion between a derived type and its parent. For example: package Integer_List_Package is type Integer_List_Type is limited private; function "=" (Left, Right: Integer_List_Type) return Boolean; -- [other subprograms] private -- Ordinary declaration of a recursive access type: type List_Cell_Type; type Cell_Pointer_Type is access List_Cell_Type; type List_Cell_Type is record Value_Part : Integer; Link_Part : Cell_Pointer_Type; end record; -- Full declaration of the limited private type: type Integer_List_Type is new Cell_Pointer_Type; end Integer_List_Package; package body Integer_List_Package is function "=" (Left, Right: Integer_List_Type) return Boolean is Left_Pointer : Cell_Pointer_Type := Cell_Pointer_Type (Left); Right_Pointer : Cell_Pointer_Type := Cell_Pointer_Type (Right); begin loop if Left_Pointer = null then return Right_Pointer = null; elsif Right_Pointer = null then return False; else Left_Pointer := Left_Pointer.Link_Part; Right_Pointer := Right_Pointer.Link_Part; end loop; end "="; -- [other subprograms] end Integer_List_Package; Left_Pointer and Right_Pointer are declared to be of Cell_Pointer_Type and initialized using type conversions. The three = operators in the if statement all have left operands of Cell_Pointer_Type, so they invoke the predefined access-type equality for Cell_Pointer_Type, not (recursively) the redefined "=" for Integer_List_Type.
kassover@minerva.crd.ge.com (David Kassover) (08/03/90)
In article <1152@cs.nps.navy.mil> erickson@cs.nps.navy.mil (David Erickson) writes: |Is there any way to define "=" for a limited private type which is an |access type (which may be null)? The problem arises trying to test for |null without producing an infinitely recursive definition. | |The only solution that I am aware of is to use UNCHECKED_CONVERSION to |retype the access type during the test for null, but this is a hack. |Is there a cleaner solution? | Export from the package defining the limited type a function that returns TRUE if the access type variable is not null. Or the other way around, if you prefer. -- David Kassover "Proper technique helps protect you against kassover@ra.crd.ge.com sharp weapons and dull judges." kassover@crd.ge.com F. Collins
erickson@cs.nps.navy.mil (David Erickson) (08/03/90)
In article <10687@crdgw1.crd.ge.com> kassover@minerva.crd.ge.com (David Kassover) writes: >In article <1152@cs.nps.navy.mil> erickson@cs.nps.navy.mil (David Erickson) writes: >|Is there any way to define "=" for a limited private type which is an >|access type (which may be null)? The problem arises trying to test for >|null without producing an infinitely recursive definition. >| >|The only solution that I am aware of is to use UNCHECKED_CONVERSION to >|retype the access type during the test for null, but this is a hack. >|Is there a cleaner solution? >| > >Export from the package defining the limited type a function that >returns TRUE if the access type variable is not null. Or the other way >around, if you prefer. > >-- >David Kassover "Proper technique helps protect you against >kassover@ra.crd.ge.com sharp weapons and dull judges." >kassover@crd.ge.com F. Collins This will not work in this case. I specifically need to define "=" for a list which is implemented as a linked list. In this case, "=" should return true if the two lists being compared are the same length and the contents of each node are equal. The user should not be aware that the implementation uses pointers. The problem is that I cannot find a way to use the predefined "=" to test for null in the definition for "=" that I am exporting. According to the ARM, the predefined "=" is implicitly declared immediately after the type declaration, prior to the next statement. However, my declaration of "=" supersedes the implicit "=", and I can think of no way to capture the implicit "=". -Dave Erickson Erickson@cs.nps.navy.mil
sampson@cod.NOSC.MIL (Charles H. Sampson) (08/04/90)
In article <1152@cs.nps.navy.mil> erickson@cs.nps.navy.mil (David Erickson) writes: >Is there any way to define "=" for a limited private type which is an >access type (which may be null)? The problem arises trying to test for >null without producing an infinitely recursive definition. This is a special case of the problem of breaking the recursion when defining an overloaded operator on a private type. The LRM contains an example, 7.4.2(13). In that example, the private type was realized as a named type (Integer) and the name was used to convert from the private type to a type different from that of the function's arguments. In your case, the realization of your private type has no name, in the straight- forward implementation, so you have to circle around the problem in order to give it a name: ... TYPE Ltd_pvt IS LIMITED PRIVATE; ... PRIVATE ... TYPE Type_name IS ACCESS List_link; TYPE Ltd_pvt IS NEW Type_name; ... END PACKAGE ...; PACKAGE BODY ... ... FUNCTION "="(L, R : Ltd_pvt) RETURN Boolean IS BEGIN ... IF Typ_name(L) = NULL THEN ... ... END "="; Charlie Sampson
clay@titan.tsd.arlut.utexas.edu (Clay Johnson) (08/10/90)
In article <1152@cs.nps.navy.mil> erickson@cs.nps.navy.mil (David Erickson) writes: > Is there any way to define "=" for a limited private type which is an > access type (which may be null)? The problem arises trying to test for > null without producing an infinitely recursive definition. > > The only solution that I am aware of is to use UNCHECKED_CONVERSION to > retype the access type during the test for null, but this is a hack. > Is there a cleaner solution? I have not done so, but you should be able to `dereference' the "=" that appears within your overloaded "=" function by using the dotted notation, prepending the package name STANDARD where you want the original interpretation. Of course, you must then use the functional rather infix notation: if STANDARD."="(POINTER,null) then ... I'm no Ada expert, but it's my understanding that the dot notation may always be used to avoid ambiguity and, specifically, unintentional recursion when overloading a subprogram or operator. In general this can be useful; depending upon your implementation, you may want both the original operator and the new operator (recursively) available at the same time. For instance, if your new operator is meant to compare two recursively defined structures, like binary trees, then you may wish to define the new operator recursively, while also refering to the original interpretation of the operator. Let me know if this works, Clay
erickson@cs.nps.navy.mil (David Erickson) (08/10/90)
In article <CLAY.90Aug9121901@clio.titan.tsd.arlut.utexas.edu> clay@titan.tsd.arlut.utexas.edu (Clay Johnson) writes: >In article <1152@cs.nps.navy.mil> erickson@cs.nps.navy.mil (David Erickson) writes: > >> Is there any way to define "=" for a limited private type which is an >> access type (which may be null)? >I have not done so, but you should be able to `dereference' the "=" >that appears within your overloaded "=" function by using the dotted >notation, ... > if STANDARD."="(POINTER,null) then ... >Let me know if this works, >Clay This will not work. As I noted in a previous posting, the basic operators for a type (including "=") are implicitly defined immediately after the type declaration, rather than in STANDARD. -Dave Erickson