* automatic tag conversion? @ 2003-05-23 23:04 Stephan Heinemann 2003-05-23 23:57 ` Stephan Heinemann 0 siblings, 1 reply; 8+ messages in thread From: Stephan Heinemann @ 2003-05-23 23:04 UTC (permalink / raw) I would like to convert a Subtype of a tagged Supertype stored in a variable of Supertype into a variable of Subtype. I do not want to use the following: if supervar'Tag = "Subtype" then polymorphic(Subtype(supervar)); elsif ... else ... end if; Isn't there anything like: t: Tag; subvar: Subtype; ... t := supervar'Tag; subvar := t'convert(supervar); -- convert(t, supervar) polymorphic(subvar); ? It is because I would like to extend the Supertype and use dynamic binding / polymorphism for the appropriate variable of Subtype without having to do this String mess. Thanks in advance, Stephan ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: automatic tag conversion? 2003-05-23 23:04 automatic tag conversion? Stephan Heinemann @ 2003-05-23 23:57 ` Stephan Heinemann 2003-05-24 17:39 ` Georg Bauhaus 0 siblings, 1 reply; 8+ messages in thread From: Stephan Heinemann @ 2003-05-23 23:57 UTC (permalink / raw) Stephan Heinemann <zombie@cs.tu-berlin.de> wrote: > t: Tag; > subvar: Subtype; > ... > t := supervar'Tag; > subvar := t'convert(supervar); -- convert(t, supervar) > polymorphic(subvar); Of course I don't know what the concrete Subtype is and I don't wanna know. Therefore the code snippet is wrong. I meant: polymorphic(t'convert(supervar)) or better and safer (because t may describe a Type not within Supertype) polymorphic(supervar'TagType) It is not my lazyness, but I'd like to extend my code without updating conditionals on Strings. For every new Subtype of Supertype I not only need to overload the polymorphic procedure but also a String comparation. Thanks, Stephan ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: automatic tag conversion? 2003-05-23 23:57 ` Stephan Heinemann @ 2003-05-24 17:39 ` Georg Bauhaus 2003-05-25 20:59 ` Stephan Heinemann 0 siblings, 1 reply; 8+ messages in thread From: Georg Bauhaus @ 2003-05-24 17:39 UTC (permalink / raw) Stephan Heinemann <zombie@cs.tu-berlin.de> wrote: : Stephan Heinemann <zombie@cs.tu-berlin.de> wrote: : :> t: Tag; :> subvar: Subtype; :> ... :> t := supervar'Tag; :> subvar := t'convert(supervar); -- convert(t, supervar) :> polymorphic(subvar); : : Of course I don't know what the concrete Subtype is and I don't wanna : know. Therefore the code snippet is wrong. I meant: If I understand your wording correctly (in Ada, a subtype is different from a derived type (subtypes add value constraints, they do not extend)), it might be simpler. I hope i don't tell matters of course, as I might have missed the intent of your question. Consider this small hierarchy. package R is -- a tagged type type T is tagged record null; end record; function About(it: T) return String; type Switch_State is (on, off); -- an ad hoc Boolean type, used in the derived type TT -- a derived type, extended version of T (what you have called -- a subtype, I believe) type TT is new T with record toggle: Switch_State; end record; function About(it: TT) return String; end R; Then, for a variable to be able to represent objects of any type in this hierarchy, it must either be class-wide, or it must be an access type (pointer, or reference). I have tried to make this distintion in the following snippet: with R; use R; procedure U is VV: TT; -- an instance of extended type TT begin objects: -- as opposed to object pointers declare Current: T := T(VV); -- upward conversion, some VV-components gone! begin -- therefore, the next line doesn't compile, because -- it would mean a downward conversion (with missing -- TT-components): VV := TT(Current); -- however, these do compile, because there is a match for every -- component needed in a TT instance. VV := (Current with toggle => on); VV := TT'(Current with toggle => on); end objects; object_pointers: declare type Poly is access T'class; -- Poly values may refer to T-objects or to TT-objects a_tt: Poly := new TT; a_t: Poly := new T; begin -- attempts to copy assumed TT values into vv vv := TT(a_tt.all); vv := TT(a_t.all); -- tag check will fail at run time end object_pointers; class_wide: -- (this is probably a very incomplete overview) declare any1: T'class := TT'(toggle => off); any2: T'Class := T'(null record) begin any1 := any2; -- run time exception (objects copied, not pointers) VV := TT(any1); end class_wide; end U; HTH, georg ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: automatic tag conversion? 2003-05-24 17:39 ` Georg Bauhaus @ 2003-05-25 20:59 ` Stephan Heinemann 2003-05-26 8:29 ` Dmitry A. Kazakov 0 siblings, 1 reply; 8+ messages in thread From: Stephan Heinemann @ 2003-05-25 20:59 UTC (permalink / raw) Georg, first of all, you are quite right: I should have used the term "derived type" instead of "subtype". Further I did not explain what the problem really is forcing you to write a lot of code - sorry for that. I actually was not talking about tagged types, access to tagged types or even class-wide types but about access to all class-wide types with a given type-identifier. The problem for which I do not have a good solution until now is the following: I am using generic sets like this one: generic type Element is private; package CNAda.Utils.Sets is type Set is private; type LookProcedure is access procedure (e: in Element); type MapProcedure is access procedure (e: in out Element); procedure empty(s: in out Set); procedure insert(e: in Element; s: in out Set); procedure remove(e: in Element; s: in out Set); procedure look(lookp: in LookProcedure; s: in Set); procedure map(mapp: in MapProcedure; s: in Set); private type SetElement is record content: Element; prev: Set; next: Set; end record; type Set is access SetElement; end CNAda.Utils.Sets; I use the following for instantiation of this package. type Node is abstract new Component with private; type NodeClassAccess is access all Node'Class; package NodeClassAccessSets is new CNAda.Utils.Sets(NodeClassAccess); NodeClassAccessSets.Set is a component within another tagged (record) type - a Net. There are various derived types of Node like Transition, Place and further Operation, Socket, Port and so on.... I want to apply a LookProcedure on the set for example to print all elements of this set. There is a primitive operation print defined on the types within the hierarchy: procedure print(n: access Node) is abstract; procedure print(t: access Transition); procedure print(p: access Place); ...and so on. I want the system to dispatch to the most special variant of the procedure for the apropriate derived type like: NodeClassAccessSets.look(print'Access, s); It is clearly possible to pass in a NodeClassAccess variable with any derived *ClassAccess value into a print procedure defined as above even if the print procedure was not overridden by the new derived type. The system would always dispatch the most special case, am I right? But my compiler (gnat 3.13p) does not accept the last statement saying: cnada-cnets-components.adb:43:38: expected type "LookProcedure" defined at cnada-utils-sets.ads:8, instance at cnada-cnets-components.ads:94 cnada-cnets-components.adb:43:38: found type access to "print" defined at line 43 So I changed the print procedures to: procedure print(n: in NodeClassAccess); procedure print(t: in TransitionClassAccess); procedure print(p: in PlaceClassAccess); Now the problematic statement compiles. The first procedure cannot be abstract anymore because it is the procedure passed as the LookProcedure. Now the problem is the following: Always the procedure for the approprate local pointer type of the passed in actual parameter is taken now. (1) If I passed in a TransitionClassAccess actual parameter with a derived *ClassAccess value the procedure of the former is taken. (2) Further I could not pass in a derived *ClassAccess actual parameter without having defined a more special print procedure. (1) forces me to always use the exact *ClassAccess variable for which I want to apply a procedure. Further it forces me to implement the procedure for NodeClassAccess which can be used as type for the passed in actual parameter (having to ask 'Tag for what is the appropriate procedure because Node is still abstract and shall be - that was the problem of my former posting). (2) forces me to always overide the procedure I want to use. There will be procedures for which the appropriate variant is much more important than for print and it would be much less work. What can I do to get out of this mess? Thanks, Stephan ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: automatic tag conversion? 2003-05-25 20:59 ` Stephan Heinemann @ 2003-05-26 8:29 ` Dmitry A. Kazakov 2003-05-26 18:16 ` Georg Bauhaus 0 siblings, 1 reply; 8+ messages in thread From: Dmitry A. Kazakov @ 2003-05-26 8:29 UTC (permalink / raw) Stephan Heinemann wrote: > I am using generic sets like this one: > > generic > type Element is private; > package CNAda.Utils.Sets is > > type Set is private; > type LookProcedure is access procedure (e: in Element); > type MapProcedure is access procedure (e: in out Element); > > procedure empty(s: in out Set); > procedure insert(e: in Element; s: in out Set); > procedure remove(e: in Element; s: in out Set); > > procedure look(lookp: in LookProcedure; s: in Set); > procedure map(mapp: in MapProcedure; s: in Set); [...] > I use the following for instantiation of this package. > > type Node is abstract new Component with private; > type NodeClassAccess is access all Node'Class; > > package NodeClassAccessSets is new CNAda.Utils.Sets(NodeClassAccess); > > NodeClassAccessSets.Set is a component within another tagged (record) > type - a Net. > There are various derived types of Node like Transition, Place and > further Operation, Socket, Port and so on.... > > I want to apply a LookProcedure on the set for example to > print all elements of this set. There is a primitive operation print > defined on the types within the hierarchy: > > procedure print(n: access Node) is abstract; > procedure print(t: access Transition); > procedure print(p: access Place); > > ...and so on. I want the system to dispatch to the most special variant > of the procedure for the apropriate derived type like: > > NodeClassAccessSets.look(print'Access, s); > > It is clearly possible to pass in a NodeClassAccess variable with any > derived *ClassAccess value into a print procedure defined as above even if > the print procedure was not overridden by the new derived type. > The system would always dispatch the most special case, am I right? No, Element is of NodeClassAccess which is different from anonymous "access Node" (that will dispatch). Thus LookProcedure.all is not dispatching at all. However it will be sort of "class-wide" when NodeClassAccess is class-wide, as it is. So you practically have everything to make it working. Just define a wrapper in the same package, where Node is defined: procedure Print_Any (Ptr : NodeClassAccess) is begin Print (Ptr); -- Dispatches end Print_Any; Then NodeClassAccessSets.look (Print_Any'Access, s); should work as expected. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: automatic tag conversion? 2003-05-26 8:29 ` Dmitry A. Kazakov @ 2003-05-26 18:16 ` Georg Bauhaus 2003-05-26 18:27 ` Georg Bauhaus 0 siblings, 1 reply; 8+ messages in thread From: Georg Bauhaus @ 2003-05-26 18:16 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: :> The system would always dispatch the most special case, am I right? : : No, Element is of NodeClassAccess which is different from anonymous "access : Node" (that will dispatch). Thus LookProcedure.all is not dispatching at : all. However it will be sort of "class-wide" when NodeClassAccess is : class-wide, as it is. So you practically have everything to make it : working. Just define a wrapper in the same package, where Node is defined: : : procedure Print_Any (Ptr : NodeClassAccess) is : begin : Print (Ptr); -- Dispatches : end Print_Any; Yes. I've made something similar, using a slightly modified set with a generic "look" function, generic with procedure accessor(e: in Element); procedure look(s: in Set); (and also deriving Node from a Printable abstract tagged type, type Printable is abstract tagged private; procedure print(p: access Printable) is abstract; ) Maybe both the Booch components and the Charles library might provide some ideas (in addition to code :) of how iteration can be done. The slight change results in with Sets; with nodes; use nodes; procedure run is -- testing package Node_Sets is new Sets(Element => Node_ptr); net: Node_sets.Set; procedure print_any(n: Node_ptr) is begin print(n.all'access); end print_any; procedure print_all is new node_sets.look(accessor => print_any); begin node_sets.insert(new Transition, net); node_sets.insert(new Place, net); node_sets.insert(new Transition, net); node_sets.insert(new Transition, net); print_all(net); end run; $ ./run a transition a transition a place a transition $ Georg ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: automatic tag conversion? 2003-05-26 18:16 ` Georg Bauhaus @ 2003-05-26 18:27 ` Georg Bauhaus 2003-05-26 20:49 ` Stephan Heinemann 0 siblings, 1 reply; 8+ messages in thread From: Georg Bauhaus @ 2003-05-26 18:27 UTC (permalink / raw) Georg Bauhaus <sb463ba@d2-hrz.uni-duisburg.de> wrote: : : procedure print_any(n: Node_ptr) is : begin : print(n.all'access); : end print_any; That should be print(n); : procedure print_all is : new node_sets.look(accessor => print_any); : : begin : node_sets.insert(new Transition, net); : node_sets.insert(new Place, net); And maybe: (Hyperway derived from Transition, not overriding print) node_sets.insert(new Hyperway, net); : node_sets.insert(new Transition, net); : print_all(net); : end run; Still: : $ ./run : a transition : a transition : a place : a transition : $ ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: automatic tag conversion? 2003-05-26 18:27 ` Georg Bauhaus @ 2003-05-26 20:49 ` Stephan Heinemann 0 siblings, 0 replies; 8+ messages in thread From: Stephan Heinemann @ 2003-05-26 20:49 UTC (permalink / raw) Thank you Dmitry and Georg! That was exactly what I needed. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2003-05-26 20:49 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2003-05-23 23:04 automatic tag conversion? Stephan Heinemann 2003-05-23 23:57 ` Stephan Heinemann 2003-05-24 17:39 ` Georg Bauhaus 2003-05-25 20:59 ` Stephan Heinemann 2003-05-26 8:29 ` Dmitry A. Kazakov 2003-05-26 18:16 ` Georg Bauhaus 2003-05-26 18:27 ` Georg Bauhaus 2003-05-26 20:49 ` Stephan Heinemann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox