* Newbie question -- dereferencing access @ 2009-03-11 20:26 Tim Rowe 2009-03-11 20:46 ` Ludovic Brenta 0 siblings, 1 reply; 30+ messages in thread From: Tim Rowe @ 2009-03-11 20:26 UTC (permalink / raw) If I have an access variable, for example: s: access string := new String'("Foo"); is there an easy way to assign from s to a string variable? Obviously I can't assign it directly, because access string is not string, so how do I convert? Everything I read says that dereferences happen automatically, but in this situation! TIA ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-11 20:26 Newbie question -- dereferencing access Tim Rowe @ 2009-03-11 20:46 ` Ludovic Brenta 2009-03-12 9:57 ` Tim Rowe 0 siblings, 1 reply; 30+ messages in thread From: Ludovic Brenta @ 2009-03-11 20:46 UTC (permalink / raw) On Mar 11, 9:26 pm, Tim Rowe <spamt...@tgrowe.plus.net> wrote: > If I have an access variable, for example: > s: access string := new String'("Foo"); > is there an easy way to assign from s to a string variable? Obviously I > can't assign it directly, because access string is not string, so how do > I convert? Everything I read says that dereferences happen > automatically, but in this situation! Copy_Of_S : String := s.all; This also works when passing parameters, e.g. procedure P (Str : in String) is null; begin P (s.all); -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-11 20:46 ` Ludovic Brenta @ 2009-03-12 9:57 ` Tim Rowe 2009-03-12 10:16 ` Ludovic Brenta ` (3 more replies) 0 siblings, 4 replies; 30+ messages in thread From: Tim Rowe @ 2009-03-12 9:57 UTC (permalink / raw) Ludovic Brenta wrote: > On Mar 11, 9:26 pm, Tim Rowe <spamt...@tgrowe.plus.net> wrote: >> If I have an access variable, for example: >> s: access string := new String'("Foo"); >> is there an easy way to assign from s to a string variable? Obviously I >> can't assign it directly, because access string is not string, so how do >> I convert? Everything I read says that dereferences happen >> automatically, but in this situation! > > Copy_Of_S : String := s.all; > > This also works when passing parameters, e.g. > > procedure P (Str : in String) is null; > begin > P (s.all); Perfect! Thanks. Can you (or anyone else) suggest a good book or online tutorial for an existing programmer, wanting to add Ada to his language portfolio? I have John Barnes "Programming in Ada 95", but I don't find his explanations very clear (and I couldn't find the answer to the question above), so if there's something better out there it might be worth me getting it. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-12 9:57 ` Tim Rowe @ 2009-03-12 10:16 ` Ludovic Brenta 2009-03-12 13:24 ` Tim Rowe 2009-03-12 12:13 ` christoph.grein ` (2 subsequent siblings) 3 siblings, 1 reply; 30+ messages in thread From: Ludovic Brenta @ 2009-03-12 10:16 UTC (permalink / raw) On Mar 12, 10:57 am, Tim Rowe <spamt...@tgrowe.plus.net> wrote: > Ludovic Brenta wrote: > > On Mar 11, 9:26 pm, Tim Rowe <spamt...@tgrowe.plus.net> wrote: > >> If I have an access variable, for example: > >> s: access string := new String'("Foo"); > >> is there an easy way to assign from s to a string variable? Obviously I > >> can't assign it directly, because access string is not string, so how do > >> I convert? Everything I read says that dereferences happen > >> automatically, but in this situation! > > > Copy_Of_S : String := s.all; > > > This also works when passing parameters, e.g. > > > procedure P (Str : in String) is null; > > begin > > P (s.all); > > Perfect! Thanks. > > Can you (or anyone else) suggest a good book or online tutorial for an > existing programmer, wanting to add Ada to his language portfolio? I > have John Barnes "Programming in Ada 95", but I don't find his > explanations very clear (and I couldn't find the answer to the question > above), so if there's something better out there it might be worth me > getting it. The Ada Programing wikibook has received a lot of praise and has a complete chapter discussing access types: http://en.wikibooks.org/wiki/Ada_Programming/Types/access See also the books and tutorials listed at http://www.adaic.com/learn/index.html -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-12 10:16 ` Ludovic Brenta @ 2009-03-12 13:24 ` Tim Rowe 0 siblings, 0 replies; 30+ messages in thread From: Tim Rowe @ 2009-03-12 13:24 UTC (permalink / raw) Ludovic Brenta wrote: > The Ada Programing wikibook has received a lot of praise and has a > complete chapter discussing access types: > > http://en.wikibooks.org/wiki/Ada_Programming/Types/access I'd looked at that. It looks as if it will be an invaluable reference once I know the language, but I don't see it as a tutorial. For example, on the page you reference, where does it explain what .all means? Where does it say that .all dereferences the access type? Presumably being a wikibook I could edit it, but I don't know enough about the language to do that and get it right. I've raised it on the comments page. > See also the books and tutorials listed at http://www.adaic.com/learn/index.html Ah, now /that/ looks promising! Thanks. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-12 9:57 ` Tim Rowe 2009-03-12 10:16 ` Ludovic Brenta @ 2009-03-12 12:13 ` christoph.grein 2009-03-12 13:00 ` Tim Rowe 2009-03-12 13:30 ` Ed Falis 2009-03-12 16:43 ` qunying 2009-03-12 18:21 ` Ivan Levashew 3 siblings, 2 replies; 30+ messages in thread From: christoph.grein @ 2009-03-12 12:13 UTC (permalink / raw) On Mar 12, 10:57 am, Tim Rowe <spamt...@tgrowe.plus.net> wrote: > ... I > have John Barnes "Programming in Ada 95", but I don't find his > explanations very clear (and I couldn't find the answer to the question > above), I have Barnes' "Programming in Ada 2005" and there is a "derefrencing" entry in the index; I would be very astonished if this wasn't also present in his older book. See the chapter about Access Types. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-12 12:13 ` christoph.grein @ 2009-03-12 13:00 ` Tim Rowe 2009-03-12 13:30 ` Ed Falis 1 sibling, 0 replies; 30+ messages in thread From: Tim Rowe @ 2009-03-12 13:00 UTC (permalink / raw) christoph.grein@eurocopter.com wrote: > I have Barnes' "Programming in Ada 2005" and there is a "derefrencing" > entry in the index; I would be very astonished if this wasn't also > present in his older book. See the chapter about Access Types. There is an entry for dereferencing in the Ada95 book, pointing to two pages. Dereferincing those pointers (!) I find that what both pages say about dereferencing is that it's automatic, unlike Pascal. I read the Access Types chapter a few times, but didn't find the idiom I needed or anything that would help me to find the idiom. Now I know what the answer is, I can see it in Barnes, so I can't say he didn't cover it, but the way he did it wasn't clear to this particular newbie! ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-12 12:13 ` christoph.grein 2009-03-12 13:00 ` Tim Rowe @ 2009-03-12 13:30 ` Ed Falis 2009-03-13 9:55 ` Tim Rowe 1 sibling, 1 reply; 30+ messages in thread From: Ed Falis @ 2009-03-12 13:30 UTC (permalink / raw) Try the books on this page: http://www.adaic.org/free/freebook.html Richard Riehle's "Ada Distilled" may be exactly what you're looking for, as it's aimed at experienced programmers. - Ed ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-12 13:30 ` Ed Falis @ 2009-03-13 9:55 ` Tim Rowe 2009-03-13 11:06 ` Alex R. Mosteo 2009-03-13 16:19 ` Martin 0 siblings, 2 replies; 30+ messages in thread From: Tim Rowe @ 2009-03-13 9:55 UTC (permalink / raw) Ed Falis wrote: > Try the books on this page: http://www.adaic.org/free/freebook.html > > Richard Riehle's "Ada Distilled" may be exactly what you're looking for, > as it's aimed at experienced programmers. Thanks. I am now working through "Ada Distilled". I'm a little nervous that it says "very little about Ada.Finalization, Storage Pool Management [...]" -- I hope the "very little" it says is enough for me to be able to use access types without memory leaks! I suppose I'll find out when I get there. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 9:55 ` Tim Rowe @ 2009-03-13 11:06 ` Alex R. Mosteo 2009-03-13 16:31 ` Tim Rowe 2009-03-13 16:50 ` Tim Rowe 2009-03-13 16:19 ` Martin 1 sibling, 2 replies; 30+ messages in thread From: Alex R. Mosteo @ 2009-03-13 11:06 UTC (permalink / raw) Tim Rowe wrote: > Ed Falis wrote: >> Try the books on this page: http://www.adaic.org/free/freebook.html >> >> Richard Riehle's "Ada Distilled" may be exactly what you're looking for, >> as it's aimed at experienced programmers. > > Thanks. I am now working through "Ada Distilled". I'm a little nervous > that it says "very little about Ada.Finalization, Storage Pool > Management [...]" -- I hope the "very little" it says is enough for me > to be able to use access types without memory leaks! I suppose I'll find > out when I get there. While these are certainly important skills, one thing you should notice when transitioning to Ada is a decreased need for access types thanks to unconstrained/indefinite types. I'd think that would mean that you're in the right track. It can depend on your particular application domain, of course. Anyway, if you have a sound knowledge of memory management in C/C++, it's pretty much the same. Don't forget to deallocate, wrap it all in a controlled type. Storage pools are quite exotic a need in my experience, specially for a newbie (with the possible exception of Gnat.Debug_Pools, and for that you only need the very basics). ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 11:06 ` Alex R. Mosteo @ 2009-03-13 16:31 ` Tim Rowe 2009-03-13 16:52 ` Georg Bauhaus ` (3 more replies) 2009-03-13 16:50 ` Tim Rowe 1 sibling, 4 replies; 30+ messages in thread From: Tim Rowe @ 2009-03-13 16:31 UTC (permalink / raw) To: Alex R. Mosteo Alex R. Mosteo wrote: > While these are certainly important skills, one thing you should notice when > transitioning to Ada is a decreased need for access types thanks to > unconstrained/indefinite types. I'd think that would mean that you're in the > right track. But I can't put an unconstrained type into a record. I realise that I can make the record discriminated and constrain the type on the discriminant, trying to write a class that gives strtok-like functionality -- the excercise I have set myself at the moment -- means that I discover the sizes of relevant strings rather late in the game. > Anyway, if you have a sound knowledge of memory management in C/C++, it's > pretty much the same. Don't forget to deallocate, wrap it all in a > controlled type. What I'm feeling the lack of is destructors for classes (sorry, for tagged records). I suspect I'll find what I need when I learn about finalizers, but whereas in C++ I learned about delete at the same time as I learned about new, and I learned about destructors at the same time as I learned about constructors, it seems strange in Ada to find access allocation addressed in the mainstream and access deallocation relegated to an advanced topic (and destructors nowhere in my sight). And yet it's C/C++ that has the reputation for memory leaks! ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 16:31 ` Tim Rowe @ 2009-03-13 16:52 ` Georg Bauhaus 2009-03-13 17:31 ` Tim Rowe 2009-03-13 16:52 ` Tim Rowe ` (2 subsequent siblings) 3 siblings, 1 reply; 30+ messages in thread From: Georg Bauhaus @ 2009-03-13 16:52 UTC (permalink / raw) Tim Rowe schrieb: > Alex R. Mosteo wrote: > But I can't put an unconstrained type into a record. Have you seen Bounded_String (and Unbounded_String)? > What I'm feeling the lack of is destructors for classes (sorry, for > tagged records). I suspect I'll find what I need when I learn about > finalizers, but whereas in C++ I learned about delete at the same time > as I learned about new, and I learned about destructors at the same time > as I learned about constructors, it seems strange in Ada to find access > allocation addressed in the mainstream and access deallocation relegated > to an advanced topic (and destructors nowhere in my sight). And yet it's > C/C++ that has the reputation for memory leaks! OK, but not every implementations requires programmer defined deallocation :-) Ada on the JVM delegates storage handling to the VM. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 16:52 ` Georg Bauhaus @ 2009-03-13 17:31 ` Tim Rowe 2009-03-13 18:18 ` Tim Rowe 0 siblings, 1 reply; 30+ messages in thread From: Tim Rowe @ 2009-03-13 17:31 UTC (permalink / raw) Georg Bauhaus wrote: > Tim Rowe schrieb: >> Alex R. Mosteo wrote: > >> But I can't put an unconstrained type into a record. > > Have you seen Bounded_String (and Unbounded_String)? Not yet, but I'll go and explore... > OK, but not every implementations requires programmer defined > deallocation :-) Ada on the JVM delegates storage handling > to the VM. And I understand that on .NET it delegates it to .NET. But I can't imagine Ada running on the JVM or .NET in the sorts of mission-critical applications with which Ada won its spurs! (Of course, those applications would avoid access types pretty thoroughly too, wouldn't they?) ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 17:31 ` Tim Rowe @ 2009-03-13 18:18 ` Tim Rowe 2009-03-13 18:27 ` Pascal Obry 2009-03-13 18:46 ` Niklas Holsti 0 siblings, 2 replies; 30+ messages in thread From: Tim Rowe @ 2009-03-13 18:18 UTC (permalink / raw) Tim Rowe wrote: > Georg Bauhaus wrote: >> Tim Rowe schrieb: >>> Alex R. Mosteo wrote: >> >>> But I can't put an unconstrained type into a record. >> >> Have you seen Bounded_String (and Unbounded_String)? > > Not yet, but I'll go and explore... Ok, I've seen it now! Am I correct that the statement in the spec that "No storage associated with an Unbounded_String object shall be lost upon assignment or scope exit" means somebody else has done all the work of handling the underlying access types and I don't need to worry? I note that it does have a free method, but presumably that's just for early release before it goes out of scope. If I'm right then yes, I can completely eliminate access types in the code I've done on my exercise so far. Hurrah! ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 18:18 ` Tim Rowe @ 2009-03-13 18:27 ` Pascal Obry 2009-03-13 18:46 ` Niklas Holsti 1 sibling, 0 replies; 30+ messages in thread From: Pascal Obry @ 2009-03-13 18:27 UTC (permalink / raw) To: Tim Rowe Tim Rowe a �crit : > Ok, I've seen it now! Am I correct that the statement in the spec that > "No storage associated with an Unbounded_String object shall be lost > upon assignment or scope exit" means somebody else has done all the work > of handling the underlying access types and I don't need to worry? Exactly. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.net - http://v2p.fr.eu.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver keys.gnupg.net --recv-key F949BD3B ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 18:18 ` Tim Rowe 2009-03-13 18:27 ` Pascal Obry @ 2009-03-13 18:46 ` Niklas Holsti 2009-03-13 21:38 ` Tim Rowe 1 sibling, 1 reply; 30+ messages in thread From: Niklas Holsti @ 2009-03-13 18:46 UTC (permalink / raw) Tim Rowe wrote: > Tim Rowe wrote: > >> Georg Bauhaus wrote: >> >>> Tim Rowe schrieb: >>> >>>> Alex R. Mosteo wrote: >>> >>> >>>> But I can't put an unconstrained type into a record. >>> >>> >>> Have you seen Bounded_String (and Unbounded_String)? >> >> >> Not yet, but I'll go and explore... > > > > Ok, I've seen it now! Am I correct that the statement in the > spec that "No storage associated with an Unbounded_String object > shall be lost upon assignment or scope exit" means somebody else > has done all the work of handling the underlying access types > and I don't need to worry? That is the intent, yes, as Pascal Obry already replied. > I note that it does have a free method, but presumably that's just for > early release before it goes out of scope. There could be such a method for Unbounded_String, but actually the Free procedure in Ada.Strings.Unbounded works on the type String_Access, which is just an access to an ordinary fixed-length String (assumed to be dynamically allocated if Free is used). I have often used Unbounded_String but never that procedure Free or the String_Access type. They have no public connection to Unbounded_String; probably they are declared in Ada.Strings.Unbounded just because the private implementations of Unbounded_String commonly use them, and the language designers thought that they might as well be public in case somebody finds them useful for other purposes. If I wanted to discard the storage of an Unbounded_String variable S at some point in the program, before S goes out of scope, I would assign S := Null_Unbounded_String. This is likely to discard the storage for S, but I think the Ada standard does not guarantee that it happens at the assignment; it might happen later. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ . ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 18:46 ` Niklas Holsti @ 2009-03-13 21:38 ` Tim Rowe 2009-03-13 22:28 ` Per Sandberg 0 siblings, 1 reply; 30+ messages in thread From: Tim Rowe @ 2009-03-13 21:38 UTC (permalink / raw) Niklas Holsti wrote: > If I wanted to discard the storage of an Unbounded_String variable S at > some point in the program, before S goes out of scope, I would assign S > := Null_Unbounded_String. This is likely to discard the storage for S, > but I think the Ada standard does not guarantee that it happens at the > assignment; it might happen later. Much as I'm used to with Java and C#; thanks. I'd need to know if I were doing hard real time, but then if I don't know a maximum length for a string I couldn't show compliance with hard real time constraints anyway, could I? ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 21:38 ` Tim Rowe @ 2009-03-13 22:28 ` Per Sandberg 0 siblings, 0 replies; 30+ messages in thread From: Per Sandberg @ 2009-03-13 22:28 UTC (permalink / raw) If maximum length of strings have impact on your timing it means that you are talking about nanoseconds and in that case many other things have much more impact on your timing such as context switches, critical regions, flushing of cashes in the CPU etc etc and on top of that brand of CPU, compiler as always (the language will of course help you specify your constraints but in the end reality hits). /Per Tim Rowe wrote: > Niklas Holsti wrote: > >> If I wanted to discard the storage of an Unbounded_String variable S >> at some point in the program, before S goes out of scope, I would >> assign S := Null_Unbounded_String. This is likely to discard the >> storage for S, but I think the Ada standard does not guarantee that it >> happens at the assignment; it might happen later. > > Much as I'm used to with Java and C#; thanks. I'd need to know if I were > doing hard real time, but then if I don't know a maximum length for a > string I couldn't show compliance with hard real time constraints > anyway, could I? ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 16:31 ` Tim Rowe 2009-03-13 16:52 ` Georg Bauhaus @ 2009-03-13 16:52 ` Tim Rowe 2009-03-13 17:33 ` Martin 2009-03-16 8:30 ` Alex R. Mosteo 3 siblings, 0 replies; 30+ messages in thread From: Tim Rowe @ 2009-03-13 16:52 UTC (permalink / raw) Sorry for the duplicates -- newsgroup reader problem :-( ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 16:31 ` Tim Rowe 2009-03-13 16:52 ` Georg Bauhaus 2009-03-13 16:52 ` Tim Rowe @ 2009-03-13 17:33 ` Martin 2009-03-14 7:30 ` sjw 2009-03-16 8:30 ` Alex R. Mosteo 3 siblings, 1 reply; 30+ messages in thread From: Martin @ 2009-03-13 17:33 UTC (permalink / raw) On Mar 13, 4:31 pm, Tim Rowe <spamt...@tgrowe.plus.net> wrote: > Alex R. Mosteo wrote: > > While these are certainly important skills, one thing you should notice when > > transitioning to Ada is a decreased need for access types thanks to > > unconstrained/indefinite types. I'd think that would mean that you're in the > > right track. > > But I can't put an unconstrained type into a record. I realise that I > can make the record discriminated and constrain the type on the > discriminant, trying to write a class that gives strtok-like > functionality -- the excercise I have set myself at the moment -- means > that I discover the sizes of relevant strings rather late in the game. > > > Anyway, if you have a sound knowledge of memory management in C/C++, it's > > pretty much the same. Don't forget to deallocate, wrap it all in a > > controlled type. > > What I'm feeling the lack of is destructors for classes (sorry, for > tagged records). I suspect I'll find what I need when I learn about > finalizers, but whereas in C++ I learned about delete at the same time > as I learned about new, and I learned about destructors at the same time > as I learned about constructors, it seems strange in Ada to find access > allocation addressed in the mainstream and access deallocation relegated > to an advanced topic (and destructors nowhere in my sight). And yet it's > C/C++ that has the reputation for memory leaks! This might help: It's my implementation of the "Ada1Z" package Ada.Containers.Indefinite_Holders (AI0069): File: a-coinho.ads -- The language-defined generic package Containers.Indefinite_Holders -- provides private type Holder and a set of operations for that type. A -- holder container holds a single element of an indefinite type. -- -- A holder containers allows the declaration of an object that can be used -- like an uninitialized variable or component of an indefinite type. -- -- A holder container may be *empty*. An empty holder does not contain an -- element. with Ada.Finalization; with Ada.Streams; generic type Element_Type (<>) is private; with function "=" (Left, Right : Element_Type) return Boolean is <>; -- The actual function for the generic formal function "=" on Element_Type -- values is expected to define a reflexive and symmetric relationship and -- return the same result value each time it is called with a particular -- pair of values. If it behaves in some other manner, the function "=" on -- holder values returns an unspecified value. The exact arguments and -- number of calls of this generic formal function by the function "=" on -- holder values are unspecified. -- -- AARM Ramification: If the actual function for "=" is not symmetric -- and consistent, the result returned by any of the functions defined -- to use "=" cannot be predicted. The implementation is not required -- to protect against "=" raising an exception, or returning random -- results, or any other "bad" behavior. And it can call "=" in -- whatever manner makes sense. But note that only the results of the -- function "=" is unspecified; other subprograms are not allowed to -- break if "=" is bad. package Ada.Containers.Indefinite_Holders is pragma Preelaborate (Indefinite_Holders); -- This package provides a "holder" of a definite type that contains a -- single value of an indefinite type. -- This allows one to effectively declare an uninitialized variable or -- component of an indefinite type. type Holder is tagged private; pragma Preelaborable_Initialization (Holder); -- The type Holder is used to represent holder containers. The type Holder -- needs finalization (see 7.6). Empty_Holder : constant Holder; -- Empty_Holder represents an empty holder object. If an object of type -- Holder is not otherwise initialized, it is initialized to the same -- value as Empty_Holder. function "=" (Left, Right : Holder) return Boolean; -- If Left and Right denote the same holder object, then the function -- returns True. -- Otherwise, it compares the element contained in Left to the element -- contained in Right using the generic formal equality operator, -- returning The Result of that operation. Any exception raised during -- the evaluation of element equality is propagated. function To_Holder (New_Item : Element_Type) return Holder; -- Returns a non-empty holder containing an element initialized to -- New_Item. function Is_Empty (Container : Holder) return Boolean; -- Returns True if the holder is empty, and False if it contains an -- element. procedure Clear (Container : in out Holder); -- Removes the element from Container. function Element (Container : Holder) return Element_Type; -- If Container is empty, Constraint_Error is propagated. -- Otherwise, returns the element stored in Container. procedure Replace_Element (Container : in out Holder; New_Item : Element_Type); -- Replace_Element assigns the value New_Item into Container, replacing -- any preexisting content of Container. Container is not empty -- after a successful call to Replace_Element. procedure Query_Element (Container : Holder; Process : not null access procedure (Element : Element_Type)); -- If Container is empty, Constraint_Error is propagated. -- Otherwise, Query_Element calls Process.all with the contained element -- as the argument. Program_Error is raised if Process.all tampers with -- the elements of Container. Any exception raised by Process.all is -- propagated. procedure Update_Element (Container : Holder; Process : not null access procedure (Element : in out Element_Type)); -- If Container is empty, Constraint_Error is propagated. -- Otherwise, Query_Element calls Process.all with the contained element -- as the argument. Program_Error is raised if Process.all tampers with -- the elements of Container. Any exception raised by Process.all is -- propagated. procedure Move (Target : in out Holder; Source : in out Holder); -- If Target denotes the same object as Source, then Move has no effect. -- Otherwise, the element contained by Source (if any) is removed from -- Source and inserted into Target, replacing any preexisting content. -- Source is empty after a successful call to Move. private type Element_Ptr is access Element_Type; type Holder is new Ada.Finalization.Controlled with record Contents : Element_Ptr := null; Busy : Natural := 0; end record; procedure Adjust (Container : in out Holder); procedure Finalize (Container : in out Holder); use Ada.Streams; procedure Write (Stream : access Root_Stream_Type'Class; Container : Holder); for Holder'Write use Write; procedure Read (Stream : access Root_Stream_Type'Class; Container : out Holder); for Holder'Read use Read; Empty_Holder : constant Holder := (Ada.Finalization.Controlled with others => <>); end Ada.Containers.Indefinite_Holders; File: a-coinho.adb with Ada.Unchecked_Deallocation; with System; package body Ada.Containers.Indefinite_Holders is procedure Free is new Ada.Unchecked_Deallocation (Element_Type, Element_Ptr); --------- -- "=" -- --------- function "=" (Left, Right : Holder) return Boolean is use type System.Address; begin if Left'Address = Right'Address then return True; end if; if Is_Empty (Left) then return Is_Empty (Right); else return not Is_Empty (Right) and then Left.Contents.all = Right.Contents.all; end if; end "="; --------------- -- To_Holder -- --------------- function To_Holder (New_Item : Element_Type) return Holder is begin return (Ada.Finalization.Controlled with Contents => new Element_Type'(New_Item), Busy => 0); end To_Holder; -------------- -- Is_Empty -- -------------- function Is_Empty (Container : Holder) return Boolean is begin return Container.Contents = null; end Is_Empty; ----------- -- Clear -- ----------- procedure Clear (Container : in out Holder) is begin if Container.Busy > 0 then raise Program_Error with "attempt to tamper with element (holder is busy)"; end if; if Container.Contents /= null then Free (Container.Contents); Container.Busy := 0; end if; end Clear; ------------- -- Element -- ------------- function Element (Container : Holder) return Element_Type is begin if Container.Contents = null then raise Constraint_Error with "Container has no element"; end if; return Container.Contents.all; end Element; --------------------- -- Replace_Element -- --------------------- procedure Replace_Element (Container : in out Holder; New_Item : Element_Type) is begin if Container.Busy > 0 then raise Program_Error with "attempt to tamper with element (holder is busy)"; end if; Clear (Container); Container.Contents := new Element_Type'(New_Item); end Replace_Element; ------------------- -- Query_Element -- ------------------- procedure Query_Element (Container : Holder; Process : not null access procedure (Element : Element_Type)) is H : Holder renames Container'Unrestricted_Access.all; B : Natural renames H.Busy; begin if Container.Contents = null then raise Constraint_Error with "Container has no element"; end if; B := B + 1; begin Process (Container.Contents.all); exception when others => B := B - 1; raise; end; B := B - 1; end Query_Element; -------------------- -- Update_Element -- -------------------- procedure Update_Element (Container : Holder; Process : not null access procedure (Element : in out Element_Type)) is H : Holder renames Container'Unrestricted_Access.all; B : Natural renames H.Busy; begin if Container.Contents = null then raise Constraint_Error with "Container has no element"; end if; B := B + 1; begin Process (Container.Contents.all); exception when others => B := B - 1; raise; end; B := B - 1; end Update_Element; ---------- -- Move -- ---------- procedure Move (Target : in out Holder; Source : in out Holder) is begin if Target.Busy > 0 then raise Program_Error with "attempt to tamper with elements (Target is busy)"; end if; if Source.Busy > 0 then raise Program_Error with "attempt to tamper with elements (Source is busy)"; end if; if Target.Contents /= Source.Contents then Clear (Target); Target.Contents := Source.Contents; Source.Contents := null; end if; end Move; ------------ -- Adjust -- ------------ procedure Adjust (Container : in out Holder) is begin if Container.Contents /= null then Container.Contents := new Element_Type'(Container.Contents.all); Container.Busy := 0; end if; end Adjust; -------------- -- Finalize -- -------------- procedure Finalize (Container : in out Holder) is begin if Container.Busy > 0 then raise Program_Error with "attempt to tamper with element (holder is busy)"; end if; if Container.Contents /= null then Free (Container.Contents); Container.Busy := 0; end if; end Finalize; ----------- -- Write -- ----------- procedure Write (Stream : access Root_Stream_Type'Class; Container : Holder) is Is_Present : constant Boolean := Container.Contents /= null; begin Boolean'Write (Stream, Is_Present); if Is_Present then Element_Type'Output (Stream, Container.Contents.all); end if; end Write; ---------- -- Read -- ---------- procedure Read (Stream : access Root_Stream_Type'Class; Container : out Holder) is Is_Present : Boolean := Boolean'Input(Stream); begin Clear (Container); if Is_Present then Container.Contents := new Element_Type'(Element_Type'Input (Stream)); end if; end Read; end Ada.Containers.Indefinite_Holders; Usual caveats about no warrenties, etc. but other than that use as you see fit! :-) Here's a (very) small test / demo: File: test_ai05_0068.adb --pragma Warnings (Off); with Ada.Containers.Indefinite_Holders; --pragma Warnings (On); with Ada.Exceptions; with Ada.Text_IO; procedure Test_AI05_0069 is package String_Holders is new Ada.Containers.Indefinite_Holders (String); My_String : String_Holders.Holder := String_Holders.To_Holder ("Hello World!"); procedure Test_Query is procedure Do_Something (Element : String) is begin My_String.Clear; end Do_Something; begin My_String.Query_Element (Do_Something'Access); exception when E : Program_Error => Ada.Text_Io.Put_Line ("Caught exception [" & Ada.Exceptions.Exception_Name (E) & "] with message [" & Ada.Exceptions.Exception_Message (E) & "]"); end Test_Query; procedure Test_Update is procedure Do_Something (Element : in out String) is begin My_String.Clear; Element := "asdasdas"; end Do_Something; begin My_String.Update_Element (Do_Something'Access); exception when E : Program_Error => Ada.Text_Io.Put_Line ("Caught exception [" & Ada.Exceptions.Exception_Name (E) & "] with message [" & Ada.Exceptions.Exception_Message (E) & "]"); end Test_Update; procedure Test_Move is My_Other_String : String_Holders.Holder := String_Holders.To_Holder ("s"); begin Ada.Text_IO.Put_Line ("Source = [" & My_String.Element & "]"); Ada.Text_IO.Put_Line ("Target = [" & My_Other_String.Element & "]"); String_Holders.Move (Source => My_String, Target => My_Other_String); begin Ada.Text_Io.Put_Line ("Source = [" & My_String.Element & "]"); exception when E : Constraint_Error => Ada.Text_Io.Put_Line ("Caught exception [" & Ada.Exceptions.Exception_Name (E) & "] with message [" & Ada.Exceptions.Exception_Message (E) & "]"); end; Ada.Text_IO.Put_Line ("Target = [" & My_Other_String.Element & "]"); end Test_Move; type A_Record is record Component : String_Holders.Holder; end record; My_Record : A_Record; begin Ada.Text_IO.Put_Line ("Is_Empty = " & Boolean'Image (My_String.Is_Empty)); My_String.Query_Element (Process => Ada.Text_IO.Put_Line'Access); Ada.Text_IO.Put_Line ("Element = [" & My_String.Element & "]"); My_String.Replace_Element ("Wibble"); My_String.Query_Element (Process => Ada.Text_Io.Put_Line'Access); Ada.Text_IO.Put_Line ("Element = [" & My_String.Element & "]"); My_String.Clear; Ada.Text_Io.Put_Line ("Is_Empty = " & Boolean'Image (My_String.Is_Empty)); begin Ada.Text_Io.Put_Line ("Element = [" & My_String.Element & "]"); Ada.Text_Io.Put_Line ("*** Should have raised exception"); exception when E : Constraint_Error => Ada.Text_Io.Put_Line ("Caught exception [" & Ada.Exceptions.Exception_Name (E) & "] with message [" & Ada.Exceptions.Exception_Message (E) & "]"); end; My_String.Replace_Element ("Wibble again"); Test_Query; Test_Update; Test_Move; exception when E : others => Ada.Text_Io.Put_Line ("Caught unexpected exception [" & Ada.Exceptions.Exception_Name (E) & "] with message [" & Ada.Exceptions.Exception_Message (E) & "]"); end Test_AI05_0069; Remember to include a '-a' options when you build it with GNAT. Cheers -- Martin ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 17:33 ` Martin @ 2009-03-14 7:30 ` sjw 2009-03-14 7:45 ` sjw 2009-03-14 9:21 ` Martin 0 siblings, 2 replies; 30+ messages in thread From: sjw @ 2009-03-14 7:30 UTC (permalink / raw) On Mar 13, 5:33 pm, Martin <martin.do...@btopenworld.com> wrote: [...] The comment on Update_Element isn't right! Not sure I completely catch the purpose here, will explore, but an alternative solution for storage management problems might be a smart pointer package; there are lots out there, eg BC.Support.Smart_Pointers in the Booch Components at http://sourceforge.net/projects/booch95/. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-14 7:30 ` sjw @ 2009-03-14 7:45 ` sjw 2009-03-14 9:21 ` Martin 1 sibling, 0 replies; 30+ messages in thread From: sjw @ 2009-03-14 7:45 UTC (permalink / raw) On Mar 14, 7:30 am, sjw <simon.j.wri...@mac.com> wrote: > On Mar 13, 5:33 pm, Martin <martin.do...@btopenworld.com> wrote: > [...] > > The comment on Update_Element isn't right! > > Not sure I completely catch the purpose here, will explore, but an > alternative solution for storage management problems might be a smart > pointer package; there are lots out there, eg > BC.Support.Smart_Pointers in the Booch Components at > http://sourceforge.net/projects/booch95/. Rather closer - BC.Support.Indefinite_Reference (might change the name to Indefinite_Holder in flattery!) ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-14 7:30 ` sjw 2009-03-14 7:45 ` sjw @ 2009-03-14 9:21 ` Martin 2009-03-23 8:43 ` Martin 1 sibling, 1 reply; 30+ messages in thread From: Martin @ 2009-03-14 9:21 UTC (permalink / raw) On Mar 14, 7:30 am, sjw <simon.j.wri...@mac.com> wrote: > On Mar 13, 5:33 pm, Martin <martin.do...@btopenworld.com> wrote: > [...] > > The comment on Update_Element isn't right! Oops! Thanks for the spot! > Not sure I completely catch the purpose here, will explore, but an > alternative solution for storage management problems might be a smart > pointer package; there are lots out there, eg > BC.Support.Smart_Pointers in the Booch Components athttp://sourceforge.net/projects/booch95/. The purposes are: 1) to allow indefinite types to be held in other composite types; 2) to do the memory management for the user; and 3) to spot 'meddling' with what is being held when there shouldn't be, i.e. it's a safe as well as smart holder. Cheers -- Martin ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-14 9:21 ` Martin @ 2009-03-23 8:43 ` Martin 0 siblings, 0 replies; 30+ messages in thread From: Martin @ 2009-03-23 8:43 UTC (permalink / raw) On 14 Mar, 09:21, Martin <martin.do...@btopenworld.com> wrote: > On Mar 14, 7:30 am, sjw <simon.j.wri...@mac.com> wrote: > > > On Mar 13, 5:33 pm, Martin <martin.do...@btopenworld.com> wrote: > > [...] > > > The comment on Update_Element isn't right! > > Oops! Thanks for the spot! I don't feel quite so bad about this now...just checked out the draft "Ada1Z" over at adaic.org and it's there too! :-) I'll let Randy know... Cheers -- Martin ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 16:31 ` Tim Rowe ` (2 preceding siblings ...) 2009-03-13 17:33 ` Martin @ 2009-03-16 8:30 ` Alex R. Mosteo 3 siblings, 0 replies; 30+ messages in thread From: Alex R. Mosteo @ 2009-03-16 8:30 UTC (permalink / raw) Tim Rowe wrote: > Alex R. Mosteo wrote: > >> While these are certainly important skills, one thing you should notice >> when transitioning to Ada is a decreased need for access types thanks to >> unconstrained/indefinite types. I'd think that would mean that you're in >> the right track. > > But I can't put an unconstrained type into a record. I realise that I > can make the record discriminated and constrain the type on the > discriminant, trying to write a class that gives strtok-like > functionality -- the excercise I have set myself at the moment -- means > that I discover the sizes of relevant strings rather late in the game. I was only slightly concerned by your initial example of access String, which are very rarely needed. It is unfortunate that they tend to appear in examples of arrays of strings of different length, though, in not very advanced tutorials. I think you've already discovered the predefined string packages. >> Anyway, if you have a sound knowledge of memory management in C/C++, it's >> pretty much the same. Don't forget to deallocate, wrap it all in a >> controlled type. > > What I'm feeling the lack of is destructors for classes (sorry, for > tagged records). I suspect I'll find what I need when I learn about > finalizers, but whereas in C++ I learned about delete at the same time > as I learned about new, and I learned about destructors at the same time > as I learned about constructors, it seems strange in Ada to find access > allocation addressed in the mainstream and access deallocation relegated > to an advanced topic (and destructors nowhere in my sight). And yet it's > C/C++ that has the reputation for memory leaks! It may be a bit puzzling in the very beginning, when you don't yet have all the pieces, but really all these topics tend to appear fairly soon. I don't remember that Unchecked_Deallocation received a comparably smaller attention than "new" in my formation. However, with the need for instantiation and the strange long name, it was stressed that the need for access types should be carefully studied. Finalization OTOH tends to be thrown in the lot of object oriented programming, which may be the reason you haven't seen it yet. However, Finalization is by no means an advanced topic and you'll find it very soon, I'd expect. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 11:06 ` Alex R. Mosteo 2009-03-13 16:31 ` Tim Rowe @ 2009-03-13 16:50 ` Tim Rowe 1 sibling, 0 replies; 30+ messages in thread From: Tim Rowe @ 2009-03-13 16:50 UTC (permalink / raw) To: Alex R. Mosteo Alex R. Mosteo wrote: > While these are certainly important skills, one thing you should notice when > transitioning to Ada is a decreased need for access types thanks to > unconstrained/indefinite types. I'd think that would mean that you're in the > right track. But I can't put an unconstrained type into a record. I realise that I can make the record discriminated and constrain the type on the discriminant, trying to write a class that gives strtok-like functionality -- the excercise I have set myself at the moment -- means that I discover the sizes of relevant strings rather late in the game. > Anyway, if you have a sound knowledge of memory management in C/C++, it's > pretty much the same. Don't forget to deallocate, wrap it all in a > controlled type. What I'm feeling the lack of is destructors for classes (sorry, for tagged records). I suspect I'll find what I need when I learn about finalizers, but whereas in C++ I learned about delete at the same time as I learned about new, and I learned about destructors at the same time as I learned about constructors, it seems strange in Ada to find access allocation addressed in the mainstream and access deallocation relegated to an advanced topic (and destructors nowhere in my sight). And yet it's C/C++ that has the reputation for memory leaks! ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-13 9:55 ` Tim Rowe 2009-03-13 11:06 ` Alex R. Mosteo @ 2009-03-13 16:19 ` Martin 1 sibling, 0 replies; 30+ messages in thread From: Martin @ 2009-03-13 16:19 UTC (permalink / raw) On Mar 13, 9:55 am, Tim Rowe <spamt...@tgrowe.plus.net> wrote: > Ed Falis wrote: > > Try the books on this page:http://www.adaic.org/free/freebook.html > > > Richard Riehle's "Ada Distilled" may be exactly what you're looking for, > > as it's aimed at experienced programmers. > > Thanks. I am now working through "Ada Distilled". I'm a little nervous > that it says "very little about Ada.Finalization, Storage Pool > Management [...]" -- I hope the "very little" it says is enough for me > to be able to use access types without memory leaks! I suppose I'll find > out when I get there. You may find that you simply don't need to use access types by using the Ada.Containers.* packages. Not forgetting the Ada.Strings.* packages too. I can't remember off hand when I last resorted to using an access type... Cheers -- Martin ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-12 9:57 ` Tim Rowe 2009-03-12 10:16 ` Ludovic Brenta 2009-03-12 12:13 ` christoph.grein @ 2009-03-12 16:43 ` qunying 2009-03-12 18:21 ` Ivan Levashew 3 siblings, 0 replies; 30+ messages in thread From: qunying @ 2009-03-12 16:43 UTC (permalink / raw) My first Ada tutorial were using the program at: http://www.adatutor.com/ I found it quite easy to follow. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-12 9:57 ` Tim Rowe ` (2 preceding siblings ...) 2009-03-12 16:43 ` qunying @ 2009-03-12 18:21 ` Ivan Levashew 2009-03-13 5:59 ` christoph.grein 3 siblings, 1 reply; 30+ messages in thread From: Ivan Levashew @ 2009-03-12 18:21 UTC (permalink / raw) Tim Rowe wrote: > > Can you (or anyone else) suggest a good book or online tutorial for an > existing programmer, wanting to add Ada to his language portfolio? I suggest http://www.adahome.com/Ammo/cpp2ada.html But be careful with adahome.com : http://groups.google.com/groups?threadm=hDsIj.36771%24J41.10422%40newssvr14.news.prodigy.net -- If you want to get to the top, you have to start at the bottom ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: Newbie question -- dereferencing access 2009-03-12 18:21 ` Ivan Levashew @ 2009-03-13 5:59 ` christoph.grein 0 siblings, 0 replies; 30+ messages in thread From: christoph.grein @ 2009-03-13 5:59 UTC (permalink / raw) On Mar 12, 7:21 pm, Ivan Levashew <octag...@bluebottle.com> wrote: > I suggest http://www.adahome.com/Ammo/cpp2ada.html Be careful - there are some mistakes, so don't be surprised if the compiler complains on some examples. ^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2009-03-23 8:43 UTC | newest] Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2009-03-11 20:26 Newbie question -- dereferencing access Tim Rowe 2009-03-11 20:46 ` Ludovic Brenta 2009-03-12 9:57 ` Tim Rowe 2009-03-12 10:16 ` Ludovic Brenta 2009-03-12 13:24 ` Tim Rowe 2009-03-12 12:13 ` christoph.grein 2009-03-12 13:00 ` Tim Rowe 2009-03-12 13:30 ` Ed Falis 2009-03-13 9:55 ` Tim Rowe 2009-03-13 11:06 ` Alex R. Mosteo 2009-03-13 16:31 ` Tim Rowe 2009-03-13 16:52 ` Georg Bauhaus 2009-03-13 17:31 ` Tim Rowe 2009-03-13 18:18 ` Tim Rowe 2009-03-13 18:27 ` Pascal Obry 2009-03-13 18:46 ` Niklas Holsti 2009-03-13 21:38 ` Tim Rowe 2009-03-13 22:28 ` Per Sandberg 2009-03-13 16:52 ` Tim Rowe 2009-03-13 17:33 ` Martin 2009-03-14 7:30 ` sjw 2009-03-14 7:45 ` sjw 2009-03-14 9:21 ` Martin 2009-03-23 8:43 ` Martin 2009-03-16 8:30 ` Alex R. Mosteo 2009-03-13 16:50 ` Tim Rowe 2009-03-13 16:19 ` Martin 2009-03-12 16:43 ` qunying 2009-03-12 18:21 ` Ivan Levashew 2009-03-13 5:59 ` christoph.grein
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox