comp.lang.ada
 help / color / mirror / Atom feed
* 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  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 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 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  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

* 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  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-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 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 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: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: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 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: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 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-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-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

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