comp.lang.ada
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* Re: Ada and Unicode
  2023-03-31  3:06  4%               ` Thomas
@ 2023-04-01 10:18  0%                 ` Randy Brukardt
  0 siblings, 0 replies; 73+ results
From: Randy Brukardt @ 2023-04-01 10:18 UTC (permalink / raw)


I'm not going to answer this point-by-point, as it would take very much too 
long, and there is a similar thread going on the ARG's Github (which needs 
my attention more than comp.lang.ada.

But my opinion is that Ada got strings completely wrong, and the best thing 
to do with them is to completely nuke them and start over. But one cannot do 
that in the context of Ada, one would have to at least leave way to use the 
old mechanisms for compatibility with older code. That would leave a 
hodge-podge of mechanisms that would make Ada very much harder (rather than 
easier) to use.

As far as the cruft goes, I wrote up a 20+ page document on that during the 
pandemic, but I could never interest anyone knowledgeable to review it, and 
I don't plan to make it available without that. Most of the things are 
caused by interactions -- mostly because of too much generality. And of 
course there are features that Ada would be better off without (like 
anonymous access types).

                          Randy.

"Thomas" <fantome.forums.tDeContes@free.fr.invalid> wrote in message 
news:64264e2f$0$25952$426a74cc@news.free.fr...
> In article <t2g0c1$eou$1@dont-email.me>,
> "Randy Brukardt" <randy@rrsoftware.com> wrote:
>
>> "Thomas" <fantome.forums.tDeContes@free.fr.invalid> wrote in message
>> news:fantome.forums.tDeContes-5E3B70.20370903042022@news.free.fr...
>> ...
>> > as i said to Vadim Godunko, i need to fill a string type with an UTF-8
>> > litteral.but i don't think this string type has to manage various
>> > conversions.
>> >
>> > from my point of view, each library has to accept 1 kind of string type
>> > (preferably UTF-8 everywhere),
>> > and then, this library has to make needed conversions regarding the
>> > underlying API. not the user.
>>
>> This certainly is a fine ivory tower solution,
>
> I like to think from an ivory tower,
> and then look at the reality to see what's possible to do or not. :-)
>
>
>
>> but it completely ignores two
>> practicalities in the case of Ada:
>>
>> (1) You need to replace almost all of the existing Ada language defined
>> packages to make this work. Things that are deeply embedded in both
>> implementations and programs (like Ada.Exceptions and Ada.Text_IO) would
>> have to change substantially. The result would essentially be a different
>> language, since the resulting libraries would not work with most existing
>> programs.
>
> - in Ada, of course we can't delete what's existing, and there are many
> packages which are already in 3 versions (S/WS/WWS).
> imho, it would be consistent to make a 4th version of them for a new
> UTF_8_String type.
>
> - in a new language close to Ada, it would not necessarily be a good
> idea to remove some of them, depending on industrial needs, to keep them
> with us.
>
>> They'd have to have different names (since if you used the same
>> names, you change the failures from compile-time to runtime -- or even
>> undetected -- which would be completely against the spirit of Ada), which
>> means that one would have to essentially start over learning and using 
>> the
>> resulting language.
>
> i think i don't understand.
>
>> (and it would make sense to use this point to
>> eliminate a lot of the cruft from the Ada design).
>
> could you give an example of cruft from the Ada design, please? :-)
>
>
>>
>> (2) One needs to be able to read and write data given whatever encoding 
>> the
>> project requires (that's often decided by outside forces, such as other
>> hardware or software that the project needs to interoperate with).
>
>> At a minimum, you
>> have to have a way to specify the encoding of files, streams, and 
>> hardware
>> interfaces
>
>> That will greatly complicate the interface and
>> implementation of the libraries.
>
> i don't think so.
> it's a matter of interfacing libraries, for the purpose of communicating
> with the outside (neither of internal libraries nor of the choice of the
> internal type for the implementation).
>
> Ada.Text_IO.Open.Form already allows (a part of?) this (on the content
> of the files, not on their name), see ARM A.10.2 (6-8).
> (write i the reference to ARM correctly?)
>
>
>
>>
>> > ... of course, it would be very nice to have a more thicker language 
>> > with
>> > a garbage collector ...
>>
>> I doubt that you will ever see that in the Ada family,
>
>> as analysis and
>> therefore determinism is a very important property for the language.
>
> I completely agree :-)
>
>> Ada has
>> lots of mechanisms for managing storage without directly doing it 
>> yourself
>> (by calling Unchecked_Deallocation), yet none of them use any garbage
>> collection in a traditional sense.
>
> sorry, i meant "garbage collector" in a generic sense, not in a
> traditional sense.
> that is, as Ada users we could program with pointers and pool, without
> memory leaks nor calling Unchecked_Deallocation.
>
> for example Ada.Containers.Indefinite_Holders.
>
> i already wrote one for constrained limited types.
> do you know if it's possible to do it for unconstrained limited types,
> like the class of a limited tagged type?
>
> -- 
> RAPID maintainer
> http://savannah.nongnu.org/projects/rapid/ 


^ permalink raw reply	[relevance 0%]

* Re: Ada and Unicode
  @ 2023-03-31  3:06  4%               ` Thomas
  2023-04-01 10:18  0%                 ` Randy Brukardt
  0 siblings, 1 reply; 73+ results
From: Thomas @ 2023-03-31  3:06 UTC (permalink / raw)


In article <t2g0c1$eou$1@dont-email.me>,
 "Randy Brukardt" <randy@rrsoftware.com> wrote:

> "Thomas" <fantome.forums.tDeContes@free.fr.invalid> wrote in message 
> news:fantome.forums.tDeContes-5E3B70.20370903042022@news.free.fr...
> ...
> > as i said to Vadim Godunko, i need to fill a string type with an UTF-8
> > litteral.but i don't think this string type has to manage various 
> > conversions.
> >
> > from my point of view, each library has to accept 1 kind of string type
> > (preferably UTF-8 everywhere),
> > and then, this library has to make needed conversions regarding the
> > underlying API. not the user.
> 
> This certainly is a fine ivory tower solution,

I like to think from an ivory tower, 
and then look at the reality to see what's possible to do or not. :-)



> but it completely ignores two 
> practicalities in the case of Ada:
> 
> (1) You need to replace almost all of the existing Ada language defined 
> packages to make this work. Things that are deeply embedded in both 
> implementations and programs (like Ada.Exceptions and Ada.Text_IO) would 
> have to change substantially. The result would essentially be a different 
> language, since the resulting libraries would not work with most existing 
> programs.

- in Ada, of course we can't delete what's existing, and there are many 
packages which are already in 3 versions (S/WS/WWS).
imho, it would be consistent to make a 4th version of them for a new 
UTF_8_String type.

- in a new language close to Ada, it would not necessarily be a good 
idea to remove some of them, depending on industrial needs, to keep them 
with us.

> They'd have to have different names (since if you used the same 
> names, you change the failures from compile-time to runtime -- or even 
> undetected -- which would be completely against the spirit of Ada), which 
> means that one would have to essentially start over learning and using the 
> resulting language.

i think i don't understand.

> (and it would make sense to use this point to 
> eliminate a lot of the cruft from the Ada design).

could you give an example of cruft from the Ada design, please? :-)


> 
> (2) One needs to be able to read and write data given whatever encoding the 
> project requires (that's often decided by outside forces, such as other 
> hardware or software that the project needs to interoperate with).

> At a minimum, you 
> have to have a way to specify the encoding of files, streams, and hardware 
> interfaces

> That will greatly complicate the interface and 
> implementation of the libraries.

i don't think so.
it's a matter of interfacing libraries, for the purpose of communicating 
with the outside (neither of internal libraries nor of the choice of the 
internal type for the implementation).

Ada.Text_IO.Open.Form already allows (a part of?) this (on the content 
of the files, not on their name), see ARM A.10.2 (6-8).
(write i the reference to ARM correctly?)



> 
> > ... of course, it would be very nice to have a more thicker language with 
> > a garbage collector ...
> 
> I doubt that you will ever see that in the Ada family,

> as analysis and 
> therefore determinism is a very important property for the language.

I completely agree :-)

> Ada has 
> lots of mechanisms for managing storage without directly doing it yourself 
> (by calling Unchecked_Deallocation), yet none of them use any garbage 
> collection in a traditional sense.

sorry, i meant "garbage collector" in a generic sense, not in a 
traditional sense.
that is, as Ada users we could program with pointers and pool, without 
memory leaks nor calling Unchecked_Deallocation.

for example Ada.Containers.Indefinite_Holders.

i already wrote one for constrained limited types.
do you know if it's possible to do it for unconstrained limited types, 
like the class of a limited tagged type?

-- 
RAPID maintainer
http://savannah.nongnu.org/projects/rapid/

^ permalink raw reply	[relevance 4%]

* Re: Unchecked_Deallocation with tagged types
  @ 2022-04-18  5:51  5%                   ` Thomas
  0 siblings, 0 replies; 73+ results
From: Thomas @ 2022-04-18  5:51 UTC (permalink / raw)


In article <s5naeu$r4c$1@gioia.aioe.org>,
 "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote:

> On 2021-04-20 20:53, Randy Brukardt wrote:
> 
> > OTOH, an Ada
> > follow-on would most likely have access types with automatic deallocation as
> > proposed by Tucker in one of the many AIs on ownership.

who is Tucker, and where can i read him, please? :-)

> > So using any form of
> > explicit deallocation would be discouraged (as would the use of raw pointer
> > types).
> 
> I do not understand how that could work, it sounds like a halting 
> problem to me,

i feel that:

1)
afaik, non-pool-specific access-to-variable types, which should point on 
aliased objects, are not dangerous, as long as neither new nor 
Unchecked_Deallocation are used.

2)
pool-specific access-to-variable types should mostly look like 
Ada.Containers.Indefinite_Holders.
there is missing one for definite limited types,
and i hope it's possible to also make it for indefinite limited types
(if it's not allowed in Ada, it should be planned for an Ada follow-on).


> but anyway, where is a problem? Add a whole new hierarchy 
> of access types independent on the existing one.

anyway, we can begin to think about it, and see later what it should 
become.
but if Tucker already begun to think about it, i would prefer read him 
before develop my own think, to avoid redo what he already did :-)

-- 
RAPID maintainer
http://savannah.nongnu.org/projects/rapid/

^ permalink raw reply	[relevance 5%]

* Re: Unchecked_Deallocation with tagged types
  @ 2022-04-18  1:51  6%                       ` Thomas
  0 siblings, 0 replies; 73+ results
From: Thomas @ 2022-04-18  1:51 UTC (permalink / raw)


In article <s5vpul$ldb$1@franka.jacob-sparre.dk>,
 "Randy Brukardt" <randy@rrsoftware.com> wrote:

> "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message 
> news:ie8uagFqaf2U1@mid.individual.net...
> > On 2021-04-20 23:32, Jeffrey R. Carter wrote:
> >> On 4/20/21 8:53 PM, Randy Brukardt wrote:
> >>>
> >>> 'Free makes more sense in a new language (an Ada follow-on).
> >>
> >> Right. I don't think it would be a good idea to add it to Ada.
> >>
> >> But I think a new language should not have pointers at all.
> >>
> >> No more radical than not having arrays.
> >
> > It seems to me that a language without arrays and pointers would be very 
> > difficult to use in an embedded, real-time, close-to-HW context. So we 
> > would lose the nice wide-spectrum nature of Ada.

i like "the nice wide-spectrum nature of Ada" :-)
If I got it right, it is the thickness*, that is, it goes both far in 
low level and far in high level.

* Natacha Porte, https://www.youtube.com/watch?v=b5lRyBRk0d8&t=430s 
(during 1:10 - sorry, it's only in french)


> 
> It's important that a new language have a way to interface to existing 
> hardware and software. So there has to be something that maps to C arrays 
> and pointers (and the equivalent for hardware). But that doesn't necessarily 
> have to be something that is used outside of interfacing. An Ada example is 
> Unchecked_Unions -- they exist for interfacing but shouldn't be used 
> otherwise.

i don't know much "exotic things" (for me) like embedded or real-time 
programming,
but i would not take the risk to exclude users who need low level in 
various cases (not only in interfaces),
so i think it would be better to keep a full thickness with the ability 
to go far in low level at any place it is considered usefull.

> A fixed vector type and a raw general access type would do the 
> trick, but those could be something that are almost never used outside of 
> interfacing packages.

an other point here, is the ability to create new structures that could 
be considered as "basic" later.

for example Ada.Containers.Multiway_Trees seems to be based on 
Ada.Containers.Doubly_Linked_Lists,
and i don't know if it could be needed / usefull to have trees based on 
Ada.Containers.Vectors,
but based on Ada.Containers.Ordered_Maps, certainly!

and sometimes using other high level data structures would be enough, 
but probably sometimes it would be non-optimal, and maybe, in the worst 
case, it could be impossible (especially in the event that we had not 
foreseen all the needed high level data structures)


so, i think:

- we could keep arrays as is, no matter if they are rarly used.

- for access types, it would be nice to find a kind of "controlled 
access type" that allows:
  - to access the "raw general access type", as low level type,
    when needed,
  - to need not Unchecked_Deallocation, making automatic Deallocation,
  - and which would not be too much high level
    (for example Ada.Containers.Indefinite_Holders is fine).

-- 
RAPID maintainer
http://savannah.nongnu.org/projects/rapid/

^ permalink raw reply	[relevance 6%]

* Re: GCC 11 bug? lawyer needed
  2021-05-06 20:02  7%         ` Simon Wright
  2021-05-06 20:51  0%           ` Dmitry A. Kazakov
@ 2021-05-06 23:59  0%           ` Randy Brukardt
  1 sibling, 0 replies; 73+ results
From: Randy Brukardt @ 2021-05-06 23:59 UTC (permalink / raw)


"Simon Wright" <simon@pushface.org> wrote in message 
news:lylf8ry6j5.fsf@pushface.org...
> "Randy Brukardt" <randy@rrsoftware.com> writes:
>
>> I agree that the original author of that program should not have used
>> "aliased" in the way that they did (they don't need the special 
>> semantics),
>> but we realize that some people would prefer to *explicitly* mark things 
>> as
>> aliased when they are going to take 'Access (and not worry about the type 
>> of
>> the parameter -- after all, it could change). That is, they don't want to
>> depend on the implicit behavior of tagged types -- or perhaps they don't
>> even know about it. Which leads to the problem that occurs here, as
>> "aliased" has slightly different meanings for functions (now just 
>> composite
>> functions) and procedures.
>
> The original code, from the Alire project, had (I've edited it slightly)
>
>   package Holders
>   is new Ada.Containers.Indefinite_Holders (Node'Class);
>
>   type Tree is
>     new Holders.Holder
>     and ...
>
>   function Root (This : Tree) return Node'Class is
>     (This.Constant_Reference);
>
> where that Constant_Reference is inherited (eventually) from
> Ada.Containers.Indefinite_Holders.Holder,
>
>   function Constant_Reference
>     (Container : aliased Holder) return Constant_Reference_Type;
>   pragma Inline (Constant_Reference);
>
> Shame it had to be there.

Constant_Reference is the case for which these semantics was designed. Hard 
to avoid it there. ;-)

Note that by returning Node'Class rather than an elementary type, you don't 
get to use the new rule tweak. Since all tagged types are by-reference (not 
by copy), the "Root" routine has to return the object that it has, which 
ultimately is part of Tree. So you actually need "aliased" on Root, since 
you are (ultimately) returning a part of the formal parameter (and which 
could become dangling if you pass in an object which is too local).

> I've just tried splattering 'aliased' wherever the compiler told me it
> was needed; it's now spreading into other packages. Ugh.

I think you need to make a copy of the return object somewhere; the obvious 
answer is to replace function Constant_Reference with function Element. Of 
course, if the return object is large enough, that could be expensive. (That 
doesn't work if you want to write the node, but the use of 
Constant_Reference doesn't allow that anyway, so in this case it doesn't 
matter.)

> The solution might just be using composition rather than inheritance.

Yeah, or using handles more as Dmitry says. In any case, it seems like some 
redesign is necessary.

                  Randy.


^ permalink raw reply	[relevance 0%]

* Re: GCC 11 bug? lawyer needed
  2021-05-06 20:02  7%         ` Simon Wright
@ 2021-05-06 20:51  0%           ` Dmitry A. Kazakov
  2021-05-06 23:59  0%           ` Randy Brukardt
  1 sibling, 0 replies; 73+ results
From: Dmitry A. Kazakov @ 2021-05-06 20:51 UTC (permalink / raw)


On 2021-05-06 22:02, Simon Wright wrote:
> "Randy Brukardt" <randy@rrsoftware.com> writes:
> 
>> I agree that the original author of that program should not have used
>> "aliased" in the way that they did (they don't need the special semantics),
>> but we realize that some people would prefer to *explicitly* mark things as
>> aliased when they are going to take 'Access (and not worry about the type of
>> the parameter -- after all, it could change). That is, they don't want to
>> depend on the implicit behavior of tagged types -- or perhaps they don't
>> even know about it. Which leads to the problem that occurs here, as
>> "aliased" has slightly different meanings for functions (now just composite
>> functions) and procedures.
> 
> The original code, from the Alire project, had (I've edited it slightly)
> 
>     package Holders
>     is new Ada.Containers.Indefinite_Holders (Node'Class);
> 
>     type Tree is
>       new Holders.Holder
>       and ...
> 
>     function Root (This : Tree) return Node'Class is
>       (This.Constant_Reference);
> 
> where that Constant_Reference is inherited (eventually) from
> Ada.Containers.Indefinite_Holders.Holder,
> 
>     function Constant_Reference
>       (Container : aliased Holder) return Constant_Reference_Type;
>     pragma Inline (Constant_Reference);
> 
> Shame it had to be there.
> 
> I've just tried splattering 'aliased' wherever the compiler told me it
> was needed; it's now spreading into other packages. Ugh.
> 
> The solution might just be using composition rather than inheritance.

In my experience mixing handles with target types does not work anyway 
regardless accessibility rules mess.

I tend to use interfaces instead:

    type Abstract_Node_Interface is interface ...;

Then both the handle and the target type implement 
Abstract_Node_Interface. The target type goes into hiding, the client 
need not to see it.

This requires manual delegation in all primitive operations of handles: 
dereference + call. But in the end it pays off. Especially with trees, 
because in mutator operations I can check the reference count of the 
node and choose to clone it (and maybe the subtree) if there are 
multiple external handles to it.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: GCC 11 bug? lawyer needed
  @ 2021-05-06 20:02  7%         ` Simon Wright
  2021-05-06 20:51  0%           ` Dmitry A. Kazakov
  2021-05-06 23:59  0%           ` Randy Brukardt
  0 siblings, 2 replies; 73+ results
From: Simon Wright @ 2021-05-06 20:02 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> I agree that the original author of that program should not have used 
> "aliased" in the way that they did (they don't need the special semantics), 
> but we realize that some people would prefer to *explicitly* mark things as 
> aliased when they are going to take 'Access (and not worry about the type of 
> the parameter -- after all, it could change). That is, they don't want to 
> depend on the implicit behavior of tagged types -- or perhaps they don't 
> even know about it. Which leads to the problem that occurs here, as 
> "aliased" has slightly different meanings for functions (now just composite 
> functions) and procedures.

The original code, from the Alire project, had (I've edited it slightly)

   package Holders
   is new Ada.Containers.Indefinite_Holders (Node'Class);

   type Tree is
     new Holders.Holder
     and ...

   function Root (This : Tree) return Node'Class is
     (This.Constant_Reference);

where that Constant_Reference is inherited (eventually) from
Ada.Containers.Indefinite_Holders.Holder,

   function Constant_Reference
     (Container : aliased Holder) return Constant_Reference_Type;
   pragma Inline (Constant_Reference);

Shame it had to be there.

I've just tried splattering 'aliased' wherever the compiler told me it
was needed; it's now spreading into other packages. Ugh.

The solution might just be using composition rather than inheritance.

^ permalink raw reply	[relevance 7%]

* Re: set_index and and end_of_file with just a stream reference
  @ 2021-02-23 17:21  5%           ` Shark8
  0 siblings, 0 replies; 73+ results
From: Shark8 @ 2021-02-23 17:21 UTC (permalink / raw)


On Saturday, February 20, 2021 at 12:08:16 PM UTC-7, 0012com wrote:
> Okay :-) 
> what I wanted is: 
> I read an acronyme in the stream file, if good I input the adjacent record type, otherwise I would advance on the stream until the next acronyme with set_index(stream_access, index(stream_access) + composite_type_stream_size) and read the next acronyme (unbounded_string). 
> Now I just input both objects and verify the acronyme. 
> But I don't like writing an object that maybe won't be used.
Hm, what are your datatypes? Is this ONLY text, or are you able to impose your own structure?
You could have something like this:

-- Instantiated Container Packages.
Package String_Holder is new Ada.Containers.Indefinite_Holders(
       Element_Type => String,
       "="          => Ada.Strings.Equal_Case_Insensitive
      );
Package String_Map is new Ada.Containers.Indefinite_Ordered_Maps(
       "<"          => Ada.Strings.Less_Case_Insensitive,
       "="          => Ada.Strings.Equal_Case_Insensitive,
       Key_Type     => String,
       Element_Type => String
      );

-- The heart of the operating program.
With String_Holder, String_Map;
Package Acronyms is
  -- Because this is it's own type, you can put other things in the record, like a link to the place that it's defined, if needed.
  Type Initialism is new String_Holder.Holder with null record;

  Function Expand( Acronym : Initialism ) return String;
  Procedure Register( Acronym, Expansion : String );
--...
End Acronyms;

Package Body Acronyms is
    Acronym_Map : String_Map.Map;
  Procedure Register( Acronym, Expansion : String ) is
  Begin
    Acronym_Map.Insert( New_Item => Expansion, Key => Acronym );
  End Register;  

  Function Expand( Acronym : Initialism ) return String is
  Begin
    Return Acronym_Map( Acronym );
  Exception
    when others => Return Acronym; -- I forget if it's CONSTRAINT_ERROR or ASSERT_ERROR when the element is not present.
  End Expand;
End Acronyms;

-- in your main Acronym-Stream package...
-- Text_Soup is a variant record for handling portions of an acronym-expanding string; your main data-structure would probably be an Indefinite_Vector of Text_Soup'Class,
-- you might not need Input or output, depending on your usage, but for automatically expanding the initialism you'd need to use Acronyms.Expand.

    Type Text_Soup(<>) is tagged private;
    procedure Output(
       Stream : not null access Ada.Streams.Root_Stream_Type'Class;
       Item   : in Text_Soup'Class);
    function Input(
       Stream : not null access Ada.Streams.Root_Stream_Type'Class)
       return Text_Soup'Class;

   -- Other public operations.
PRIVATE
    For Text_Soup'Class'Input  use Input;
    For Text_Soup'Class'Output use Output;

Type Text_Soup(Length : Natural) is record
  case Length is
    when 0 => Acronym : Initialism;
    when others => Text : String(1..Length);
  end case;
end record;
--...


^ permalink raw reply	[relevance 5%]

* Re: Proposal: Auto-allocation of Indefinite Objects
  @ 2020-07-27 20:31  6%     ` Jeffrey R. Carter
  0 siblings, 0 replies; 73+ results
From: Jeffrey R. Carter @ 2020-07-27 20:31 UTC (permalink / raw)


On 7/27/20 7:48 PM, Brian Drummond wrote:
> 
> Is there any way we could generalise the (storage, access and lifetime
> aspects of) Unbounded_String for unconstrained arrays and discriminated
> records in such a way that Unbounded_String can be a simple instantiation
> of one of these?

Ada.Strings.Unbounded can be considered a combination of 
Ada.Containers.Indefinite_Holders instantiated for String and 
Ada.Containers.Vectors instantiated with Positive and Character, with some 
additional operations added.

The To_String and To_Unbounded_String operations of Unbounded_String are similar 
to the Element and Replace_Element operations of Holder, which do not exist for 
Vector.

The indexed operations of Unbounded_String are similar to the indexed operations 
of Vector, which do not exist for Holder.

If Ada.Containers.Vectors had an additional generic formal type

    type Fixed is array (Index_Type range <>) of Element_Type;

and 2 new operations

    function To_Fixed (From : Vector) return Fixed;
    function To_Vector (From : Fixed) return Vector;

then we wouldn't need Ada.Strings.Unbounded.

-- 
Jeff Carter
"Blessed is just about anyone with a vested interest in the status quo."
Monty Python's Life of Brian
73

^ permalink raw reply	[relevance 6%]

* Re: GNAT vs Matlab - operation on   multidimensional complex matrices
  @ 2020-06-08 17:42  3% ` Shark8
  0 siblings, 0 replies; 73+ results
From: Shark8 @ 2020-06-08 17:42 UTC (permalink / raw)


Cleaning out my computer, I found this working-file; it might be of interesti to you -- it shows "going all-in" with Generics:
--------------------------------------------------------------
With
Ada.Real_Time,
Ada.Containers.Indefinite_Holders,
Ada.Numerics.Long_Complex_Types,
Ada.Exceptions,
Ada.Text_IO.Complex_IO;

Procedure Demo is
    package TIO renames Ada.Text_IO;
    package CTIO is new TIO.Complex_IO(Ada.Numerics.Long_Complex_Types);

    subtype mReal   is Long_Float;
    subtype Complex is Ada.Numerics.Long_Complex_Types.Complex;


    NumIteration : constant  := 1_000;
    NumChannels  : constant  := 64;
    NumRanges    : constant  := 400;
    NumAngles    : constant  := 30;


    Type Channel is range 1..NumChannels;
    Type Angle   is range 1..NumAngles;
    Type Range_T is range 1..NumRanges;

    type tCubeReal    is array (Channel, Angle, Range_T) of mReal;
    type tCubeComplex is array (Channel, Angle, Range_T) of Complex;

    Generic
        Type T is private;
        Type IndexA is (<>);
        Type IndexB is (<>);
        Type IndexC is (<>);
        Type Cubic is Array(IndexA, IndexB, indexC) of T;
        Zero : in T;
        with Function "+"(Left, Right: T) return T is <>;
    Function Summation( Input : Cubic ) return T
      with Inline;

    Function Summation( Input : Cubic ) return T is
    Begin
        Return Result : T := Zero do
            For A in IndexA loop
                For B in IndexB loop
                    For C in IndexC loop
                        Result:= Result + Input(A, B, C);
                    End loop;
                End loop;
            End loop;
        End return;
    End Summation;

    Generic
        Type Element is private;
        Type Cubic is array (Channel, Angle, Range_T) of Element;
        Zero : In Element;
        with Function "+"(Left, Right: Element) return Element is <>;
    Procedure Timing_Harness(Mtx : in Cubic;  S: out Element; Iterations : in Positive:= 1);

    Procedure Timing_Harness(Mtx : in Cubic;  S: out Element; Iterations : in Positive:= 1) is
        Function Sum is new Summation(Element, Channel, Angle, Range_T, Cubic, Zero);
        Use Ada.Real_Time;
        Start : Time renames Clock;
    Begin
        For Count in 1..Iterations Loop
            S := Sum( Mtx );
        End loop;


        METRICS:
        Declare
            Execution_Time  : Constant Time_Span:= Clock - Start;
            Execution_Image : Constant String:= Duration'Image(To_Duration(Execution_Time));
            T : Constant mReal := mReal(To_Duration(Execution_Time))/mReal(NumIteration);
        Begin
            TIO.New_Line;
            TIO.Put_Line("Computation time:" & Execution_Image );
            TIO.Put_Line("Computation time per iteration:" & mReal'Image(T));
        End METRICS;
    End Timing_Harness;


    Function Image( Input : mReal   )  return string renames mReal'Image;
    Function Image( Input : Complex )  return string is
        ('(' & mReal'Image(Input.Re) & ", " & mReal'Image(Input.Im) & ')');
    
    Generic
        Type T is private;
        Type IndexA is (<>);
        Type IndexB is (<>);
        Type IndexC is (<>);
        Type Cubic is Array(IndexA, IndexB, indexC) of T;
        Default : in T;
    Package Test_Data is
        Type Access_Cubic is not null access all Cubic;

        Access_Data : Constant Access_Cubic := new Cubic'(others => (others => (others => Default)));
        Data        : Cubic renames Access_Data.all;
    End Test_Data;

    Generic
        Type Element    is private;
        Type Cube_Array is array (Channel, Angle, Range_T) of Element;
        Default,
        Zero      : in Element;
        Test_Name : in String;
        with Function "+"(Left, Right: Element) return Element is <>;
        with Function Image( Input : Element )  return string  is <>;
    Procedure TEST;


    Procedure TEST is

        Package Test_Set is new Test_Data(
           T       => Element,
           IndexA  => Channel,
           IndexB  => Angle,
           IndexC  => Range_T,
           Cubic   => Cube_Array,
           Default => Default
          );
        
        procedure SpeedSum is new Timing_Harness(
           Element => Element,
           Cubic   => Cube_Array,
           Zero    => Zero,
           "+"     => TEST."+"
          );
        
        Cube   : Cube_Array renames Test_Set.Data;
        Result : Element;
    Begin
        TIO.Put_Line(Test_Name & " cube");
        TIO.Put_Line(Test_Name & " type size is:" & Integer'Image(Element'Size));

        SpeedSum(
           Mtx          => Cube,
           S            => Result,
           Iterations   => NumIteration
          );

        TIO.Put_Line("Sum is:" & Image(Result));
    End TEST;

Begin
    REAL_CUBE_TEST:
    Declare
        Procedure Do_Test is new Test(
           Element    => mReal,
           Cube_Array => tCubeReal,
           Default    => 1.0,
           Zero       => 0.0,
           Test_Name  => "Real"
          );
    Begin
        Do_Test;
    End REAL_CUBE_TEST;

    TIO.Put_Line( (1..20 => '-') ); -- Separator.

    COMPLEX_CUBE_TEST:
    Declare
        Procedure Do_Test is new Test(
           "+"        => Ada.Numerics.Long_Complex_Types."+",
           Element    => Complex,
           Cube_Array => tCubeComplex,
           Default    => (Re => 1.0, Im => 1.0),
           Zero       => (Re => 0.0, Im => 0.0),
           Test_Name  => "Complex"
          );
    Begin
        Do_Test;
    End COMPLEX_CUBE_TEST;



    TIO.Put_Line( (1..20 => '-') ); -- Separator.


    Ada.Text_IO.Put_Line( "Done." );
End Demo;

^ permalink raw reply	[relevance 3%]

* Re: Type naming conventions: Any_Foo
  2019-12-06 20:35  0%                 ` Dmitry A. Kazakov
@ 2019-12-07  0:57  0%                   ` Randy Brukardt
  0 siblings, 0 replies; 73+ results
From: Randy Brukardt @ 2019-12-07  0:57 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:qsee2v$par$1@gioia.aioe.org...
> On 2019-12-06 21:18, Jeffrey R. Carter wrote:
>> On 12/5/19 10:51 PM, Dmitry A. Kazakov wrote:
>>>
>>> Ada standard library uses _Type, e.g.
>>>
>>> generic
>>> type Element_Type (<>) is private;
>>> with function "=" (Left, Right : Element_Type) return Boolean is <>;
>>> package Ada.Containers.Indefinite_Holders
>>
>> Yes, and the ARM also includes such abominations as anonymous access 
>> types. Just because it's in the ARM doesn't mean it's the best way to do 
>> something. Element is be a better name for that formal type.
>
> No, it would be misleading. Element must be reserved for instances of the 
> type. They are actual elements. The type of an element is not an element, 
> these are two totally different things.

Agreed. Ada.Containers all have a function Element that retrieves a (copy 
of) a single element object from the container. If the type was named 
element, what would this function be called? Similarly, some of the 
parameters are called Element (thus, Element : Element_Type in many 
parameter lists); those also would need alternate names.

There were a number of ARG members that disliked the "_Type" notation, so we 
looked at alternatives. And we didn't find anything that worked as well. 
Sometimes, package design is about the "least bad" alternative.

                                     Randy.




>>> There are lots of cases in Ada, you certainly should know that. As a 
>>> practical example GtkAda declares all widget types twice:
>>>
>>> type Gtk_Button_Record is ...
>>> type Gtk_Button is access all Gtk_Button_Record'Class;
>>
>> No well designed library has public access types. You aren't required to 
>> use a library that does, and you aren't required to use access types.
>
> I am required to. There must be always be two types in a GUI, one 
> referential type and one implementation type. The widget implementation 
> object in GtkAda is Gtk_Button_Record. The widget referential object is 
> Gtk_Button. It could be a handle or a smart pointer type instead of plain 
> pointer, but there is no way to reduce it to a single type. So the problem 
> will persist.
>
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de 



^ permalink raw reply	[relevance 0%]

* Re: Type naming conventions: Any_Foo
  2019-12-06 20:18  0%               ` Jeffrey R. Carter
@ 2019-12-06 20:35  0%                 ` Dmitry A. Kazakov
  2019-12-07  0:57  0%                   ` Randy Brukardt
  0 siblings, 1 reply; 73+ results
From: Dmitry A. Kazakov @ 2019-12-06 20:35 UTC (permalink / raw)


On 2019-12-06 21:18, Jeffrey R. Carter wrote:
> On 12/5/19 10:51 PM, Dmitry A. Kazakov wrote:
>>
>> Ada standard library uses _Type, e.g.
>>
>> generic
>>     type Element_Type (<>) is private;
>>     with function "=" (Left, Right : Element_Type) return Boolean is <>;
>> package Ada.Containers.Indefinite_Holders
> 
> Yes, and the ARM also includes such abominations as anonymous access 
> types. Just because it's in the ARM doesn't mean it's the best way to do 
> something. Element is be a better name for that formal type.

No, it would be misleading. Element must be reserved for instances of 
the type. They are actual elements. The type of an element is not an 
element, these are two totally different things.

>> There are lots of cases in Ada, you certainly should know that. As a 
>> practical example GtkAda declares all widget types twice:
>>
>>     type Gtk_Button_Record is ...
>>     type Gtk_Button is access all Gtk_Button_Record'Class;
> 
> No well designed library has public access types. You aren't required to 
> use a library that does, and you aren't required to use access types.

I am required to. There must be always be two types in a GUI, one 
referential type and one implementation type. The widget implementation 
object in GtkAda is Gtk_Button_Record. The widget referential object is 
Gtk_Button. It could be a handle or a smart pointer type instead of 
plain pointer, but there is no way to reduce it to a single type. So the 
problem will persist.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 0%]

* Re: Type naming conventions: Any_Foo
  2019-12-05 21:51  7%             ` Dmitry A. Kazakov
@ 2019-12-06 20:18  0%               ` Jeffrey R. Carter
  2019-12-06 20:35  0%                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 73+ results
From: Jeffrey R. Carter @ 2019-12-06 20:18 UTC (permalink / raw)


On 12/5/19 10:51 PM, Dmitry A. Kazakov wrote:
> 
> Ada standard library uses _Type, e.g.
> 
> generic
>     type Element_Type (<>) is private;
>     with function "=" (Left, Right : Element_Type) return Boolean is <>;
> package Ada.Containers.Indefinite_Holders

Yes, and the ARM also includes such abominations as anonymous access types. Just 
because it's in the ARM doesn't mean it's the best way to do something. Element 
is be a better name for that formal type.

> There are lots of cases in Ada, you certainly should know that. As a practical 
> example GtkAda declares all widget types twice:
> 
>     type Gtk_Button_Record is ...
>     type Gtk_Button is access all Gtk_Button_Record'Class;

No well designed library has public access types. You aren't required to use a 
library that does, and you aren't required to use access types.

-- 
Jeff Carter
"Brave Sir Robin ran away."
Monty Python and the Holy Grail
59

^ permalink raw reply	[relevance 0%]

* Re: Type naming conventions: Any_Foo
  @ 2019-12-05 21:51  7%             ` Dmitry A. Kazakov
  2019-12-06 20:18  0%               ` Jeffrey R. Carter
  0 siblings, 1 reply; 73+ results
From: Dmitry A. Kazakov @ 2019-12-05 21:51 UTC (permalink / raw)


On 2019-12-05 21:03, Jeffrey R. Carter wrote:
> On 12/5/19 6:45 PM, Dmitry A. Kazakov wrote:
>>
>> 1. Formal generic types. They are customarily named XXX_Type.
> 
> Well chosen names for generic formal types do not end with _Type. The 
> PragmAda Reusable Components have many generic formal types, none of 
> which end with _Type.

Ada standard library uses _Type, e.g.

generic
    type Element_Type (<>) is private;
    with function "=" (Left, Right : Element_Type) return Boolean is <>;
package Ada.Containers.Indefinite_Holders

As I said, the rationale is that there is no meaningful name for 
Element_Type in the problem space. There is no problem space at all. 
Indefinite_Holders is a helper package so general that considered in 
isolation it has no meaning.

>>        -- I don't want access type, I am required to have it
> 
> Please provide examples of being required to have an access type.

There are lots of cases in Ada, you certainly should know that. As a 
practical example GtkAda declares all widget types twice:

    type Gtk_Button_Record is ...
    type Gtk_Button is access all Gtk_Button_Record'Class;

The suffix _Record is an equivalent to _Type.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 7%]

* Re: How to transfer Class-Wide object to a Task ?
  2019-10-16 20:04  6%       ` William FRANCK
@ 2019-10-17  9:28  7%         ` William FRANCK
  0 siblings, 0 replies; 73+ results
From: William FRANCK @ 2019-10-17  9:28 UTC (permalink / raw)


On 2019-10-16 20:04:41 +0000, William FRANCK said:
 I've uploaded my PoC source file on the comp.lang.ada group.

main_ClassWide_to_2Task.adb

"Transfering Class-Wide Objects to task-entries, with 
Ada.Containers.Indefinite_Holders."

-- ==== here it is as a copy =====
with Ada.Containers.Indefinite_Holders,
     Ada.Text_IO;
use
     Ada,
     Ada.Text_IO;

procedure main_ClassWide_to_2Task is
   -- ========================================================================
   -- Demo program showing how to transfer Class-Wide objects to task-entries,
   -- with Ada.Containers.Indefinite_Holders
   -- ========================================================================
   type Geo2D is tagged record
      Y, X : Integer;
      Name : String (1 .. 8) := "Object 0";
   end record;

   type Circle is new Geo2D with record
      Radius : Integer;
   end record;

   package Geo2D_Holders is new Ada.Containers.Indefinite_Holders 
(Geo2D'Class);

   myDataStore : Geo2D_Holders.Holder;

   -- ==========================================================
   package Object_Reading is

      task reading is
         entry Open;
         entry Object (DataStore : in out Geo2D_Holders.Holder);
         entry Stop;
      end reading;
   end Object_Reading;

   -- ==========================================================
   package Object_Writing is

      task writing is
         entry Create;
         entry Object (DataStore : in Geo2D_Holders.Holder);
         entry Stop;
      end writing;
   end Object_Writing;

   -- ==========================================================
   package body Object_Reading is

      task body reading is
         LocalDataStore : Geo2D_Holders.Holder;
         Nb_items       : Natural := 0;  -- for tracing
      begin
         accept Open do -- end go further only after open is complete
            Text_IO.Put_Line (Standard_Error,"Opening file ...");
         end Open;
         Text_IO.Put_Line (Standard_Error,"Input file ready !");
         loop
            select
               accept Object (DataStore : in out Geo2D_Holders.Holder) do
                  DataStore := Geo2D_Holders.Copy (Source => LocalDataStore);
               end Object;
               declare
                  -- (shortcut to simulate real case with Streams and 
*'Class'Input dispatching) ::
                  --Object : constant Geo2D'Class := Dispatching_Input 
(Ada.Tags.Internal_Tag (External_Tag), Stream);
                  O2D : Geo2D'Class := Circle'(0, 0, "Cercle 0", 10); 
-- simulate object creation done by 'Dispatching_Input'
               begin
                  NB_Items := NB_Items +1; -- for demo
                  O2D.Name(7..8) := Natural'Image(Nb_Items); -- for demo
                  Text_IO.Put_Line (Standard_Error,"Reading 2D Object 
#"& Natural'Image(Nb_Items)&": " & O2D.Name); -- debug trace
                  Geo2D_Holders.Replace_Element (Container => 
LocalDataStore, New_Item => O2D);
               end;
            or
               accept Stop do
                  Text_IO.Put_Line (Standard_Error,"Closing Input file...");
               end Stop;
               Text_IO.Put_Line (Standard_Error,"File cloded, Reading 
Stopped !");
               exit;
            end select;
         end loop;
      end reading;

   end Object_Reading;

   -- ==========================================================
   package body Object_Writing is

      task body writing is

         LocalDataStore : Geo2D_Holders.Holder;
         Nb_items  : Natural := 0;

      begin
         accept Create; -- and go ahead (with i.e. opening input file)
         Text_IO.Put_Line (Standard_Error,"Creating file ...");
         Text_IO.Put_Line (Standard_Error,"Output file ready !");
         loop
            select
               accept Object (DataStore : in Geo2D_Holders.Holder) do
                  LocalDataStore := Geo2D_Holders.copy (DataStore );
               end Object; -- go return to the main process, and go 
ahead with reading next record
               if not Geo2D_Holders.Is_Empty(Container => LocalDataStore)
               then
                  declare
                     O2D : Geo2D'Class := Geo2D_Holders.Element 
(Container => LocalDataStore);
                  begin
                     NB_Items := NB_Items +1; -- for demo
                     --  (shortcut to simulate real case with Streams 
and *'Class'Output dispatching) ::
                     Text_IO.Put_Line (Standard_Error,"   Writing 2D 
Object #"& Natural'Image(Nb_Items)&": " & O2D.Name); -- debug trace
                  end;
               end if;
            or
               accept Stop do
                  Text_IO.Put_Line (Standard_Error,"Closing Output file...");
               end Stop;
               Text_IO.Put_Line (Standard_Error,"File Closed, Writing 
Stopped ! ");
               exit;
            end select;
         end loop;
      end writing;
   end Object_Writing;

   -- ==========================================================
   use Object_Reading;
   use Object_Writing;

begin

   Writing.Create;
   Reading.Open;

   for i in 1 .. 9 loop -- While not end_of_file()
      Reading.Object (myDataStore);
      Writing.Object (myDataStore);
   end loop;

   Reading.Stop;
   Writing.Stop;

end main_ClassWide_to_2Task;


^ permalink raw reply	[relevance 7%]

* Re: How to transfer Class-Wide object to a Task ?
  2019-10-15  4:40  8%     ` Per Sandberg
  2019-10-15  5:40  0%       ` William FRANCK
@ 2019-10-16 20:04  6%       ` William FRANCK
  2019-10-17  9:28  7%         ` William FRANCK
  1 sibling, 1 reply; 73+ results
From: William FRANCK @ 2019-10-16 20:04 UTC (permalink / raw)


Hello Per,

Thaks for the tip !
It saved my life :-).

By using 'Ada.Containers.Indefinite_Holders'
it was possible to transfer the class-wide object from one task-entry 
to another.

If some of you are interested by the 129 SLOC for the sake of sharing designs,
I will post it on this tread.

William.

PS : I didn't found any practical advantage to implement a design with 
a regular FIFO as  the queue will always be at it's max allocation, 
waiting for writing on the file...
Thanks Dmitry for the tip!



On 2019-10-15 04:40:33 +0000, Per Sandberg said:

> Why not use Ada.Containers.Indefinite_holders to encapsulate the 
> Classwide type during store?
> ----------------
> with ADA.Containers.Indefinite_Holders;
> package Demo is
>     type T1 is interface;
>     package T1_Holders is new ADA.Containers.Indefinite_Holders (T1'Class);
> 
>     task type Storage_Task is
>        entry Internal_Store (D : in T1_Holders.Holder);
>        entry Internal_Fetch (D : out T1_Holders.Holder);
>     end Storage_Task;
> 
>     procedure Store (S : Storage_Task; Var : in Demo.T1'Class );
>     Function Fetch(S : Storage_Task) return Demo.T1'Class;
> end Demo;
> ---------------------
> package body Demo is
>     procedure Store (S : Storage_Task; Var : in Demo.T1'Class ) is
>        H : Demo.T1_Holders.Holder;
>     begin
>        H.Replace_Element (Var);
>        S.Internal_Store(H);
>     end Store;
>     Function Fetch(S : Storage_Task) return Demo.T1'Class is
>        H : Demo.T1_Holders.Holder;
>     begin
>        S.Internal_Fetch (H);
>        return H.Element;
>     end Fetch;
> 
>     task body Storage_Task is
>        S : T1_Holders.Holder;
>     begin
>        loop
>           select
>              accept Internal_Fetch (D : out T1_Holders.Holder)  do
>                 D := S;
>              end Internal_Fetch;
>           or accept Internal_Store (D : in T1_Holders.Holder) do
>                 S := D;
>              end Internal_Store;
>           or
>              terminate;
>           end select;
>        end loop;
>     end Storage_Task;
> end Demo;
> ---------------------
> /P
> 
> On 2019-10-14 22:58, William FRANCK wrote:
>> On 2019-10-14 19:58:34 +0000, Dmitry A. Kazakov said:
>> 
>>> On 2019-10-14 21:41, William FRANCK wrote:
>>> 
>>>> Here is a nice issue I have with Ada (GNAT 2012) when trying to do OO 
>>>> dispatching with streams in different tasks ...
>>>> 
>>>> Here it is :
>>>> I'd like to get from a task RdV (Entry-Access) an object which could be 
>>>> any subclass of a root'Class, and pass it to another task
>>>> 
>>>> Context : read (Root'Class'Input() ) tagged records from an input 
>>>> stream, and send them to anther task which will write 
>>>> (Root'Class'Output() ) the given records to another output stream.
>>> 
>>> Strange design, why not to pipe streams using a FIFO?
>>> 
>>>> I'm stuck with task memory isolation with does NOT allow to pass any 
>>>> access object to a Root'Class.
>>>> 
>>>> Should I try to use a protected object ?
>>>> (not shore this solves the passing of a Class-wide object ...)
>>> 
>>> Yes, if using FIFO, a protected object can be used to signal 
>>> non-empty/not-full events at the FIFO ends.
>>> 
>>> Otherwise, use a reference-counted handle or a plain access type to the 
>>> target object. The reader task allocates the object in the pool and 
>>> passes a handle or access to it to the writer. The writer task writes 
>>> the object and then disposes it.
>> 
>> Thanks you Dimitry for your follow-up.
>> 
>> Here is the multitasking part (simplified) (working, no issue)
>> for reading the datafile, and writing it back (after some data-process)
>> 
>> My first intention was : while Writing.Bloc is busy writing on the 
>> output file, Reading.Bloc can take 1 record in advance
>> 
>> Now I have to insert the class-wide object passing in the Bloc.
>> 
>> As You mentionned, should I use a protected type (FIFO)  instead of 2 
>> // tasks ?
>> 
>> --================
>> with Ada.Text_io;
>> 
>> procedure main_tasks is
>> 
>>   task reading is
>>      entry Open;
>>      entry Bloc;
>>      entry Stop;
>>   end reading;
>> 
>>   task  writing is
>>      entry Create;
>>      entry Bloc;
>>      entry Stop;
>>   end writing;
>> 
>>   task body reading is
>>   begin
>>      loop
>>         select
>>            accept Open;
>>               Ada.Text_IO.put_line("Opening file ...");
>>         or
>>            accept Bloc do
>>               Ada.Text_IO.put_line("Reading ...");
>>            end Bloc;
>>         or
>>            accept Stop;
>>            Ada.Text_IO.put_line("Reading Stopped !");
>>            exit;
>>         end select;
>>      end loop;
>>   end reading;
>> 
>>   task body writing is
>>   begin
>>      loop
>>      select
>>         accept Create;
>>         Ada.Text_IO.put_line("Creating file ...");
>>         or
>>            accept Bloc do
>>               Ada.Text_IO.put_line("Got bloc !");
>>            end Bloc;
>>            Ada.Text_IO.put_line("Writing bloc ...");
>>         or
>>            accept Stop;
>>            Ada.Text_IO.put_line("Writing Stopped !");
>>            exit;
>>         end select;
>>      end loop;
>>   end writing;
>> 
>> begin
>> 
>>   Writing.Create;
>>   Reading.Open;
>>   for i in 1..10 loop -- While not end_of_file()
>>      Reading.Bloc;
>>      Writing.Bloc;
>>   end loop;
>> 
>>   Reading.Stop;
>>   Writing.Stop;
>> 
>> end main_tasks;


^ permalink raw reply	[relevance 6%]

* Re: How to transfer Class-Wide object to a Task ?
  @ 2019-10-15 19:41  5%       ` William FRANCK
  0 siblings, 0 replies; 73+ results
From: William FRANCK @ 2019-10-15 19:41 UTC (permalink / raw)


Thank you Optikas for your feedback and advice :-)

Sure, the usual design of a multithreaded  'producer' and 'consumer' 
takes advantage of a FIFO round.
I will considering and testing this as Dmitry outlined it for me.

In fact I may considering my design as a FIFO of one (1) (lol) ?

For now I'm implementing the 'Ada.Containers.Indefinite_Holders' in a 
little PoC.
I'l will share this to the group.

As I mentionned, I do use the Stream attributes 'Input and 'Output, and 
is OK in one single program. The challenge for me is to make it work 
(and pass the objects) in a multi-tasking design.

Huh ?!? There is still something to learn about class-wide and 
indefinite type usage :-)


By the way, I really appreciate the support of this group !
Kind regards,
William



On 2019-10-15 14:31:30 +0000, Optikos said:

> On Tuesday, October 15, 2019 at 2:21:51 AM UTC-5, Dmitry A. Kazakov wrote:
>> On 2019-10-14 22:58, William FRANCK wrote:
>> 
>>> Here is the multitasking part (simplified) (working, no issue)
>>> for reading the datafile, and writing it back (after some data-process)
>>> 
>>> My first intention was : while Writing.Bloc is busy writing on the> > 
>>> output file, Reading.Bloc can take 1 record in advance
>> 
>> That is what OS asynchronous I/O does already. But that is aside.
>> 
>>> Now I have to insert the class-wide object passing in the Bloc.
>> 
>> Stream attributes 'Input and 'Output would do.
>> 
>>> As You mentionned, should I use a protected type (FIFO)  instead of 2 
>>> //> > tasks ?
>> 
>> A protected object to synchronize two tasks:
>> 
>> Producer -> FIFO -> Consumer
>> Block put <- PO -> Block get
>> when full          when empty
>> 
>> FIFO does not need interlocking in this scenario. Protected object is> 
>> only to prevent busy waiting at the ends.
>> 
>> Since you are working with streams you can use a storage stream 
>> instead> of raw FIFO:
>> 
>> Producer -> Storage stream -> Consumer
>> Block write when full    Block read when empty
>> 
>> I still do not understand why you serialize and deserialize insted of> 
>> copying bytes as they are.
> 
> Because OPer is apparently migrating code that was in 2 (UNIXesque) 
> processes to instead be 2 threads in the same process.
> 
> William Franck, you really should rework your design to do as Dmitry 
> advises:  FIFO message queues between 2 otherwise asynchronous threads 
> that work on their own slice of the problem (and have their own slice 
> of the problem's data structures).  Under that revised design, only the 
> FIFO's internals need to worry about thread safety, because before 
> posting and after retrieving from the queue the 2 threads run full tilt 
> in their independent territory without interacting with each other.  
> (This of course assumes that there exists some sort of 
> slicing/partitioning of your problem-space, but there usually is if you 
> look intensely enough for well-defined demarcations.)


^ permalink raw reply	[relevance 5%]

* Re: How to transfer Class-Wide object to a Task ?
  2019-10-14 21:57  4%   ` Shark8
@ 2019-10-15  5:43  0%     ` William FRANCK
  0 siblings, 0 replies; 73+ results
From: William FRANCK @ 2019-10-15  5:43 UTC (permalink / raw)


Thank you Shark,
I'll give it a try too :-)

And send you all a more complete source code of my use case.

William


On 2019-10-14 21:57:57 +0000, Shark8 said:


> On Monday, October 14, 2019 at 2:21:50 PM UTC-6, William FRANCK wrote:
>> On 2019-10-14 19:41:53 +0000, William FRANCK said:
>> 
> Maybe something like this:
> 
>     procedure Example is
>         Package Types is
>             Subtype Params is Ada.Streams.Root_Stream_Type'Class;
>             Type Root   is abstract tagged null record;
>             Function Create (Parameters : not null access Params) 
> return Root is abstract;
> 
>             Type Circle is new Root with record
>                 Radius : Float;
>             end record;
> 
>             Type Square is new Root with record
>                 Side : Integer;
>             end record;
>         Private
> 
>             Function Create (Parameters : not null access Params) 
> return Square;
>             Function Create (Parameters : not null access Params) 
> return Circle;
>         End Types;
> 
> 
>         Use Types;
>         Package Class_Holder is new 
> Ada.Containers.Indefinite_Holders(Root'Class);
>         Task Type Producer( Stream : not null access 
> Ada.Streams.Root_Stream_Type'Class ) is
>             Entry Get( Object: out Class_Holder.Holder );
>         End Producer;
> 
>         Task body Producer is
>             Function MAKE is new Ada.Tags.Generic_Dispatching_Constructor(
>                T           => Types.Root,
>                Parameters  => Ada.Streams.Root_Stream_Type'Class,
>                Constructor => Types.Create
>               );
> 
>             Function To_Tag return Ada.Tags.Tag is
>             Begin
>                 Return Square'Tag;
> --                  (if    Ch = 'C' then Circle'Tag
> --                   elsif Ch = 'S' then Square'Tag
> --                   else raise Constraint_Error with "Tag '"&Ch&"' is 
> invalid.");
>             End;
> 
>         Begin
>             accept Get (Object : out Class_Holder.Holder) do
>                 Object:=
>                   Class_Holder.To_Holder( MAKE(To_Tag, Stream) );
>             end Get;
>         end Producer;
> 
>         Function Get(P : Producer) return Root'Class is
>             H : Class_Holder.Holder;
>         Begin
>             P.Get(H);
>             Return H.Element;
>         End Get;
> 
> 
> 
>         Package Body Types is
>             Function Create(Parameters : not null access Params) return 
> Square is
>             Begin
>                 Return (Side => 3);
>             End;
> 
>             Function Create(Parameters : not null access Params) return 
> Circle is
>             Begin
>                 Return (Radius => 2.2);
>             End;
>         End Types;
> 
>     begin
>         Ada.Text_IO.Put_Line( "START EXAMPLE." );
>         declare
>             I : Ada.Text_IO.File_Type renames Ada.Text_IO.Standard_Input;
>             P : Producer( Ada.Text_IO.Text_Streams.Stream(I) );
>             O : Root'Class := Get(P);
>         begin
>             Ada.Text_IO.Put_Line( "Tag: " & Ada.Tags.Expanded_Name(O'Tag) );
>         end;
>         Ada.Text_IO.Put_Line( "STOP EXAMPLE." );
>     end Example;


^ permalink raw reply	[relevance 0%]

* Re: How to transfer Class-Wide object to a Task ?
  2019-10-15  4:40  8%     ` Per Sandberg
@ 2019-10-15  5:40  0%       ` William FRANCK
  2019-10-16 20:04  6%       ` William FRANCK
  1 sibling, 0 replies; 73+ results
From: William FRANCK @ 2019-10-15  5:40 UTC (permalink / raw)


Thanks Per !

"Containers.Indefinite_holders" seems to be the way to go.
(I didn't used them yet)
I will give it a try :-)

William.

On 2019-10-15 04:40:33 +0000, Per Sandberg said:

> Why not use Ada.Containers.Indefinite_holders to encapsulate the 
> Classwide type during store?
> ----------------
> with ADA.Containers.Indefinite_Holders;
> package Demo is
>     type T1 is interface;
>     package T1_Holders is new ADA.Containers.Indefinite_Holders (T1'Class);
> 
>     task type Storage_Task is
>        entry Internal_Store (D : in T1_Holders.Holder);
>        entry Internal_Fetch (D : out T1_Holders.Holder);
>     end Storage_Task;
> 
>     procedure Store (S : Storage_Task; Var : in Demo.T1'Class );
>     Function Fetch(S : Storage_Task) return Demo.T1'Class;
> end Demo;
> ---------------------
> package body Demo is
>     procedure Store (S : Storage_Task; Var : in Demo.T1'Class ) is
>        H : Demo.T1_Holders.Holder;
>     begin
>        H.Replace_Element (Var);
>        S.Internal_Store(H);
>     end Store;
>     Function Fetch(S : Storage_Task) return Demo.T1'Class is
>        H : Demo.T1_Holders.Holder;
>     begin
>        S.Internal_Fetch (H);
>        return H.Element;
>     end Fetch;
> 
>     task body Storage_Task is
>        S : T1_Holders.Holder;
>     begin
>        loop
>           select
>              accept Internal_Fetch (D : out T1_Holders.Holder)  do
>                 D := S;
>              end Internal_Fetch;
>           or accept Internal_Store (D : in T1_Holders.Holder) do
>                 S := D;
>              end Internal_Store;
>           or
>              terminate;
>           end select;
>        end loop;
>     end Storage_Task;
> end Demo;
> ---------------------
> /P
> 
> On 2019-10-14 22:58, William FRANCK wrote:
>> On 2019-10-14 19:58:34 +0000, Dmitry A. Kazakov said:
>> 
>>> On 2019-10-14 21:41, William FRANCK wrote:
>>> 
>>>> Here is a nice issue I have with Ada (GNAT 2012) when trying to do OO 
>>>> dispatching with streams in different tasks ...
>>>> 
>>>> Here it is :
>>>> I'd like to get from a task RdV (Entry-Access) an object which could be 
>>>> any subclass of a root'Class, and pass it to another task
>>>> 
>>>> Context : read (Root'Class'Input() ) tagged records from an input 
>>>> stream, and send them to anther task which will write 
>>>> (Root'Class'Output() ) the given records to another output stream.
>>> 
>>> Strange design, why not to pipe streams using a FIFO?
>>> 
>>>> I'm stuck with task memory isolation with does NOT allow to pass any 
>>>> access object to a Root'Class.
>>>> 
>>>> Should I try to use a protected object ?
>>>> (not shore this solves the passing of a Class-wide object ...)
>>> 
>>> Yes, if using FIFO, a protected object can be used to signal 
>>> non-empty/not-full events at the FIFO ends.
>>> 
>>> Otherwise, use a reference-counted handle or a plain access type to the 
>>> target object. The reader task allocates the object in the pool and 
>>> passes a handle or access to it to the writer. The writer task writes 
>>> the object and then disposes it.
>> 
>> Thanks you Dimitry for your follow-up.
>> 
>> Here is the multitasking part (simplified) (working, no issue)
>> for reading the datafile, and writing it back (after some data-process)
>> 
>> My first intention was : while Writing.Bloc is busy writing on the 
>> output file, Reading.Bloc can take 1 record in advance
>> 
>> Now I have to insert the class-wide object passing in the Bloc.
>> 
>> As You mentionned, should I use a protected type (FIFO)  instead of 2 
>> // tasks ?
>> 
>> --================
>> with Ada.Text_io;
>> 
>> procedure main_tasks is
>> 
>>   task reading is
>>      entry Open;
>>      entry Bloc;
>>      entry Stop;
>>   end reading;
>> 
>>   task  writing is
>>      entry Create;
>>      entry Bloc;
>>      entry Stop;
>>   end writing;
>> 
>>   task body reading is
>>   begin
>>      loop
>>         select
>>            accept Open;
>>               Ada.Text_IO.put_line("Opening file ...");
>>         or
>>            accept Bloc do
>>               Ada.Text_IO.put_line("Reading ...");
>>            end Bloc;
>>         or
>>            accept Stop;
>>            Ada.Text_IO.put_line("Reading Stopped !");
>>            exit;
>>         end select;
>>      end loop;
>>   end reading;
>> 
>>   task body writing is
>>   begin
>>      loop
>>      select
>>         accept Create;
>>         Ada.Text_IO.put_line("Creating file ...");
>>         or
>>            accept Bloc do
>>               Ada.Text_IO.put_line("Got bloc !");
>>            end Bloc;
>>            Ada.Text_IO.put_line("Writing bloc ...");
>>         or
>>            accept Stop;
>>            Ada.Text_IO.put_line("Writing Stopped !");
>>            exit;
>>         end select;
>>      end loop;
>>   end writing;
>> 
>> begin
>> 
>>   Writing.Create;
>>   Reading.Open;
>>   for i in 1..10 loop -- While not end_of_file()
>>      Reading.Bloc;
>>      Writing.Bloc;
>>   end loop;
>> 
>>   Reading.Stop;
>>   Writing.Stop;
>> 
>> end main_tasks;



^ permalink raw reply	[relevance 0%]

* Re: How to transfer Class-Wide object to a Task ?
  @ 2019-10-15  4:40  8%     ` Per Sandberg
  2019-10-15  5:40  0%       ` William FRANCK
  2019-10-16 20:04  6%       ` William FRANCK
    1 sibling, 2 replies; 73+ results
From: Per Sandberg @ 2019-10-15  4:40 UTC (permalink / raw)


Why not use Ada.Containers.Indefinite_holders to encapsulate the 
Classwide type during store?
----------------
with ADA.Containers.Indefinite_Holders;
package Demo is
    type T1 is interface;
    package T1_Holders is new ADA.Containers.Indefinite_Holders (T1'Class);

    task type Storage_Task is
       entry Internal_Store (D : in T1_Holders.Holder);
       entry Internal_Fetch (D : out T1_Holders.Holder);
    end Storage_Task;

    procedure Store (S : Storage_Task; Var : in Demo.T1'Class );
    Function Fetch(S : Storage_Task) return Demo.T1'Class;
end Demo;
---------------------
package body Demo is
    procedure Store (S : Storage_Task; Var : in Demo.T1'Class ) is
       H : Demo.T1_Holders.Holder;
    begin
       H.Replace_Element (Var);
       S.Internal_Store(H);
    end Store;
    Function Fetch(S : Storage_Task) return Demo.T1'Class is
       H : Demo.T1_Holders.Holder;
    begin
       S.Internal_Fetch (H);
       return H.Element;
    end Fetch;

    task body Storage_Task is
       S : T1_Holders.Holder;
    begin
       loop
          select
             accept Internal_Fetch (D : out T1_Holders.Holder)  do
                D := S;
             end Internal_Fetch;
          or accept Internal_Store (D : in T1_Holders.Holder) do
                S := D;
             end Internal_Store;
          or
             terminate;
          end select;
       end loop;
    end Storage_Task;
end Demo;
---------------------
/P

On 2019-10-14 22:58, William FRANCK wrote:
> On 2019-10-14 19:58:34 +0000, Dmitry A. Kazakov said:
> 
>> On 2019-10-14 21:41, William FRANCK wrote:
>>
>>> Here is a nice issue I have with Ada (GNAT 2012) when trying to do OO 
>>> dispatching with streams in different tasks ...
>>>
>>> Here it is :
>>> I'd like to get from a task RdV (Entry-Access) an object which could 
>>> be any subclass of a root'Class, and pass it to another task
>>>
>>> Context : read (Root'Class'Input() ) tagged records from an input 
>>> stream, and send them to anther task which will write 
>>> (Root'Class'Output() ) the given records to another output stream.
>>
>> Strange design, why not to pipe streams using a FIFO?
>>
>>> I'm stuck with task memory isolation with does NOT allow to pass any 
>>> access object to a Root'Class.
>>>
>>> Should I try to use a protected object ?
>>> (not shore this solves the passing of a Class-wide object ...)
>>
>> Yes, if using FIFO, a protected object can be used to signal 
>> non-empty/not-full events at the FIFO ends.
>>
>> Otherwise, use a reference-counted handle or a plain access type to 
>> the target object. The reader task allocates the object in the pool 
>> and passes a handle or access to it to the writer. The writer task 
>> writes the object and then disposes it.
> 
> Thanks you Dimitry for your follow-up.
> 
> Here is the multitasking part (simplified) (working, no issue)
> for reading the datafile, and writing it back (after some data-process)
> 
> My first intention was : while Writing.Bloc is busy writing on the 
> output file, Reading.Bloc can take 1 record in advance
> 
> Now I have to insert the class-wide object passing in the Bloc.
> 
> As You mentionned, should I use a protected type (FIFO)  instead of 2 // 
> tasks ?
> 
> --================
> with Ada.Text_io;
> 
> procedure main_tasks is
> 
>    task reading is
>       entry Open;
>       entry Bloc;
>       entry Stop;
>    end reading;
> 
>    task  writing is
>       entry Create;
>       entry Bloc;
>       entry Stop;
>    end writing;
> 
>    task body reading is
>    begin
>       loop
>          select
>             accept Open;
>                Ada.Text_IO.put_line("Opening file ...");
>          or
>             accept Bloc do
>                Ada.Text_IO.put_line("Reading ...");
>             end Bloc;
>          or
>             accept Stop;
>             Ada.Text_IO.put_line("Reading Stopped !");
>             exit;
>          end select;
>       end loop;
>    end reading;
> 
>    task body writing is
>    begin
>       loop
>       select
>          accept Create;
>          Ada.Text_IO.put_line("Creating file ...");
>          or
>             accept Bloc do
>                Ada.Text_IO.put_line("Got bloc !");
>             end Bloc;
>             Ada.Text_IO.put_line("Writing bloc ...");
>          or
>             accept Stop;
>             Ada.Text_IO.put_line("Writing Stopped !");
>             exit;
>          end select;
>       end loop;
>    end writing;
> 
> begin
> 
>    Writing.Create;
>    Reading.Open;
>    for i in 1..10 loop -- While not end_of_file()
>       Reading.Bloc;
>       Writing.Bloc;
>    end loop;
> 
>    Reading.Stop;
>    Writing.Stop;
> 
> end main_tasks;
> 


^ permalink raw reply	[relevance 8%]

* Re: How to transfer Class-Wide object to a Task ?
  @ 2019-10-14 21:57  4%   ` Shark8
  2019-10-15  5:43  0%     ` William FRANCK
  0 siblings, 1 reply; 73+ results
From: Shark8 @ 2019-10-14 21:57 UTC (permalink / raw)


On Monday, October 14, 2019 at 2:21:50 PM UTC-6, William FRANCK wrote:
> On 2019-10-14 19:41:53 +0000, William FRANCK said:
> 
Maybe something like this:

    procedure Example is
        Package Types is
            Subtype Params is Ada.Streams.Root_Stream_Type'Class;
            Type Root   is abstract tagged null record;
            Function Create (Parameters : not null access Params) return Root is abstract;
            
            Type Circle is new Root with record
                Radius : Float;
            end record;
            
            Type Square is new Root with record
                Side : Integer;
            end record;
        Private
            
            Function Create (Parameters : not null access Params) return Square;
            Function Create (Parameters : not null access Params) return Circle;
        End Types;
        
        
        Use Types;
        Package Class_Holder is new Ada.Containers.Indefinite_Holders(Root'Class);
        Task Type Producer( Stream : not null access Ada.Streams.Root_Stream_Type'Class ) is
            Entry Get( Object: out Class_Holder.Holder );
        End Producer;
        
        Task body Producer is
            Function MAKE is new Ada.Tags.Generic_Dispatching_Constructor(
               T           => Types.Root,
               Parameters  => Ada.Streams.Root_Stream_Type'Class,
               Constructor => Types.Create
              );

            Function To_Tag return Ada.Tags.Tag is
            Begin
                Return Square'Tag;
--                  (if    Ch = 'C' then Circle'Tag
--                   elsif Ch = 'S' then Square'Tag
--                   else raise Constraint_Error with "Tag '"&Ch&"' is invalid.");
            End;
            
        Begin
            accept Get (Object : out Class_Holder.Holder) do
                Object:=
                  Class_Holder.To_Holder( MAKE(To_Tag, Stream) );
            end Get;
        end Producer;
        
        Function Get(P : Producer) return Root'Class is
            H : Class_Holder.Holder;
        Begin
            P.Get(H);
            Return H.Element;
        End Get;
        
        
        
        Package Body Types is
            Function Create(Parameters : not null access Params) return Square is
            Begin
                Return (Side => 3);
            End;
            
            Function Create(Parameters : not null access Params) return Circle is
            Begin
                Return (Radius => 2.2);
            End;
        End Types;
        
    begin
        Ada.Text_IO.Put_Line( "START EXAMPLE." );
        declare
            I : Ada.Text_IO.File_Type renames Ada.Text_IO.Standard_Input;
            P : Producer( Ada.Text_IO.Text_Streams.Stream(I) );
            O : Root'Class := Get(P);
        begin
            Ada.Text_IO.Put_Line( "Tag: " & Ada.Tags.Expanded_Name(O'Tag) );
        end;
        Ada.Text_IO.Put_Line( "STOP EXAMPLE." );
    end Example;

^ permalink raw reply	[relevance 4%]

* Indefinite_Holders: bug or misunderstanding?
@ 2018-01-31 12:06  7% Alejandro R. Mosteo
  0 siblings, 0 replies; 73+ results
From: Alejandro R. Mosteo @ 2018-01-31 12:06 UTC (permalink / raw)


I have used the Indefinite_Holders sometimes to make definite types from 
classwide ones, or variant records without defaults. However this sample 
case doesn't work with an array (with GNAT 2017 or GCC 7.2.0) and I'm 
unsure wether it should:

---8<---

with Ada.Containers.Indefinite_Holders;

procedure Test_Holder is

    package Inner is

       type Str (<>) is private;

    private

       type Str is array (Positive range <>) of Character;

       -- type Str (Len : Natural) is record
       --    S : String (1 .. Len);
       -- end record;

    end Inner;

    package Str_Holders is new Ada.Containers.Indefinite_Holders
       (Inner.Str, Inner."=");

begin
    null;
end Test_Holder;

---8<---

The commented alternate Str type does compile fine. The error I'm 
getting for the uncommented one is:

$ gnatmake test_holder.adb
gcc -c test_holder.adb
test_holder.adb:19:04: instantiation error at a-coinho.adb:337
test_holder.adb:19:04: invalid constraint: type has no discriminant
test_holder.adb:19:04: instantiation error at a-coinho.adb:337
test_holder.adb:19:04: unconstrained subtype not allowed (need 
initialization)
test_holder.adb:19:04: provide initial value or explicit array bounds
test_holder.adb:19:04: instantiation error at a-coinho.adb:337
test_holder.adb:19:04: expected private type "Str" defined at line 7
test_holder.adb:19:04: found type "Str" defined at line 11
gnatmake: "test_holder.adb" compilation error

Something obvious I'm missing?

Thanks,
Alex.

^ permalink raw reply	[relevance 7%]

* How discriminants interplay with derived tagged types?
@ 2017-11-26 23:00  7% Victor Porton
  0 siblings, 0 replies; 73+ results
From: Victor Porton @ 2017-11-26 23:00 UTC (permalink / raw)


Below three is a fragment of my real code.

It uses both discriminants and derived tagged types. I am not sure I well 
understand how they interplay.

Please explain how discriminants and derived tagged types interplay.


with Ada.Containers.Indefinite_Holders;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

package Boiler.RDF_Format.Resource is

   type Script_Kind_Enum is (Transformer, Validator);

   type Transformer_Kind_Enum is (Entire, Sequential, Up_Down, Down_Up);

   type Validator_Kind_Enum is (Entire, Parts);

   package String_Holder is new Ada.Containers.Indefinite_Holders(String);

   type Script_Info (Script_Kind: Script_Kind_Enum) is tagged
      record
         Completeness, Stability, Preference: Long_Float; -- or better just 
Float?
         -- TODO: Distinguishing transformer and validator scripts does not 
conform to the specification
         case Script_Kind is
            when Transformer =>
               Transformer_Kind: Transformer_Kind_Enum;
            when Validator =>
               Validator_Kind  : Validator_Kind_Enum;
         end case;
      end record;

   type Command_Script_Info is new Script_Info with
      record
         Language: URI_Type;
         Min_Version, Max_Version: String_Holder.Holder;
         Script_URL:     String_Holder.Holder;
         Command_String: String_Holder.Holder;
         OK_Result: String_Holder.Holder;
      end record;

   type Web_Service_Script_Info is new Script_Info with
      record
         Action: RDF.Redland.URI.URI_Type;
         Method: Unbounded_String;
         XML_Field: Unbounded_String;
      end record;

end Boiler.RDF_Format.Resource;


-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Holders and limited types
  2017-11-15  8:35  7% ` Dmitry A. Kazakov
@ 2017-11-15 22:24  6%   ` Randy Brukardt
  0 siblings, 0 replies; 73+ results
From: Randy Brukardt @ 2017-11-15 22:24 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:ougu7j$1g1c$1@gioia.aioe.org...
> On 15/11/2017 01:00, Victor Porton wrote:
>> Why Ada.Containers.Indefinite_Holders (as of Ada2012) accepts "private"
>> Element_Type? I would like it be "limited private" instead.
>>
>> The particular reason I want this is to hold Timing_Event inside an
>> indefinite holder inside a record.
>
> It is a design choice. Handles can use either external or internal 
> allocator. The latter option requires copying, so it cannot be limited, 
> the former option might be less comfortable.

Right. The Insert operation of all of the containers requires making a new 
copy of the element in the container. That's necessary if one wants the 
container to handle all of the storage management for the elements (which 
was an explicit design goal of the containers -- preventing the need to use 
explicit access types for non-limited element types).

> I prefer design with an external allocator, so I pass a access type to my 
> generic handles package.

That's a fine alternative; it does put the storage management burden on the 
client (which we were trying to avoid). Note that you can use the definite 
containers to do this - which is another reason to use non-limited element 
types.

Several of us have tried to design containers that could directly contain 
limited objects, but no one (me included) has been able to come up with 
anything that had any significant advantage over just putting an explicit 
general access value into the container instead (and getting that value from 
'Access of an aliased object).

                                                 Randy.


^ permalink raw reply	[relevance 6%]

* Re: Ada.Containers.Indefinite_Holders and limited types
  2017-11-15  0:00 13% Ada.Containers.Indefinite_Holders and limited types Victor Porton
  2017-11-15  7:52  7% ` Simon Wright
@ 2017-11-15  8:35  7% ` Dmitry A. Kazakov
  2017-11-15 22:24  6%   ` Randy Brukardt
  1 sibling, 1 reply; 73+ results
From: Dmitry A. Kazakov @ 2017-11-15  8:35 UTC (permalink / raw)


On 15/11/2017 01:00, Victor Porton wrote:
> Why Ada.Containers.Indefinite_Holders (as of Ada2012) accepts "private"
> Element_Type? I would like it be "limited private" instead.
> 
> The particular reason I want this is to hold Timing_Event inside an
> indefinite holder inside a record.

It is a design choice. Handles can use either external or internal 
allocator. The latter option requires copying, so it cannot be limited, 
the former option might be less comfortable.

I prefer design with an external allocator, so I pass a access type to 
my generic handles package.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Holders and limited types
  2017-11-15  0:00 13% Ada.Containers.Indefinite_Holders and limited types Victor Porton
@ 2017-11-15  7:52  7% ` Simon Wright
  2017-11-15  8:35  7% ` Dmitry A. Kazakov
  1 sibling, 0 replies; 73+ results
From: Simon Wright @ 2017-11-15  7:52 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> Why Ada.Containers.Indefinite_Holders (as of Ada2012) accepts
> "private" Element_Type? I would like it be "limited private" instead.
>
> The particular reason I want this is to hold Timing_Event inside an
> indefinite holder inside a record.

Because there are Holder operations that allow copying of the
Element_Type, perhaps; e.g. Copy.

Why not use "access Timing_Event'Class" or suchlike?


^ permalink raw reply	[relevance 7%]

* Ada.Containers.Indefinite_Holders and limited types
@ 2017-11-15  0:00 13% Victor Porton
  2017-11-15  7:52  7% ` Simon Wright
  2017-11-15  8:35  7% ` Dmitry A. Kazakov
  0 siblings, 2 replies; 73+ results
From: Victor Porton @ 2017-11-15  0:00 UTC (permalink / raw)


Why Ada.Containers.Indefinite_Holders (as of Ada2012) accepts "private" 
Element_Type? I would like it be "limited private" instead.

The particular reason I want this is to hold Timing_Event inside an 
indefinite holder inside a record.

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 13%]

* Re: Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders
  2017-09-23  9:16  5%           ` Jeffrey R. Carter
@ 2017-10-03  0:15  7%             ` Randy Brukardt
  0 siblings, 0 replies; 73+ results
From: Randy Brukardt @ 2017-10-03  0:15 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:oq58qb$o3s$1@dont-email.me...
> On 09/23/2017 10:09 AM, Dmitry A. Kazakov wrote:
>> On 2017-09-23 00:15, Victor Porton wrote:
>>>
>>> In my opinion, it would be better to change RM phrasing from "null 
>>> string"
>>> to "empty string", because in some other languages (notably C) NULL 
>>> means
>>> something other. It is just confusing.
....
> It's called overloading. Many of these cases refer to things that can have 
> components and mean one with zero components: a null record has no 
> components, a null array has no components ('Length = 0), a null string 
> literal has no characters, a null set has no members, ... It should not be 
> confusing.

And it also shows the amount of change needed to actually make such a change 
to the RM. It would be a lot of change for (at most) not much value, so it 
wouldn't be a very good use of scarce resources.

                              Randy.


^ permalink raw reply	[relevance 7%]

* Re: Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders
  2017-09-23  8:09  6%         ` Dmitry A. Kazakov
@ 2017-09-23  9:16  5%           ` Jeffrey R. Carter
  2017-10-03  0:15  7%             ` Randy Brukardt
  0 siblings, 1 reply; 73+ results
From: Jeffrey R. Carter @ 2017-09-23  9:16 UTC (permalink / raw)


On 09/23/2017 10:09 AM, Dmitry A. Kazakov wrote:
> On 2017-09-23 00:15, Victor Porton wrote:
>>
>> In my opinion, it would be better to change RM phrasing from "null string"
>> to "empty string", because in some other languages (notably C) NULL means
>> something other. It is just confusing.
> 
> The adjective null and the noun null are distinct parts of speech. C's noun null 
> is an abbreviation of null pointer. If pointers can be null so strings can.

Another way to look at it: Ada has the formal concepts of:

* null access value ARM 4.2(9)
* null array 3.6.1(7)
* null constraint 3.2(7/2)
* null_exclusion 3.10(5.1/2)
* null extension 3.9.1(4.1/2)
* null procedure 6.7(3/3)
* null range 3.5(4)
* null record 3.8(15)
* null slice 4.1.2(7)
* null string literal 2.6(6)
* null value (of an access type) 3.10(13/2)
* null_statement 5.1(6)

not to mention the language-defined identifiers

Null_Address
    in System   13.7(12)
Null_Bounded_String
    in Ada.Strings.Bounded   A.4.4(7)
Null_Id
    in Ada.Exceptions   11.4.1(2/2)
Null_Occurrence
    in Ada.Exceptions   11.4.1(3/2)
Null_Ptr
    in Interfaces.C.Strings   B.3.1(7)
Null_Set
    in Ada.Strings.Maps   A.4.2(5)
    in Ada.Strings.Wide_Maps   A.4.7(5)
    in Ada.Strings.Wide_Wide_Maps   A.4.8(5/2)
Null_Task_Id
    in Ada.Task_Identification   C.7.1(2/2)
Null_Unbounded_String
    in Ada.Strings.Unbounded   A.4.5(5)

(Just look under N in the index.)

It's called overloading. Many of these cases refer to things that can have 
components and mean one with zero components: a null record has no components, a 
null array has no components ('Length = 0), a null string literal has no 
characters, a null set has no members, ... It should not be confusing.

-- 
Jeff Carter
"You cheesy lot of second-hand electric donkey-bottom biters."
Monty Python & the Holy Grail
14

^ permalink raw reply	[relevance 5%]

* Re: Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders
  2017-09-22 22:15  7%       ` Victor Porton
@ 2017-09-23  8:09  6%         ` Dmitry A. Kazakov
  2017-09-23  9:16  5%           ` Jeffrey R. Carter
  0 siblings, 1 reply; 73+ results
From: Dmitry A. Kazakov @ 2017-09-23  8:09 UTC (permalink / raw)


On 2017-09-23 00:15, Victor Porton wrote:
> Simon Wright wrote:
> 
>> Victor Porton <porton@narod.ru> writes:
>>
>>> What is 2.5(6)? There is no (6) in RM 2.5.
>>
>> 2.6(6):
>>
>>      A null string literal is a string_literal with no string_elements
>>      between the quotation marks.
> 
> In my opinion, it would be better to change RM phrasing from "null string"
> to "empty string", because in some other languages (notably C) NULL means
> something other. It is just confusing.

The adjective null and the noun null are distinct parts of speech. C's 
noun null is an abbreviation of null pointer. If pointers can be null so 
strings can.

Wouldn't it be silly to change, say, mathematical group theory with its 
null group elements because C (and Ada too) have null pointers called nulls?

BTW, empty is string is indeed a null element for the concatenation 
operation &:

    forall X in String   X & "" = X

So, using the null adjective is absolutely justified.

A null string is a bit more than just empty string. (:-))

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 6%]

* Re: Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders
  2017-09-22 19:25  7%     ` Simon Wright
@ 2017-09-22 22:15  7%       ` Victor Porton
  2017-09-23  8:09  6%         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 73+ results
From: Victor Porton @ 2017-09-22 22:15 UTC (permalink / raw)


Simon Wright wrote:

> Victor Porton <porton@narod.ru> writes:
> 
>> What is 2.5(6)? There is no (6) in RM 2.5.
> 
> 2.6(6):
> 
>     A null string literal is a string_literal with no string_elements
>     between the quotation marks.

In my opinion, it would be better to change RM phrasing from "null string" 
to "empty string", because in some other languages (notably C) NULL means 
something other. It is just confusing.

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 7%]

* Re: Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders
  2017-09-22 12:16  7%   ` Victor Porton
@ 2017-09-22 19:25  7%     ` Simon Wright
  2017-09-22 22:15  7%       ` Victor Porton
  0 siblings, 1 reply; 73+ results
From: Simon Wright @ 2017-09-22 19:25 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> What is 2.5(6)? There is no (6) in RM 2.5.

2.6(6):

    A null string literal is a string_literal with no string_elements
    between the quotation marks.

^ permalink raw reply	[relevance 7%]

* Re: Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders
  2017-09-21 21:30  7% ` AdaMagica
@ 2017-09-22 12:16  7%   ` Victor Porton
  2017-09-22 19:25  7%     ` Simon Wright
  0 siblings, 1 reply; 73+ results
From: Victor Porton @ 2017-09-22 12:16 UTC (permalink / raw)


AdaMagica wrote:

> Am Donnerstag, 21. September 2017 20:14:29 UTC+2 schrieb Victor Porton:
>> This may be a little slower.
> 
> Why do you care for performance? Have you ever measured what you are
> worrying about?
> 
> Premature optimization is the source of all evil - you can hear this
> mantra very often here.
> 
> 
>> Hm well, do I understand Null_Unbounded_String correctly? Is
>> Null_Unbounded_String really "no string"? or is it just empty string
>> ("")?
> 
> It's the latter. Is RM A.4.5(73) and 2.5(6) clear enough?

The problem I asked about is exactly that A.4.5(73) is not clear enough. 
What is 2.5(6)? There is no (6) in RM 2.5.

Well, you are right (assuming that GCC 7.2.0 does the right thing), as this 
prints "True":

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO;

procedure Test is
begin
  Ada.Text_IO.Put_Line(Boolean'Image(To_Unbounded_String("") = 
Null_Unbounded_String));
end;


-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 7%]

* Re: Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders
  2017-09-21 18:14 12% Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders Victor Porton
@ 2017-09-21 21:30  7% ` AdaMagica
  2017-09-22 12:16  7%   ` Victor Porton
  0 siblings, 1 reply; 73+ results
From: AdaMagica @ 2017-09-21 21:30 UTC (permalink / raw)


Am Donnerstag, 21. September 2017 20:14:29 UTC+2 schrieb Victor Porton:
> This may be a little slower.

Why do you care for performance? Have you ever measured what you are worrying about?

Premature optimization is the source of all evil - you can hear this mantra very often here.


> Hm well, do I understand Null_Unbounded_String correctly? Is 
> Null_Unbounded_String really "no string"? or is it just empty string ("")? 

It's the latter. Is RM A.4.5(73) and 2.5(6) clear enough?

^ permalink raw reply	[relevance 7%]

* Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders
@ 2017-09-21 18:14 12% Victor Porton
  2017-09-21 21:30  7% ` AdaMagica
  0 siblings, 1 reply; 73+ results
From: Victor Porton @ 2017-09-21 18:14 UTC (permalink / raw)


I am writing an interface to a C library. Some C functions accept either a C 
string pointer or NULL.

I need some way to define an Ada object which could hold values equivalent 
to C strings with possible NULL.

I consider two approaches:

1. Ada.Strings.Unbounded (remind that it can be Null_Unbounded_String which 
is equivalent to NULL C string).

2. Ada.Containers.Indefinite_Holders holding a String.

The first way seems more natural, as a more specialized package is used.

The second way may have the advantage that there is Is_Empty function while 
for unbounded strings I would need to compare with Null_Unbounded_String 
using "=" operator. This may be a little slower. Or does it matter with 
modern compilers?

Hm well, do I understand Null_Unbounded_String correctly? Is 
Null_Unbounded_String really "no string"? or is it just empty string ("")? 
RM2012 should be made more clear on this topic!

-- 
Victor Porton - http://portonvictor.org


^ permalink raw reply	[relevance 12%]

* Interest in standard smart pointers for Ada 2020
@ 2017-08-31 12:12  4% Alejandro R. Mosteo
  0 siblings, 0 replies; 73+ results
From: Alejandro R. Mosteo @ 2017-08-31 12:12 UTC (permalink / raw)


I wonder if there would be interest in standardizing some usual smart 
pointers for the next revision. I will try to state the problems. I hope 
you'll point any misunderstandings on my part.

Ada has the particular limited and indefinite types, typically absent in 
other languages. However, their constraints often get in the way of 
comfort (all the cases I will list have workarounds, it's only tiresome 
and unnecessary noise):

* You cannot have indefinite record members, unless you make the record 
indefinite as well by providing a constraint. This basically moves the 
problem elsewhere (to the containing record, which may have no reason to 
be indefinite). Furthermore, some types do not have public constraints 
(e.g., to prevent declaration without initialization), so the previous 
solution wouldn't work. Also for class-wide members?

*** Ada.Containers.Indefinite_Holders is aimed at this use case, but it 
is only for by-value semantics, so if you don't want to pay that penalty 
for some reason (large types) you're out of luck.

* You cannot have a limited type (obviously) as a member of an unlimited 
type. You're then forced to resort to low-level accesses or custom 
wrappers to pass around those members.

* Delayed initialization of limited types, specially in combination with 
indefinite-ness will require some access type use.

* Delayed initialization of indefinite types, when you don't want to/can 
have a default discriminant (I remember a recent discussion about 
limited-size indefinites).

* Any other use cases I'm forgetting about right now?

Arguably (I'm unsure about this) in most cases problems could be avoided 
with careful design? I don't know, but I do know that there are smart 
pointer Ada libraries around, and I have rolled my own more often than 
not, and when I try to go the unconstrained way all around, sooner or 
later I have to backpedal.

If we look at the cousin C++, the standard pointers there are:

> unique_ptr [1]

> Allows exactly one owner of the underlying pointer. Use as the default choice for POCO unless you know for certain that you require a shared_ptr. Can be moved to a new owner, but not copied or shared.

> shared_ptr [2]

> Reference-counted smart pointer. Use when you want to assign one raw pointer to multiple owners, for example, when you return a copy of a pointer from a container but want to keep the original. The raw pointer is not deleted until all shared_ptr owners have gone out of scope or have otherwise given up ownership.

> weak_ptr [3]

> Special-case smart pointer for use in conjunction with shared_ptr. A weak_ptr provides access to an object that is owned by one or more shared_ptr instances, but does not participate in reference counting. Use when you want to observe an object, but do not require it to remain alive. Required in some cases to break circular references between shared_ptr instances.

I'd argue for having these, and also thread-safe implementations (that I 
guess would be heavier, requiring protected internals). I'd be willing 
to work on this too, if there is interest.

Alex.

[1] http://en.cppreference.com/w/cpp/memory/unique_ptr
[2] http://en.cppreference.com/w/cpp/memory/shared_ptr
[3] http://en.cppreference.com/w/cpp/memory/weak_ptr

^ permalink raw reply	[relevance 4%]

* Re: Need a way to convert a constant to a variable
  2017-08-05 13:41  7% Need a way to convert a constant to a variable Victor Porton
  2017-08-05 14:48  8% ` Dmitry A. Kazakov
  2017-08-05 15:41  7% ` Jeffrey R. Carter
@ 2017-08-05 17:59  0% ` Per Sandberg
  2 siblings, 0 replies; 73+ results
From: Per Sandberg @ 2017-08-05 17:59 UTC (permalink / raw)


????
A constant shall never ever change its value since the compiler is free 
to use the value in compile time to optimize the code if possible.

So the whole suggestion is screaming "I want to do a very bad design".

/P


Den 2017-08-05 kl. 15:41, skrev Victor Porton:
> I've sent the following email to ada-comment mailing list. I duplicate it
> here.
> 
> !topic Need a way to convert a constant to a variable
> !reference Ada 2012 RM
> !from Victor Porton 17-08-05
> !keywords constant, variable, view, conversion
> !discussion
> 
> Sometimes one needs to convert a constant view into variable view (I am
> fully conscious that after this the programmer should take care not to
> change the object of the view).
> 
> In the following (not compilable with GNAT 7.1.0) code I present my
> best attempt to solve the following problem:
> 
> Write a function with an "in" indefinite holder with a string, return
> chars_ptr corresponding to the string.
> 
> It looks like there is no solution of this in Ada 2012 :-(
> 
> with Interfaces.C; use Interfaces.C;
> with Interfaces.C.Strings; use Interfaces.C.Strings;
> with Ada.Containers.Indefinite_Holders;
> 
> procedure Conv is
> 
>     package Char_Array_Holders is
>        new Ada.Containers.Indefinite_Holders(char_array);
> 
>     type C_String_Holder is new Char_Array_Holders.Holder
>        with null record;
>     
>     function To_C_String (Object: C_String_Holder) return chars_ptr is
>        Value: char_array renames Constant_Reference(Object).Element.all;
>        Value2: aliased Char_Array(Value'Range) with Import;
>        for Value2'Address use Value'Address;
>     begin
>        return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
>     end;
> begin
>     null;
> end;
> 
> $ gnatgcc -c conv.adb -c conv.adb
> conv.adb:13:07: warning: aliased object has explicit bounds
> conv.adb:13:07: warning: declare without bounds (and with explicit
> initialization)
> conv.adb:13:07: warning: for use with unconstrained access
> conv.adb:16:46: object subtype must statically match designated subtype
> 
> My current workaround is to define my own "indefinite holder" type to
> use it in my software instead of Ada.Containers.Indefinite_Holders.
> 
> I propose the following language change:
> 
> Please add 'Unchecked_Variable attribute.
> 
> There are two possible meanings (of which we should choose one) of the
> attribute:
> 
> 1. C'Unchecked_Variable returns a variable view of a constant C.
> 
> 2. A'Unchecked_Variable returns the corresponding access to a variable
> for an access A to constant.
> 
> Both variants seem to solve the trouble.
> 
> Can any problem with different representation of constant and variables
> appear?
> 

^ permalink raw reply	[relevance 0%]

* Re: Need a way to convert a constant to a variable
  2017-08-05 15:41  7% ` Jeffrey R. Carter
@ 2017-08-05 16:25  0%   ` Victor Porton
  0 siblings, 0 replies; 73+ results
From: Victor Porton @ 2017-08-05 16:25 UTC (permalink / raw)


Jeffrey R. Carter wrote:

> On 08/05/2017 03:41 PM, Victor Porton wrote:
>> 
>> Write a function with an "in" indefinite holder with a string, return
>> chars_ptr corresponding to the string.
> 
> Your requirements are for an indefinite holder with a string, but your
> attempted solution is for an indefinite holder with a char_array. I will
> assume you meant an indefinite holder with a char_array.

Yes, my typo. I am about an indefinite holder with a char_array.

>> It looks like there is no solution of this in Ada 2012 :-(
> 
> with Ada.Containers.Indefinite_Holders;
> with Interfaces.C.Strings;
> 
> package Conv is
>     package C_Str_Holders is new Ada.Containers.Indefinite_Holders
>        (Element_Type => Interfaces.C.Char_Array, "=" => Interfaces.C."=");
> 
>     function To_Chars_Ptr (Item : C_Str_Holders.Holder)
>                         return Interfaces.C.Strings.Chars_Ptr is
>        (Interfaces.C.Strings.New_Char_Array (Item.Element) );
> end Conv;
> 
> This compiles fine, so clearly there is a way to do this without a
> language change.

Your code allocates a new string which requires to be freed later.

I want a function, which would return a pointer to the (not necessarily nul-
terminated) string hold in the indefinite holder, so that deallocation would 
be not required and code would be more efficient (not requiring to copy the 
char_array).

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 0%]

* Re: Need a way to convert a constant to a variable
  2017-08-05 13:41  7% Need a way to convert a constant to a variable Victor Porton
  2017-08-05 14:48  8% ` Dmitry A. Kazakov
@ 2017-08-05 15:41  7% ` Jeffrey R. Carter
  2017-08-05 16:25  0%   ` Victor Porton
  2017-08-05 17:59  0% ` Per Sandberg
  2 siblings, 1 reply; 73+ results
From: Jeffrey R. Carter @ 2017-08-05 15:41 UTC (permalink / raw)


On 08/05/2017 03:41 PM, Victor Porton wrote:
> 
> Write a function with an "in" indefinite holder with a string, return
> chars_ptr corresponding to the string.

Your requirements are for an indefinite holder with a string, but your attempted 
solution is for an indefinite holder with a char_array. I will assume you meant 
an indefinite holder with a char_array.

> It looks like there is no solution of this in Ada 2012 :-(

with Ada.Containers.Indefinite_Holders;
with Interfaces.C.Strings;

package Conv is
    package C_Str_Holders is new Ada.Containers.Indefinite_Holders
       (Element_Type => Interfaces.C.Char_Array, "=" => Interfaces.C."=");

    function To_Chars_Ptr (Item : C_Str_Holders.Holder)
                        return Interfaces.C.Strings.Chars_Ptr is
       (Interfaces.C.Strings.New_Char_Array (Item.Element) );
end Conv;

This compiles fine, so clearly there is a way to do this without a language change.

-- 
Jeff Carter
"He didn't get that nose from playing ping-pong."
Never Give a Sucker an Even Break
110

---
This email has been checked for viruses by AVG.
http://www.avg.com


^ permalink raw reply	[relevance 7%]

* Re: Need a way to convert a constant to a variable
  2017-08-05 14:48  8% ` Dmitry A. Kazakov
@ 2017-08-05 15:11  0%   ` Victor Porton
  0 siblings, 0 replies; 73+ results
From: Victor Porton @ 2017-08-05 15:11 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> On 2017-08-05 15:41, Victor Porton wrote:
>> I've sent the following email to ada-comment mailing list. I duplicate it
>> here.
>> 
>> !topic Need a way to convert a constant to a variable
>> !reference Ada 2012 RM
>> !from Victor Porton 17-08-05
>> !keywords constant, variable, view, conversion
>> !discussion
>> 
>> Sometimes one needs to convert a constant view into variable view (I am
>> fully conscious that after this the programmer should take care not to
>> change the object of the view).
>> 
>> In the following (not compilable with GNAT 7.1.0) code I present my
>> best attempt to solve the following problem:
>> 
>> Write a function with an "in" indefinite holder with a string, return
>> chars_ptr corresponding to the string.
>> 
>> It looks like there is no solution of this in Ada 2012 :-(
>> 
>> with Interfaces.C; use Interfaces.C;
>> with Interfaces.C.Strings; use Interfaces.C.Strings;
>> with Ada.Containers.Indefinite_Holders;
>> 
>> procedure Conv is
>> 
>>     package Char_Array_Holders is
>>        new Ada.Containers.Indefinite_Holders(char_array);
>> 
>>     type C_String_Holder is new Char_Array_Holders.Holder
>>        with null record;
>>     
>>     function To_C_String (Object: C_String_Holder) return chars_ptr is
>>        Value: char_array renames Constant_Reference(Object).Element.all;
>>        Value2: aliased Char_Array(Value'Range) with Import;
>>        for Value2'Address use Value'Address;
>>     begin
>>        return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
>>     end;
>> begin
>>     null;
>> end;
> 
> AFAIK, Ada.Containers.Indefinite_Holders was designed in a way to
> prevent specifically what you want.
> 
>> Can any problem with different representation of constant and variables
>> appear?
> 
> 1. Don't use Ada.Containers.Indefinite_Holders?
> 
> 2. Don't use char_array. It has restricted use when interfacing C. You
> probably need chars_ptr put into a controlled type if you want safe C
> strings. This is basically same as Holder internally is, except that you
> are in full control.

I do use char_array for interfacing with C.

It is a pity that I need to reimplement Indefinite_Holders for this task.

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 0%]

* Re: Need a way to convert a constant to a variable
  2017-08-05 13:41  7% Need a way to convert a constant to a variable Victor Porton
@ 2017-08-05 14:48  8% ` Dmitry A. Kazakov
  2017-08-05 15:11  0%   ` Victor Porton
  2017-08-05 15:41  7% ` Jeffrey R. Carter
  2017-08-05 17:59  0% ` Per Sandberg
  2 siblings, 1 reply; 73+ results
From: Dmitry A. Kazakov @ 2017-08-05 14:48 UTC (permalink / raw)


On 2017-08-05 15:41, Victor Porton wrote:
> I've sent the following email to ada-comment mailing list. I duplicate it
> here.
> 
> !topic Need a way to convert a constant to a variable
> !reference Ada 2012 RM
> !from Victor Porton 17-08-05
> !keywords constant, variable, view, conversion
> !discussion
> 
> Sometimes one needs to convert a constant view into variable view (I am
> fully conscious that after this the programmer should take care not to
> change the object of the view).
> 
> In the following (not compilable with GNAT 7.1.0) code I present my
> best attempt to solve the following problem:
> 
> Write a function with an "in" indefinite holder with a string, return
> chars_ptr corresponding to the string.
> 
> It looks like there is no solution of this in Ada 2012 :-(
> 
> with Interfaces.C; use Interfaces.C;
> with Interfaces.C.Strings; use Interfaces.C.Strings;
> with Ada.Containers.Indefinite_Holders;
> 
> procedure Conv is
> 
>     package Char_Array_Holders is
>        new Ada.Containers.Indefinite_Holders(char_array);
> 
>     type C_String_Holder is new Char_Array_Holders.Holder
>        with null record;
>     
>     function To_C_String (Object: C_String_Holder) return chars_ptr is
>        Value: char_array renames Constant_Reference(Object).Element.all;
>        Value2: aliased Char_Array(Value'Range) with Import;
>        for Value2'Address use Value'Address;
>     begin
>        return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
>     end;
> begin
>     null;
> end;

AFAIK, Ada.Containers.Indefinite_Holders was designed in a way to 
prevent specifically what you want.

> Can any problem with different representation of constant and variables
> appear?

1. Don't use Ada.Containers.Indefinite_Holders?

2. Don't use char_array. It has restricted use when interfacing C. You 
probably need chars_ptr put into a controlled type if you want safe C 
strings. This is basically same as Holder internally is, except that you 
are in full control.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 8%]

* Need a way to convert a constant to a variable
@ 2017-08-05 13:41  7% Victor Porton
  2017-08-05 14:48  8% ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 73+ results
From: Victor Porton @ 2017-08-05 13:41 UTC (permalink / raw)


I've sent the following email to ada-comment mailing list. I duplicate it 
here.

!topic Need a way to convert a constant to a variable
!reference Ada 2012 RM
!from Victor Porton 17-08-05
!keywords constant, variable, view, conversion
!discussion

Sometimes one needs to convert a constant view into variable view (I am
fully conscious that after this the programmer should take care not to
change the object of the view).

In the following (not compilable with GNAT 7.1.0) code I present my
best attempt to solve the following problem:

Write a function with an "in" indefinite holder with a string, return
chars_ptr corresponding to the string.

It looks like there is no solution of this in Ada 2012 :-(

with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
with Ada.Containers.Indefinite_Holders;

procedure Conv is

   package Char_Array_Holders is
      new Ada.Containers.Indefinite_Holders(char_array);

   type C_String_Holder is new Char_Array_Holders.Holder
      with null record;
   
   function To_C_String (Object: C_String_Holder) return chars_ptr is
      Value: char_array renames Constant_Reference(Object).Element.all;
      Value2: aliased Char_Array(Value'Range) with Import;
      for Value2'Address use Value'Address;
   begin
      return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
   end;
begin
   null;
end;

$ gnatgcc -c conv.adb -c conv.adb 
conv.adb:13:07: warning: aliased object has explicit bounds
conv.adb:13:07: warning: declare without bounds (and with explicit
initialization)
conv.adb:13:07: warning: for use with unconstrained access
conv.adb:16:46: object subtype must statically match designated subtype

My current workaround is to define my own "indefinite holder" type to
use it in my software instead of Ada.Containers.Indefinite_Holders.

I propose the following language change:

Please add 'Unchecked_Variable attribute.

There are two possible meanings (of which we should choose one) of the
attribute:

1. C'Unchecked_Variable returns a variable view of a constant C.

2. A'Unchecked_Variable returns the corresponding access to a variable
for an access A to constant.

Both variants seem to solve the trouble.

Can any problem with different representation of constant and variables
appear?

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 7%]

* Re: Is there a reason System.Storage_Pools isn't Pure?
  2017-04-18 23:42  5%   ` Shark8
@ 2017-04-19 20:36  0%     ` Randy Brukardt
  0 siblings, 0 replies; 73+ results
From: Randy Brukardt @ 2017-04-19 20:36 UTC (permalink / raw)


"Shark8" <onewingedshark@gmail.com> wrote in message 
news:61e151c1-9fe6-4d32-8f13-d425bc41a616@googlegroups.com...
...
> What about a usable-for-anything holder? (In particular, I think that 
> Ada.Containers.Indefinite_Holders ought to be less restrictive than they 
> are.) We could have a Pure Indefinite_Holder with:
>
>    Generic
>      Type Element_Type(<>) is limited private;
>      -- Pure storage-pool as a parameter? a dependency?
>    Package Example with Pure, Spark_Mode => On is
>      Type Holder is private;
>      Function Has_Element( Container : Holder ) return Boolean;
>      Function Element( Container : Holder ) return Element_Type
>        with Pre => Has_Element( Container );
>      Procedure Clear( Container : in out Holder )
>        with Post => not Has_Element( Container );
>    Private
>      Pragma SPARK_Mode( Off );
>
>      Type is access Element_Type
>        with Storage_Size => 0; -- Pure pool storage to allow non-zero?
>
>      Function Has_Element( Container : Holder ) return Boolean is
>        (Container /= Null);
>      Function Has_Element( Container : Holder ) return Boolean is
>        (Container.All);
>    End Example;
>
> Or am I misunderstanding?

Your spec here doesn't have any way to put an element into the holder. And 
that's where the trouble comes (especially for limited types!). Perhaps you 
can figure it out (I haven't been able to). As it stands, your holder 
objects would have to have Has_Element = False. Not very useful. ;-)

                              Randy.
 


^ permalink raw reply	[relevance 0%]

* Re: Is there a reason System.Storage_Pools isn't Pure?
  @ 2017-04-18 23:42  5%   ` Shark8
  2017-04-19 20:36  0%     ` Randy Brukardt
  0 siblings, 1 reply; 73+ results
From: Shark8 @ 2017-04-18 23:42 UTC (permalink / raw)


On Tuesday, April 18, 2017 at 12:32:34 PM UTC-6, Randy Brukardt wrote:
> Originally, it was not Pure because it was a child of System, which was not 
> Pure. So I can't find any discussion of the merits.
> 
> However, Pure packages are automatically Remote_Types packages (that is, 
> values of the type can be transmitted between partitions). We'd never want 
> that to be the case with a storage pool, so there doesn't seem to be any 
> point in it being Pure.

Are we sure we'd never want that?
I imagine that would be an interesting way to do VMs -- essentially transmitting the [contained] memory directly between partitions, right? -- so we could essentially solve the problems plaguing JavaScript/backend development (in theory) with this, right?


> Additionally, the Pure package rules assume that no storage pools can be 
> specified for access types (because there aren't rules banning that at 
> library-level, and there need to be such rules to prevent hidden state). 
> That could be changed, I suppose, but given that a Pure storage pool could 
> only be used for a local access type in a Pure package(something that mainly 
> exists in ACATS tests), it would be close to useless (or get used for 
> back-door state). Note that state has to be strictly prohibited as Pure 
> packages are replicated when used in a distributed system (thus each 
> partition would have different state, which wouldn't make sense).

What about a usable-for-anything holder? (In particular, I think that Ada.Containers.Indefinite_Holders ought to be less restrictive than they are.) We could have a Pure Indefinite_Holder with:

    Generic
      Type Element_Type(<>) is limited private;
      -- Pure storage-pool as a parameter? a dependency?
    Package Example with Pure, Spark_Mode => On is
      Type Holder is private;
      Function Has_Element( Container : Holder ) return Boolean;
      Function Element( Container : Holder ) return Element_Type
        with Pre => Has_Element( Container );
      Procedure Clear( Container : in out Holder )
        with Post => not Has_Element( Container );
    Private
      Pragma SPARK_Mode( Off );
      
      Type is access Element_Type
        with Storage_Size => 0; -- Pure pool storage to allow non-zero?
      
      Function Has_Element( Container : Holder ) return Boolean is
        (Container /= Null);
      Function Has_Element( Container : Holder ) return Boolean is
        (Container.All);
    End Example;

Or am I misunderstanding?

> IMHO, Pure packages are too restricted to be useful (and not restricted 
> enough to be useful when synchronization is involved); it makes sense for 
> individual subprograms but not for an entire package. So I recommend only 
> trying to make packages Preelaborated. (That's especially true in Ada 2012, 
> where limited I/O is possible.) [Distribution might change this thinking; 
> I'm only considering stand-alone programs that don't use Annex E.]

That's probably truer than I'd like -- but I guess the question was borne out of playing around w/ pure units and seeing how far I could push the style-guide's instruction "Use pragma Pure where allowed."
( https://en.wikibooks.org/wiki/Ada_Style_Guide/Print_version#Pragma_Pure )


^ permalink raw reply	[relevance 5%]

* Re: Are mutually dependant and possibly recursive types using Containers possible?
  2016-09-09 20:24  5% Are mutually dependant and possibly recursive types using Containers possible? Shark8
@ 2016-09-09 20:40  0% ` Jeffrey R. Carter
  0 siblings, 0 replies; 73+ results
From: Jeffrey R. Carter @ 2016-09-09 20:40 UTC (permalink / raw)


On 09/09/2016 01:24 PM, Shark8 wrote:
> 
> We could add Strings easily enough:
>  Package String_Holder is new Ada.Containers.Indefinite_Holders( String );
>  
>  Type Type_Indicator is ( TI_Integer, TI_Real, TI_String );
>  
>  Type Item( Indicator : Type_Indicator ) is record
>     case Indicator is
>         when TI_Integer => Integer_Value : Integer;
>         when TI_Real    => Real_Value    : Float;
>         when TI_String  => String_Value  : String_Holder.Holder;
>     end case;
>  end record;
> 
> But with adding arrays things break down:
> we can't instantiate Ada.Containers.Indefinite_Vectors for use in Item because Item isn't defined at that point, yet we absolutely need it in order to make it (the structure/definition) simple.

Somebody named Shark8 asked this July 30:

https://groups.google.com/forum/#!msg/comp.lang.ada/Brf7vvOLvrQ/fQB6RUzZAgAJ;context-place=forum/comp.lang.ada

I'm not sure what was wrong with the solution you got there then, since you
didn't respond to any of the replies, but my solution is still to make Item a
type extension of a dummy tagged type Root, and instantiate Indefinite_Vectors
with Root'Class.

-- 
Jeff Carter
"In the frozen land of Nador they were forced to
eat Robin's minstrels, and there was much rejoicing."
Monty Python & the Holy Grail
70

^ permalink raw reply	[relevance 0%]

* Are mutually dependant and possibly recursive types using Containers possible?
@ 2016-09-09 20:24  5% Shark8
  2016-09-09 20:40  0% ` Jeffrey R. Carter
  0 siblings, 1 reply; 73+ results
From: Shark8 @ 2016-09-09 20:24 UTC (permalink / raw)


Alright, let's say we're implementing a programming a programming language  -- because the problem becomes very apparent there -- and it has a simple set of two primitive types, Real and Integer, and two complex ones, Array and String.

If it were just the primitive-types, we could use:
 Type Primitive(Is_Real : Boolean) is record
    case Is_Real is
        when True  => Real_Value    : Float;
        when False => Integer_Value : Integer;
    end case;
 end record;


We could add Strings easily enough:
 Package String_Holder is new Ada.Containers.Indefinite_Holders( String );
 
 Type Type_Indicator is ( TI_Integer, TI_Real, TI_String );
 
 Type Item( Indicator : Type_Indicator ) is record
    case Indicator is
        when TI_Integer => Integer_Value : Integer;
        when TI_Real    => Real_Value    : Float;
        when TI_String  => String_Value  : String_Holder.Holder;
    end case;
 end record;

But with adding arrays things break down:
we can't instantiate Ada.Containers.Indefinite_Vectors for use in Item because Item isn't defined at that point, yet we absolutely need it in order to make it (the structure/definition) simple.

True, we could avoid this if arrays of arrays aren't required/allowed, but the problem comes back if the language introduces/requires references and, arguably, pointers. (The difference being that the empty-holder would not be allowed in a reference, but would in a pointer [whose null value would be the no_element constant].)

^ permalink raw reply	[relevance 5%]

* Re: Updated PragmAda Reusable Components
  2016-09-07 10:45  6% ` Alejandro R. Mosteo
@ 2016-09-07 17:51  0%   ` Jeffrey R. Carter
  0 siblings, 0 replies; 73+ results
From: Jeffrey R. Carter @ 2016-09-07 17:51 UTC (permalink / raw)


On 09/07/2016 03:45 AM, Alejandro R. Mosteo wrote:
> On 05/09/16 21:04, PragmAda Software Engineering wrote:
>> There are some new components in the beta version of the PragmARCs for
>> ISO/IEC 8652:2007: PragmARC.Concurrent_Pipeline and PragmARC.Holders.
>>
> Ada 2012 has Ada.Containers.Indefinite_Holders for this, I guess you already
> know but need it for the 95 version.

Right, but as the 1st ¶ of the original post (quoted) shows, the components are
targeted for the previous version of the standard. However, Gnoga compiles (some
of) the components with GNAT with the -gnat2012 switch without any problems.

-- 
Jeff Carter
"I used to manufacture escalator shoes for people
who were nauseous in elevator shoes."
Take the Money and Run
142

^ permalink raw reply	[relevance 0%]

* Re: Updated PragmAda Reusable Components
  @ 2016-09-07 10:45  6% ` Alejandro R. Mosteo
  2016-09-07 17:51  0%   ` Jeffrey R. Carter
  0 siblings, 1 reply; 73+ results
From: Alejandro R. Mosteo @ 2016-09-07 10:45 UTC (permalink / raw)


On 05/09/16 21:04, PragmAda Software Engineering wrote:
> There are some new components in the beta version of the PragmARCs for
> ISO/IEC 8652:2007: PragmARC.Concurrent_Pipeline and PragmARC.Holders.
>
>
> Concurrent_Pipeline was inspired by discussions of the Rx approach to
> concurrency, such as RxJava, in which a sequence of operations are
> chained together from a source to a sink, the operations being able to
> proceed in parallel but only one execution of a given operation at a
> time. If one ignores the Rx syntax and concentrates on providing the
> functionality in a way that's natural for Ada, it becomes fairly simple:
> Concurrent_Pipeline is 45 Ada terminator semicolons.
>
> I haven't looked at the Rx approach in detail, so there may be
> differences between it and Concurrent_Pipeline.

Very interested, thank you. My own efforts at a more to-the-letter RxAda 
are at

https://bitbucket.org/amosteo/rxada

Still at the early stages but already with some interesting operators to 
play with.

> It's not clear that Concurrent_Pipeline pipeline is needed; it seems the
> same functionality could be achieved with PragmARC.Job_Pools. It may be
> a more natural approach for some problems, though.
>
> Holders provides variables for indefinite types; something like it is
> needed to allow the operations in a Concurrent_Pipeline to proceed in
> parallel. It was also not strictly needed, as the same functionality
> could be obtained with an indefinite container that is only used to
> store a single value.

Ada 2012 has Ada.Containers.Indefinite_Holders for this, I guess you 
already know but need it for the 95 version.

Álex.


> The PragmARCs may be obtained from Github
>
> https://github.com/jrcarter/PragmARC
>
> or from the web site.
>

^ permalink raw reply	[relevance 6%]

* Re: Memory leak in Indefinite_Holders
  2016-06-13  8:22  6% Memory leak in Indefinite_Holders Alejandro R. Mosteo
@ 2016-06-13  9:45  0% ` Alejandro R. Mosteo
  0 siblings, 0 replies; 73+ results
From: Alejandro R. Mosteo @ 2016-06-13  9:45 UTC (permalink / raw)


On 13/06/16 10:22, Alejandro R. Mosteo wrote:
> I think this is a bug in Gnat, but I'd like to hear some other opinion
> before submitting it.

I've now tested it using Indefinite_Doubly_Linked_Lists and the leak 
goes away.

Álex.

> Context: Using Constant_Reference of a holder type embedded in another
> record causes a memory leak.
>
> Self-contained procedure and Valgrind output below:
>
> ---8<---
>
> with Ada.Containers.Indefinite_Holders;
> with Ada.Text_IO; use Ada.Text_IO;
>
> procedure Holder_Leak is
>     use Ada.Containers;
>     type Indef is array (Integer range <>) of Integer;
>     package Holders is new Indefinite_Holders (Indef);
>     type Def is new Holders.Holder with null record;
>
>     -- This wrapper type is necessary for the leak to manifest
>     type Outer is record
>        Inner : Def;
>     end record;
>
>     procedure Eat (O : Outer) is
>     begin
>        for I of O.Inner.Constant_Reference loop
>        -- Using .Element instead there is no leak
>           Put_Line (I'Img);
>        end loop;
>     end Eat;
>
> begin
>     for I in 1 .. 666 loop
>        Eat ((Inner => To_Holder ((1, 2, 3, 4, 5))));
>     end loop;
> end Holder_Leak;
>
> ---8<---
>
> Curiously, line 17 which is necessary for the leak to occur doesn't show
> in the Valgrind output. The leak is real though, as can be confirmed by
> making the loop infinite and monitoring the process memory usage with
> e.g. top.
>
> Compiled with switches:
>   -g -gnatwal.fF -gnatVa -g -O2 -gnato -fstack-check -gnata -gnatf
> -gnat12 -gnatyO
>
> $ valgrind --leak-check=full ./holder_leak
>
> ==23853==
> ==23853== HEAP SUMMARY:
> ==23853==     in use at exit: 34,632 bytes in 1,332 blocks
> ==23853==   total heap usage: 2,664 allocs, 1,332 frees, 69,264 bytes
> allocated
> ==23853==
> ==23853== 34,632 (15,984 direct, 18,648 indirect) bytes in 666 blocks
> are definitely lost in loss record 2 of 2
> ==23853==    at 0x4C2DB8F: malloc (in
> /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==23853==    by 0x4177AC: __gnat_malloc (in
> /home/jano/local/rxada/obj/holder_leak)
> ==23853==    by 0x404A6E: holder_leak__holders__to_holder.3633
> (a-coinho.adb:444)
> ==23853==    by 0x405FC7: _ada_holder_leak (holder_leak.adb:25)
> ==23853==    by 0x4028C9: main (b__holder_leak.adb:254)
> ==23853==
> ==23853== LEAK SUMMARY:
> ==23853==    definitely lost: 15,984 bytes in 666 blocks
> ==23853==    indirectly lost: 18,648 bytes in 666 blocks
> ==23853==      possibly lost: 0 bytes in 0 blocks
> ==23853==    still reachable: 0 bytes in 0 blocks
> ==23853==         suppressed: 0 bytes in 0 blocks
> ==23853==
> ==23853== For counts of detected and suppressed errors, rerun with: -v
> ==23853== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
>
> Álex.


^ permalink raw reply	[relevance 0%]

* Memory leak in Indefinite_Holders
@ 2016-06-13  8:22  6% Alejandro R. Mosteo
  2016-06-13  9:45  0% ` Alejandro R. Mosteo
  0 siblings, 1 reply; 73+ results
From: Alejandro R. Mosteo @ 2016-06-13  8:22 UTC (permalink / raw)


I think this is a bug in Gnat, but I'd like to hear some other opinion 
before submitting it.

Context: Using Constant_Reference of a holder type embedded in another 
record causes a memory leak.

Self-contained procedure and Valgrind output below:

---8<---

with Ada.Containers.Indefinite_Holders;
with Ada.Text_IO; use Ada.Text_IO;

procedure Holder_Leak is
    use Ada.Containers;
    type Indef is array (Integer range <>) of Integer;
    package Holders is new Indefinite_Holders (Indef);
    type Def is new Holders.Holder with null record;

    -- This wrapper type is necessary for the leak to manifest
    type Outer is record
       Inner : Def;
    end record;

    procedure Eat (O : Outer) is
    begin
       for I of O.Inner.Constant_Reference loop
       -- Using .Element instead there is no leak
          Put_Line (I'Img);
       end loop;
    end Eat;

begin
    for I in 1 .. 666 loop
       Eat ((Inner => To_Holder ((1, 2, 3, 4, 5))));
    end loop;
end Holder_Leak;

---8<---

Curiously, line 17 which is necessary for the leak to occur doesn't show 
in the Valgrind output. The leak is real though, as can be confirmed by 
making the loop infinite and monitoring the process memory usage with 
e.g. top.

Compiled with switches:
  -g -gnatwal.fF -gnatVa -g -O2 -gnato -fstack-check -gnata -gnatf 
-gnat12 -gnatyO

$ valgrind --leak-check=full ./holder_leak

==23853==
==23853== HEAP SUMMARY:
==23853==     in use at exit: 34,632 bytes in 1,332 blocks
==23853==   total heap usage: 2,664 allocs, 1,332 frees, 69,264 bytes 
allocated
==23853==
==23853== 34,632 (15,984 direct, 18,648 indirect) bytes in 666 blocks 
are definitely lost in loss record 2 of 2
==23853==    at 0x4C2DB8F: malloc (in 
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23853==    by 0x4177AC: __gnat_malloc (in 
/home/jano/local/rxada/obj/holder_leak)
==23853==    by 0x404A6E: holder_leak__holders__to_holder.3633 
(a-coinho.adb:444)
==23853==    by 0x405FC7: _ada_holder_leak (holder_leak.adb:25)
==23853==    by 0x4028C9: main (b__holder_leak.adb:254)
==23853==
==23853== LEAK SUMMARY:
==23853==    definitely lost: 15,984 bytes in 666 blocks
==23853==    indirectly lost: 18,648 bytes in 666 blocks
==23853==      possibly lost: 0 bytes in 0 blocks
==23853==    still reachable: 0 bytes in 0 blocks
==23853==         suppressed: 0 bytes in 0 blocks
==23853==
==23853== For counts of detected and suppressed errors, rerun with: -v
==23853== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Álex.


^ permalink raw reply	[relevance 6%]

* Re: Advice, tasking and hardware
  2016-05-27 20:27  0%         ` Dmitry A. Kazakov
@ 2016-05-27 22:27  0%           ` Randy Brukardt
  0 siblings, 0 replies; 73+ results
From: Randy Brukardt @ 2016-05-27 22:27 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:niaaji$1nar$1@gioia.aioe.org...
> On 2016-05-27 21:13, Shark8 wrote:
>> On Friday, May 27, 2016 at 1:50:50 AM UTC-6, Dmitry A. Kazakov wrote:
>>> 5. Tasks entries have parameter passing problems. If you don't handle
>>> everything in the rendezvous in order to release the caller as soon as
>>> possible, you need to copy parameters and store them locally. The design
>>> of the select statement prevents doing this in a structured way. E.g.
>>>
>>>     select
>>>        accept String_Call (Text : String) do
>>>           Local_Text := Text; -- Accept scope
>>>        end;
>>>        declare -- Handler's scope
>>>           Local_Text : String -- This does not work!
>>>        begin
>>>           -- Process Local_Text
>>>        end;
>>>     or accept ...
>>
>> Pretty much a non-problem in Ada 2012:
>>
>>     package Example is
>>
>> Task Text_IO is
>>     Entry Get( Data : String );
>>     Entry Put;
>>     Entry Done;
>> End Text_IO;
>>
>>     end Example;
>>
>>     package body Example is
>>
>> Task Body Text_IO is
>>     Package String_Holder is new Ada.Containers.Indefinite_Holders(
>>       Element_Type => String );
>
> That is no solution. You still have to move entry-specific local data to 
> the task-wide scope, which was the main point of being unstructured.
>
> And you certainly don't want pool-allocated stuff in drivers.

> Finally, this is no different from Unbounded_String.

Sure, if the only unconstrained type you ever use is a String. The 
Indefinite_Holders solution works for any unconstrained type, not just 
String.

And no one (I hope!) is putting tasks in drivers in the first place; one 
wants as little as possible in OS drivers, because they necessarily are 
outside of the control of the OS (written without the standards used for the 
OS, etc.) The caller of the driver needs to manage concurrency. So how one 
writes tasks isn't particularly relevant to writing drivers. (Whether or not 
the OS should avoid pool allocation is a different question altogether...)

Aside: I get the feeling that the term "drivers" has been totally corrupted 
in recent systems, including all kinds of higher-level junk that belongs to 
the OS. So we might be talking about different things.

                       Randy.


^ permalink raw reply	[relevance 0%]

* Re: Advice, tasking and hardware
  2016-05-27 19:13  5%       ` Shark8
@ 2016-05-27 20:27  0%         ` Dmitry A. Kazakov
  2016-05-27 22:27  0%           ` Randy Brukardt
  0 siblings, 1 reply; 73+ results
From: Dmitry A. Kazakov @ 2016-05-27 20:27 UTC (permalink / raw)


On 2016-05-27 21:13, Shark8 wrote:
> On Friday, May 27, 2016 at 1:50:50 AM UTC-6, Dmitry A. Kazakov wrote:
>> 5. Tasks entries have parameter passing problems. If you don't handle
>> everything in the rendezvous in order to release the caller as soon as
>> possible, you need to copy parameters and store them locally. The design
>> of the select statement prevents doing this in a structured way. E.g.
>>
>>     select
>>        accept String_Call (Text : String) do
>>           Local_Text := Text; -- Accept scope
>>        end;
>>        declare -- Handler's scope
>>           Local_Text : String -- This does not work!
>>        begin
>>           -- Process Local_Text
>>        end;
>>     or accept ...
>
> Pretty much a non-problem in Ada 2012:
>
>     package Example is
> 	
> 	Task Text_IO is
> 	    Entry Get( Data : String );
> 	    Entry Put;
> 	    Entry Done;
> 	End Text_IO;
> 	
>     end Example;
>
>     package body Example is
> 	
> 	Task Body Text_IO is
> 	    Package String_Holder is new Ada.Containers.Indefinite_Holders(
> 	      Element_Type => String );

That is no solution. You still have to move entry-specific local data to 
the task-wide scope, which was the main point of being unstructured.

And you certainly don't want pool-allocated stuff in drivers. Finally, 
this is no different from Unbounded_String.

>> 6. Task entries cannot return unconstrained objects.
>
> This can be worked around:
>    We can add to the previous task the following:
> 	    Entry Data( Item : out Natural );
> 	    Entry Data( Item : out String );

This is a very low-level and very fragile design. Consider ensuring that 
nothing comes between querying the length and the body that could change 
the string. You start doing that with entry barriers risking running 
into a deadlock. Then consider a possibility that the caller of a 
get-length request dies prematurely, or that another task steals the 
string body and so on.

Note that the "discussion" started around the claim that design based on 
semaphore is more low-level than one based on monitor (the task serves 
as a monitor).

(There was a reason why protected objects were introduced in Ada 95)

P.S. The Ada-way of returning string is this:

    entry Get_Text (Text : in out String; Last : out Integer);

I am using a bit more general:

    entry Get_Text (Text : in out String; Pointer : in out Integer);

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 0%]

* Re: Advice, tasking and hardware
  @ 2016-05-27 19:13  5%       ` Shark8
  2016-05-27 20:27  0%         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 73+ results
From: Shark8 @ 2016-05-27 19:13 UTC (permalink / raw)


On Friday, May 27, 2016 at 1:50:50 AM UTC-6, Dmitry A. Kazakov wrote:
> 5. Tasks entries have parameter passing problems. If you don't handle 
> everything in the rendezvous in order to release the caller as soon as 
> possible, you need to copy parameters and store them locally. The design 
> of the select statement prevents doing this in a structured way. E.g.
> 
>     select
>        accept String_Call (Text : String) do
>           Local_Text := Text; -- Accept scope
>        end;
>        declare -- Handler's scope
>           Local_Text : String -- This does not work!
>        begin
>           -- Process Local_Text
>        end;
>     or accept ...

Pretty much a non-problem in Ada 2012:

    package Example is
	
	Task Text_IO is
	    Entry Get( Data : String );
	    Entry Put;
	    Entry Done;
	End Text_IO;
	
    end Example;
    
    package body Example is
	
	Task Body Text_IO is
	    Package String_Holder is new Ada.Containers.Indefinite_Holders(
	      Element_Type => String );

	    Internal_Data : String_Holder.Holder:= String_Holder.To_Holder("");
	    Finished      : Boolean := False;
	begin
	    loop
		select
		    accept Done do
			Finished:= True;
		    end Done;
		or
		    accept Get (Data : in String) do
			Internal_Data:= String_Holder.To_Holder( Data );
		    end Get;
		or
		    accept Put do
			Ada.Text_IO.Put_Line( "DATA: "& Internal_Data.Element );
		    end Put;
		end select;
		
		Exit when Finished;
	    end loop;
		
	End Text_IO;
	
    end Example;

and used via:
    Example.Text_IO.Put;
    Example.Text_IO.Get( "Test Data" );
    Example.Text_IO.Put;
    Example.Text_IO.Get( "Something Else" );
    Example.Text_IO.Put;

    Example.Text_IO.Done;

> 6. Task entries cannot return unconstrained objects.

This can be worked around:
   We can add to the previous task the following:
	    Entry Data( Item : out Natural );
	    Entry Data( Item : out String );
   Where the one returns the constraints needed for the other... it would be used something like this:
    declare
	Length : Natural renames Example.Text_IO.Data;
	Test   : constant String(1..Length):= Example.Text_IO.Data;
    begin
	Put_Line ( "----- " & Test & " -----" );
    end;


^ permalink raw reply	[relevance 5%]

* Re: storage error: stack overflow
  @ 2015-08-18 20:56  6%             ` Randy Brukardt
  0 siblings, 0 replies; 73+ results
From: Randy Brukardt @ 2015-08-18 20:56 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:mqvejr$hai$2@dont-email.me...
> On 08/18/2015 07:02 AM, hreba wrote:
>>
>> Huh? As much as I know you cannot declare variables of a type with 
>> unknown
>> storage requirements at compile time, such as class-wide types and arrays 
>> with
>> unknown range.
>
> These are "indefinite types". You can declare an object of an indefinite 
> type as
> long as you supply an initialization expression:
>
> S : String := "Hello";
>
> V : T'Class := Some_Function;

And if you need to change the type of the object after initialization, you 
can use the "Holder" container, which exists for this very purpose:

      package T_Class_Holder is new Ada.Containers.Indefinite_Holders 
(T'Class);

      V : T_Class_Holder.Holder;
  begin
      V.Replace_Element (Some_Function);
      ...
      V.Replace_Element (Some_Other_Function);
      ...
   end;

In Ada 2012, you can also use the reference function to modify the object, 
but you can't change the tag that way. That is:

    V.Reference := Some_Function;

As noted, this will raise Constraint_Error if the tag of V.Reference is 
changed.

I may sound like a broken record (scratched CD?? ;-), but using a Holder 
rather than explicit access types lets the library do the storage management 
rather than the programmer. There are much less likely to be bugs that way.

And of course, you can do this with all of the containers; if you need a Map 
or Tree or Vector [including an array] of T'Class, just instantiate the 
appropriate container and again let someone at your compiler vendor get the 
storage management right, rather than doing it yourself.

                                              Randy.



^ permalink raw reply	[relevance 6%]

* Re: Ada.Containers.Indefinite_Holders in GNAT and Ada2012
  2014-08-09 19:43  7% ` Victor Porton
  2014-08-10 13:06  7%   ` Victor Porton
@ 2014-08-11 23:58  6%   ` Randy Brukardt
  1 sibling, 0 replies; 73+ results
From: Randy Brukardt @ 2014-08-11 23:58 UTC (permalink / raw)


"Victor Porton" <porton@narod.ru> wrote in message 
news:ls5tkt$6g2$1@speranza.aioe.org...
> Victor Porton wrote:
>
>> I tried to write:
>>
>> Element(Object)'Access;
>>
>> for "Object" being a value of an instance of
>> Ada.Containers.Indefinite_Holders.
>>
>> This does not work because the return type of Element is not aliased.
>
> By the way, does it makes sense in the next Ada specification to make the
> return type of "Element" function aliased?

Ada doesn't allow return objects to be declared "aliased". We looked at 
allowing that when we added "aliased" parameters, but the semantics would 
have been unusual at best. We couldn't figure out what it mean in various 
usual cases (as you note later, Ada usually allows the return to be a copy, 
and this is important for some kinds of types).

Since it's doesn't make sense (in general) for a return object to be 
aliased, it couldn't make sense to allow that in a generic.

                                                  Randy.




^ permalink raw reply	[relevance 6%]

* Re: Ada.Containers.Indefinite_Holders in GNAT and Ada2012
  2014-08-10 13:06  7%   ` Victor Porton
  2014-08-10 15:32  7%     ` Simon Wright
  2014-08-11 11:01  7%     ` AdaMagica
@ 2014-08-11 15:38  7%     ` Adam Beneschan
  2 siblings, 0 replies; 73+ results
From: Adam Beneschan @ 2014-08-11 15:38 UTC (permalink / raw)


On Sunday, August 10, 2014 6:06:21 AM UTC-7, Victor Porton wrote:

> However I propose to add Element_Access to next RM which would return access 
> to the element in the container.

Since the RM already has Reference, and a Reference type has an Element component whose type is an access type, what would be gained by an Element_Access?

                               -- Adam

^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Holders in GNAT and Ada2012
  2014-08-10 13:06  7%   ` Victor Porton
  2014-08-10 15:32  7%     ` Simon Wright
@ 2014-08-11 11:01  7%     ` AdaMagica
  2014-08-11 15:38  7%     ` Adam Beneschan
  2 siblings, 0 replies; 73+ results
From: AdaMagica @ 2014-08-11 11:01 UTC (permalink / raw)


> However I propose to add Element_Access to next RM which would return access 
> to the element in the container.

I doubt this will happen because the access you propose may outlive the object is accesses. This is why there are reference objects.

^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Holders in GNAT and Ada2012
  2014-08-10 13:06  7%   ` Victor Porton
@ 2014-08-10 15:32  7%     ` Simon Wright
  2014-08-11 11:01  7%     ` AdaMagica
  2014-08-11 15:38  7%     ` Adam Beneschan
  2 siblings, 0 replies; 73+ results
From: Simon Wright @ 2014-08-10 15:32 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> One (real World!) usage for this: Interfaces.C.Strings.To_Chars_Ptr
> applied to an element in an indefinite holder of type char_array.

I don't know what your actual usage is, but I'd prefer in general to
keep to Ada types in the application, and only do interfacing at the
edges.

^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Holders in GNAT and Ada2012
  2014-08-09 19:43  7% ` Victor Porton
@ 2014-08-10 13:06  7%   ` Victor Porton
  2014-08-10 15:32  7%     ` Simon Wright
                       ` (2 more replies)
  2014-08-11 23:58  6%   ` Randy Brukardt
  1 sibling, 3 replies; 73+ results
From: Victor Porton @ 2014-08-10 13:06 UTC (permalink / raw)


Victor Porton wrote:

> Victor Porton wrote:
> 
>> I tried to write:
>> 
>> Element(Object)'Access;
>> 
>> for "Object" being a value of an instance of
>> Ada.Containers.Indefinite_Holders.
>> 
>> This does not work because the return type of Element is not aliased.
> 
> By the way, does it makes sense in the next Ada specification to make the
> return type of "Element" function aliased?

Hm, my idea was wrong: Element may return a copy instead of the actual 
element.

However I propose to add Element_Access to next RM which would return access 
to the element in the container.

One (real World!) usage for this: Interfaces.C.Strings.To_Chars_Ptr applied 
to an element in an indefinite holder of type char_array.

>> Then I tried:
>> 
>> Reference(Object).all'Access;
>> 
>> This does not work because in GNAT 4.9 a-coinho.ads source file is not up
>> to date with Ada2012 and there are no Reference function here.
>> 
>> My questions:
>> 
>> 1. How long to wait for GNAT to work with this? (in which GNAT version?)
>> 
>> 2. In a conforming Ada2012 compiler `Reference(Object).all'Access;` is
>> semantically correct, isn't it?
>> 
>> In the meantime, I need to write for my private use a container similar
>> to Ada.Containers.Indefinite_Holders for aliased objects by myself :-(

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Holders in GNAT and Ada2012
  2014-08-09 19:25 14% Ada.Containers.Indefinite_Holders in GNAT and Ada2012 Victor Porton
  2014-08-09 19:43  7% ` Victor Porton
@ 2014-08-09 21:54  7% ` Simon Wright
  1 sibling, 0 replies; 73+ results
From: Simon Wright @ 2014-08-09 21:54 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> This does not work because in GNAT 4.9 a-coinho.ads source file is not up to 
> date with Ada2012 and there are no Reference function here.
>
> My questions:
>
> 1. How long to wait for GNAT to work with this? (in which GNAT version?)

Very likely will be fixed in FSF GCC 4.10, because Reference is present
in GNST GPL 2014.

> In the meantime, I need to write for my private use a container
> similar to Ada.Containers.Indefinite_Holders for aliased objects by
> myself :-(

If it's only for private use you could use the GPL compiler.

^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Holders in GNAT and Ada2012
  2014-08-09 19:25 14% Ada.Containers.Indefinite_Holders in GNAT and Ada2012 Victor Porton
@ 2014-08-09 19:43  7% ` Victor Porton
  2014-08-10 13:06  7%   ` Victor Porton
  2014-08-11 23:58  6%   ` Randy Brukardt
  2014-08-09 21:54  7% ` Simon Wright
  1 sibling, 2 replies; 73+ results
From: Victor Porton @ 2014-08-09 19:43 UTC (permalink / raw)


Victor Porton wrote:

> I tried to write:
> 
> Element(Object)'Access;
> 
> for "Object" being a value of an instance of
> Ada.Containers.Indefinite_Holders.
> 
> This does not work because the return type of Element is not aliased.

By the way, does it makes sense in the next Ada specification to make the 
return type of "Element" function aliased?

> Then I tried:
> 
> Reference(Object).all'Access;
> 
> This does not work because in GNAT 4.9 a-coinho.ads source file is not up
> to date with Ada2012 and there are no Reference function here.
> 
> My questions:
> 
> 1. How long to wait for GNAT to work with this? (in which GNAT version?)
> 
> 2. In a conforming Ada2012 compiler `Reference(Object).all'Access;` is
> semantically correct, isn't it?
> 
> In the meantime, I need to write for my private use a container similar to
> Ada.Containers.Indefinite_Holders for aliased objects by myself :-(
> 
-- 
Victor Porton - http://portonvictor.org


^ permalink raw reply	[relevance 7%]

* Ada.Containers.Indefinite_Holders in GNAT and Ada2012
@ 2014-08-09 19:25 14% Victor Porton
  2014-08-09 19:43  7% ` Victor Porton
  2014-08-09 21:54  7% ` Simon Wright
  0 siblings, 2 replies; 73+ results
From: Victor Porton @ 2014-08-09 19:25 UTC (permalink / raw)


I tried to write:

Element(Object)'Access;

for "Object" being a value of an instance of 
Ada.Containers.Indefinite_Holders.

This does not work because the return type of Element is not aliased.

Then I tried:

Reference(Object).all'Access;

This does not work because in GNAT 4.9 a-coinho.ads source file is not up to 
date with Ada2012 and there are no Reference function here.

My questions:

1. How long to wait for GNAT to work with this? (in which GNAT version?)

2. In a conforming Ada2012 compiler `Reference(Object).all'Access;` is 
semantically correct, isn't it?

In the meantime, I need to write for my private use a container similar to 
Ada.Containers.Indefinite_Holders for aliased objects by myself :-(

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 14%]

* Re: "NULL" returned by a function
  @ 2014-08-09 16:15  6% ` Maciej Sobczak
  0 siblings, 0 replies; 73+ results
From: Maciej Sobczak @ 2014-08-09 16:15 UTC (permalink / raw)


On Friday, August 8, 2014 11:10:28 PM UTC+2, Victor Porton wrote:

> What if I want to make a function which returns either a value of type T or 
> a value signifying "nothing" (like null pointer)?

The Ada.Containers.Indefinite_Holders package can be used to create a return type for such a function.

-- 
Maciej Sobczak * http://www.msobczak.com * http://www.inspirel.com


^ permalink raw reply	[relevance 6%]

* Re: Conditional holder for a type with unknown discriminant
  @ 2012-10-27 17:17  6% ` AdaMagica
  0 siblings, 0 replies; 73+ results
From: AdaMagica @ 2012-10-27 17:17 UTC (permalink / raw)


Can't see why this shouldn't do the trick:

package Owl_Holder is new Ada.Containers.Indefinite_Holders (T);
use Owl_Holder;

type R (Has_Item: Boolean) is record
  case Has_Item is
    when False => null;
    when True  => I: Holder;
  end case;
end record; 


Y: R := F (...);

case Y.Has_Item is
  when False => null;               -- Do nothing
  when True  => P (Y.I.Element);    -- Do whatever you want
                P (Element (Y.I);   -- ditto
                P (Y.I.Reference);  -- ditto using Ada 2012 reference type
                Y.I.Reference       := New_Item;   -- via reference type or
                Y.I.Replace_Element   (New_Item);  -- in traditional way
end case;

(Haven't compiled, but you get the idea:-)




^ permalink raw reply	[relevance 6%]

* Re: API design considerations - variable-length array in record type
  2012-10-08 11:53  0%   ` Maciej Sobczak
@ 2012-10-08 14:37  0%     ` Tero Koskinen
  0 siblings, 0 replies; 73+ results
From: Tero Koskinen @ 2012-10-08 14:37 UTC (permalink / raw)


Hi,

On Mon, 8 Oct 2012 04:53:15 -0700 (PDT)
Maciej Sobczak <see.my.homepage@gmail.com> wrote:
> W dniu poniedziałek, 8 października 2012 13:29:26 UTC+2 użytkownik Egil Høvik napisał:
> 
> > If you don't mind using Ada 2012 packages, there's also Ada.Containers.Indefinite_Holders (RM A.18.18).
> 
> That would be a perfectly justified choice, except for the fact that this is a library code, which is intended for wider use and relying on Ada 2012 would be too constraining.
> Still, a possible approach would be to (re)implement Indefinite_Holders as a supporting package and at some point in the future switch to the standard package with minimal or no impact. I will seriously take it into consideration.

I have variation of Indefinite_Holders implemented in Ada 95 here:
https://bitbucket.org/tkoskine/hauki/src/tip/src/hauki-containers-object_holders.ads
https://bitbucket.org/tkoskine/hauki/src/tip/src/hauki-containers-object_holders.adb

My implementation probably doesn't match Ada 2012 100%, but shows
that it is possible to implemented them in Ada 95 also.

> 
> Regards,
> 
> -- 
> Maciej Sobczak * http://www.msobczak.com * http://www.inspirel.com


-- 
Tero Koskinen - http://iki.fi/tero.koskinen/



^ permalink raw reply	[relevance 0%]

* Re: API design considerations - variable-length array in record type
  2012-10-08 11:29  6% ` Egil Høvik
@ 2012-10-08 11:53  0%   ` Maciej Sobczak
  2012-10-08 14:37  0%     ` Tero Koskinen
  0 siblings, 1 reply; 73+ results
From: Maciej Sobczak @ 2012-10-08 11:53 UTC (permalink / raw)


Hi Egil,

W dniu poniedziałek, 8 października 2012 13:29:26 UTC+2 użytkownik Egil Høvik napisał:

> If you don't mind using Ada 2012 packages, there's also Ada.Containers.Indefinite_Holders (RM A.18.18).

That would be a perfectly justified choice, except for the fact that this is a library code, which is intended for wider use and relying on Ada 2012 would be too constraining.
Still, a possible approach would be to (re)implement Indefinite_Holders as a supporting package and at some point in the future switch to the standard package with minimal or no impact. I will seriously take it into consideration.

Regards,

-- 
Maciej Sobczak * http://www.msobczak.com * http://www.inspirel.com



^ permalink raw reply	[relevance 0%]

* Re: API design considerations - variable-length array in record type
  @ 2012-10-08 11:29  6% ` Egil Høvik
  2012-10-08 11:53  0%   ` Maciej Sobczak
  0 siblings, 1 reply; 73+ results
From: Egil Høvik @ 2012-10-08 11:29 UTC (permalink / raw)


On Monday, October 8, 2012 11:03:04 AM UTC+2, Maciej Sobczak wrote:
> 
> A straightforward choice is a predefined instantiation of Ada.Containers.Vectors for Integer and this would be probably the least surprising, especially in the context of Y : Unbounded_String, but at the same time I'm open to consider some more lightweight alternatives.
> 

If you don't mind using Ada 2012 packages, there's also Ada.Containers.Indefinite_Holders (RM A.18.18).
I haven't used it myself yet, so I can't say anything about how lightweight it is compared to Vector.

-- 
~egilhh



^ permalink raw reply	[relevance 6%]

* Re: discriminant questions
  2011-09-18 12:41  6%               ` ytomino
@ 2011-09-18 13:17  0%                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 73+ results
From: Dmitry A. Kazakov @ 2011-09-18 13:17 UTC (permalink / raw)


On Sun, 18 Sep 2011 05:41:24 -0700 (PDT), ytomino wrote:

>> But you can have P.Element which is much more comfortable. There is no
>> reason to expose access semantics if you can avoid it. And smart pointers
>> are to hide pointers rather than to expose them.

> If it hides semantics of access type,
> Ada.Containers.Indefinite_Holders gives good interface.

One problem of Indefinite_Holders is the definition of "=",  it is wrong
because Holder is declared tagged. When tagged, "=" must be doubly
dispatching. The correct definition should at least be:

   function "=" (Left : Holder; Right : Holder'Class) return Boolean;
        -- Emulates double dispatch by cascaded dispatch

But this is only an indicator of a bigger problem, which is that the design
does not support Element_Type classes. I understand that they didn't want
Holder'Class but must allow it to support prefix notation. This is how
language design problems get reflected in the container design!

Anyway, in my experience smart pointers become almost useless without
classes. I.e. you want a hierarchy of elements accompanied by a hierarchy
of smart pointers/handles/holders (name it as you wish). You also need
*same* set of operations implemented by both, such that operations on the
pointer would be delegated to the object. I.e. you don't want:

   X.Element + Y.Element

you want

   X + Y

instead. Even less you want pseudo-functional mess like:

   X.Update (Invert'Access);

you do

   Invert (X);

> (if reference-counted implementation is provided.
> but http://gcc.gnu.org/svn/gcc/trunk/gcc/ada/a-coinho.adb is not.)

My implementation uses reference counting, because its intended use was to
be a smart pointer. The intended use of Indefinite_Holders is not smart
pointers. It is only a definite wrapper for an indefinite content, only
this nothing more. Smart pointer is also definite, but much more than just
that. From smart pointers you expect them being comparable, delegating
operations, managing shared objects, supporting serialization, task safety
and so on.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* Re: discriminant questions
  @ 2011-09-18 12:41  6%               ` ytomino
  2011-09-18 13:17  0%                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 73+ results
From: ytomino @ 2011-09-18 12:41 UTC (permalink / raw)


> That is. You want to implement the interface of an access type (X.all is a
> part of this interface) by a type which is not access.
Yes.

> Ada does not allow this, unfortunately.
OK.
...If I remove assignment operation like unique_ptr of C++0x, it's
possible.

> My position is that interfaces of all types must be inheritable and
> implementable, including access types, but most people here disagree with
> me.
I agree with you. I want to make multi-precision Big_Integer, more
usable Unbounded_String, etc, too.

> But you can have P.Element which is much more comfortable. There is no
> reason to expose access semantics if you can avoid it. And smart pointers
> are to hide pointers rather than to expose them.
If it hides semantics of access type,
Ada.Containers.Indefinite_Holders gives good interface.
(if reference-counted implementation is provided.
but http://gcc.gnu.org/svn/gcc/trunk/gcc/ada/a-coinho.adb is not.)



^ permalink raw reply	[relevance 6%]

* Re: Use of abstract tagged types without access types -- again and complete
  2011-06-10 15:43  0%     ` Prof. Dr. Carl Weierstrass
@ 2011-06-12 12:05  0%       ` Alex R. Mosteo
  0 siblings, 0 replies; 73+ results
From: Alex R. Mosteo @ 2011-06-12 12:05 UTC (permalink / raw)


Prof. Dr. Carl Weierstrass wrote:

> On 9 Jun., 23:06, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
>> "Ludovic Brenta" <ludo...@ludovic-brenta.org> wrote in message
>>
>> news:87hb7yn4fs.fsf@ludovic-brenta.org...
>>
>> > "Prof. Dr. Carl Weierstrass" writes on comp.lang.ada:
>> >> type Parent_Type is new Ada.Finalization.Controlled with record
>> >> Child : Child_Type'Class;
>> >> end record;
>>
>> >> This doesn't work, because:
>> >> class-wide subtype with unknown discriminants in component declaration
>>
>> >> Of course I could use an access type to avoid the error but is there a
>> >> way to do something like this without access types.
>>
>> > No.  The reason is that the size of Child is unknown, so you cannot
>> > encapsulate a Child into a Parent_Type, which has a fixed size.  In
>> > contrast, the size of an access value is fixed at comile time, so you
>> > can encapsulate an access value in the Parent_Type.
>>
>> Not quite accurrate -- an access type is necessary somewhere, but it
>> doesn't have to be visible.
>>
>> Specifically, use the Holder container for this purpose:
>>
>> package Child_Holder is new Ada.Containers.Indefinite_Holders
>> (Child_Type'Class);
>>
>> type Parent_Type is new Ada.Finalization.Controlled with record
>> Child : Child_Holder.Holder;
>> end record;
>>
>> This is a slight complication when using the component (you have to use
>> Element and Replace_Element to access the contents), but it is usually
>> better than writing all of this storage management yourself.
>>
>> The only downside is whether your Ada compiler supports this container
>> (it was added after Ada 2005 was finished, early in the Ada 2012
>> process). It's used in the latest ASIS (that's why it was invented), so a
>> compiler supporting ASIS for Ada 2005 probably supports the container.
>>
>> If your compiler doesn't yet support this container, it's easy enough to
>> create it yourself rather than using explicit access types.
>>
>> Randy.
> 
> Thank you very much. I think that this could be the solution that I
> was looking for.
> In case of many children I considered using an
> Ada.Containers.Indefinite_Vectors type,
> but I was looking for a solution when the is only one child.
> Unfortunately I'am using
> GNAT GPL 2010 and can't find that container in the library.
> 
> Any idea, where I can find an implementation? I hope it will be in the
> next GNAT GPL 2011
> version.

I've been using this 'holder' approach for years. If you don't have the 
official, the simplest way is to make your own with any other of the 
standard containers, and a simplified spec.

Migration to the true Holder would later be a matter of seconds with a 
single search/replace if you take care to respect the subprogram names.

> 
> Regards




^ permalink raw reply	[relevance 0%]

* Re: Use of abstract tagged types without access types -- again and complete
  2011-06-09 21:06  5%   ` Randy Brukardt
@ 2011-06-10 15:43  0%     ` Prof. Dr. Carl Weierstrass
  2011-06-12 12:05  0%       ` Alex R. Mosteo
  0 siblings, 1 reply; 73+ results
From: Prof. Dr. Carl Weierstrass @ 2011-06-10 15:43 UTC (permalink / raw)


On 9 Jun., 23:06, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
> "Ludovic Brenta" <ludo...@ludovic-brenta.org> wrote in message
>
> news:87hb7yn4fs.fsf@ludovic-brenta.org...
>
> > "Prof. Dr. Carl Weierstrass" writes on comp.lang.ada:
> >>    type Parent_Type is new Ada.Finalization.Controlled with record
> >>          Child : Child_Type'Class;
> >>    end record;
>
> >> This doesn't work, because:
> >> class-wide subtype with unknown discriminants in component declaration
>
> >> Of course I could use an access type to avoid the error but is there a
> >> way to do something like this without access types.
>
> > No.  The reason is that the size of Child is unknown, so you cannot
> > encapsulate a Child into a Parent_Type, which has a fixed size.  In
> > contrast, the size of an access value is fixed at comile time, so you
> > can encapsulate an access value in the Parent_Type.
>
> Not quite accurrate -- an access type is necessary somewhere, but it doesn't
> have to be visible.
>
> Specifically, use the Holder container for this purpose:
>
>      package Child_Holder is new Ada.Containers.Indefinite_Holders
> (Child_Type'Class);
>
>      type Parent_Type is new Ada.Finalization.Controlled with record
>            Child : Child_Holder.Holder;
>      end record;
>
> This is a slight complication when using the component (you have to use
> Element and Replace_Element to access the contents), but it is usually
> better than writing all of this storage management yourself.
>
> The only downside is whether your Ada compiler supports this container (it
> was added after Ada 2005 was finished, early in the Ada 2012 process). It's
> used in the latest ASIS (that's why it was invented), so a compiler
> supporting ASIS for Ada 2005 probably supports the container.
>
> If your compiler doesn't yet support this container, it's easy enough to
> create it yourself rather than using explicit access types.
>
>                                              Randy.

Thank you very much. I think that this could be the solution that I
was looking for.
In case of many children I considered using an
Ada.Containers.Indefinite_Vectors type,
but I was looking for a solution when the is only one child.
Unfortunately I'am using
GNAT GPL 2010 and can't find that container in the library.

Any idea, where I can find an implementation? I hope it will be in the
next GNAT GPL 2011
version.

Regards



^ permalink raw reply	[relevance 0%]

* Re: Use of abstract tagged types without access types -- again and complete
  @ 2011-06-09 21:06  5%   ` Randy Brukardt
  2011-06-10 15:43  0%     ` Prof. Dr. Carl Weierstrass
  0 siblings, 1 reply; 73+ results
From: Randy Brukardt @ 2011-06-09 21:06 UTC (permalink / raw)


"Ludovic Brenta" <ludovic@ludovic-brenta.org> wrote in message 
news:87hb7yn4fs.fsf@ludovic-brenta.org...
> "Prof. Dr. Carl Weierstrass" writes on comp.lang.ada:
>>    type Parent_Type is new Ada.Finalization.Controlled with record
>>          Child : Child_Type'Class;
>>    end record;
>>
>> This doesn't work, because:
>> class-wide subtype with unknown discriminants in component declaration
>>
>> Of course I could use an access type to avoid the error but is there a
>> way to do something like this without access types.
>
> No.  The reason is that the size of Child is unknown, so you cannot
> encapsulate a Child into a Parent_Type, which has a fixed size.  In
> contrast, the size of an access value is fixed at comile time, so you
> can encapsulate an access value in the Parent_Type.

Not quite accurrate -- an access type is necessary somewhere, but it doesn't 
have to be visible.

Specifically, use the Holder container for this purpose:

     package Child_Holder is new Ada.Containers.Indefinite_Holders 
(Child_Type'Class);

     type Parent_Type is new Ada.Finalization.Controlled with record
           Child : Child_Holder.Holder;
     end record;

This is a slight complication when using the component (you have to use 
Element and Replace_Element to access the contents), but it is usually 
better than writing all of this storage management yourself.

The only downside is whether your Ada compiler supports this container (it 
was added after Ada 2005 was finished, early in the Ada 2012 process). It's 
used in the latest ASIS (that's why it was invented), so a compiler 
supporting ASIS for Ada 2005 probably supports the container.

If your compiler doesn't yet support this container, it's easy enough to 
create it yourself rather than using explicit access types.

                                             Randy.





^ permalink raw reply	[relevance 5%]

* Re: Newbie question -- dereferencing access
  @ 2009-03-13 17:33  7%               ` Martin
  0 siblings, 0 replies; 73+ results
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	[relevance 7%]

Results 1-73 of 73 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
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 12:13         ` christoph.grein
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 17:33  7%               ` Martin
2011-06-09 17:50     Use of abstract tagged types without access types -- again and complete Prof. Dr. Carl Weierstrass
2011-06-09 20:19     ` Ludovic Brenta
2011-06-09 21:06  5%   ` Randy Brukardt
2011-06-10 15:43  0%     ` Prof. Dr. Carl Weierstrass
2011-06-12 12:05  0%       ` Alex R. Mosteo
2011-09-17 16:30     discriminant questions ytomino
2011-09-17 17:19     ` Dmitry A. Kazakov
2011-09-17 17:46       ` ytomino
2011-09-17 19:41         ` Dmitry A. Kazakov
2011-09-17 22:55           ` ytomino
2011-09-18  8:50             ` Dmitry A. Kazakov
2011-09-18 10:54               ` ytomino
2011-09-18 11:35                 ` Dmitry A. Kazakov
2011-09-18 12:41  6%               ` ytomino
2011-09-18 13:17  0%                 ` Dmitry A. Kazakov
2012-10-08  9:03     API design considerations - variable-length array in record type Maciej Sobczak
2012-10-08 11:29  6% ` Egil Høvik
2012-10-08 11:53  0%   ` Maciej Sobczak
2012-10-08 14:37  0%     ` Tero Koskinen
2012-10-27  2:50     Conditional holder for a type with unknown discriminant Yannick Duchêne (Hibou57)
2012-10-27 17:17  6% ` AdaMagica
2014-08-08 21:10     "NULL" returned by a function Victor Porton
2014-08-09 16:15  6% ` Maciej Sobczak
2014-08-09 19:25 14% Ada.Containers.Indefinite_Holders in GNAT and Ada2012 Victor Porton
2014-08-09 19:43  7% ` Victor Porton
2014-08-10 13:06  7%   ` Victor Porton
2014-08-10 15:32  7%     ` Simon Wright
2014-08-11 11:01  7%     ` AdaMagica
2014-08-11 15:38  7%     ` Adam Beneschan
2014-08-11 23:58  6%   ` Randy Brukardt
2014-08-09 21:54  7% ` Simon Wright
2015-08-11 21:53     storage error: stack overflow hreba
2015-08-18  2:16     ` hreba
2015-08-18  7:24       ` Egil H H
2015-08-18 12:23         ` hreba
2015-08-18 12:37           ` Jacob Sparre Andersen
2015-08-18 14:02             ` hreba
2015-08-18 14:16               ` Jeffrey R. Carter
2015-08-18 20:56  6%             ` Randy Brukardt
2016-05-25 21:24     Advice, tasking and hardware patrick
2016-05-26  7:26     ` Dmitry A. Kazakov
2016-05-26 19:35       ` Jeffrey R. Carter
2016-05-27  7:50         ` Dmitry A. Kazakov
2016-05-27 19:13  5%       ` Shark8
2016-05-27 20:27  0%         ` Dmitry A. Kazakov
2016-05-27 22:27  0%           ` Randy Brukardt
2016-06-13  8:22  6% Memory leak in Indefinite_Holders Alejandro R. Mosteo
2016-06-13  9:45  0% ` Alejandro R. Mosteo
2016-09-05 19:04     Updated PragmAda Reusable Components PragmAda Software Engineering
2016-09-07 10:45  6% ` Alejandro R. Mosteo
2016-09-07 17:51  0%   ` Jeffrey R. Carter
2016-09-09 20:24  5% Are mutually dependant and possibly recursive types using Containers possible? Shark8
2016-09-09 20:40  0% ` Jeffrey R. Carter
2017-04-18  6:31     Is there a reason System.Storage_Pools isn't Pure? Shark8
2017-04-18 18:32     ` Randy Brukardt
2017-04-18 23:42  5%   ` Shark8
2017-04-19 20:36  0%     ` Randy Brukardt
2017-08-05 13:41  7% Need a way to convert a constant to a variable Victor Porton
2017-08-05 14:48  8% ` Dmitry A. Kazakov
2017-08-05 15:11  0%   ` Victor Porton
2017-08-05 15:41  7% ` Jeffrey R. Carter
2017-08-05 16:25  0%   ` Victor Porton
2017-08-05 17:59  0% ` Per Sandberg
2017-08-31 12:12  4% Interest in standard smart pointers for Ada 2020 Alejandro R. Mosteo
2017-09-21 18:14 12% Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders Victor Porton
2017-09-21 21:30  7% ` AdaMagica
2017-09-22 12:16  7%   ` Victor Porton
2017-09-22 19:25  7%     ` Simon Wright
2017-09-22 22:15  7%       ` Victor Porton
2017-09-23  8:09  6%         ` Dmitry A. Kazakov
2017-09-23  9:16  5%           ` Jeffrey R. Carter
2017-10-03  0:15  7%             ` Randy Brukardt
2017-11-15  0:00 13% Ada.Containers.Indefinite_Holders and limited types Victor Porton
2017-11-15  7:52  7% ` Simon Wright
2017-11-15  8:35  7% ` Dmitry A. Kazakov
2017-11-15 22:24  6%   ` Randy Brukardt
2017-11-26 23:00  7% How discriminants interplay with derived tagged types? Victor Porton
2018-01-31 12:06  7% Indefinite_Holders: bug or misunderstanding? Alejandro R. Mosteo
2019-10-14 19:41     How to transfer Class-Wide object to a Task ? William FRANCK
2019-10-14 19:58     ` Dmitry A. Kazakov
2019-10-14 20:58       ` William FRANCK
2019-10-15  4:40  8%     ` Per Sandberg
2019-10-15  5:40  0%       ` William FRANCK
2019-10-16 20:04  6%       ` William FRANCK
2019-10-17  9:28  7%         ` William FRANCK
2019-10-15 14:31         ` Optikos
2019-10-15 19:41  5%       ` William FRANCK
2019-10-14 20:21     ` William FRANCK
2019-10-14 21:57  4%   ` Shark8
2019-10-15  5:43  0%     ` William FRANCK
2019-12-04 13:56     Type naming conventions: Any_Foo Alejandro R. Mosteo
2019-12-04 14:52     ` Lucretia
2019-12-04 16:42       ` Alejandro R. Mosteo
2019-12-05 10:51         ` AdaMagica
2019-12-05 17:27           ` Jeffrey R. Carter
2019-12-05 17:45             ` Dmitry A. Kazakov
2019-12-05 20:03               ` Jeffrey R. Carter
2019-12-05 21:51  7%             ` Dmitry A. Kazakov
2019-12-06 20:18  0%               ` Jeffrey R. Carter
2019-12-06 20:35  0%                 ` Dmitry A. Kazakov
2019-12-07  0:57  0%                   ` Randy Brukardt
2020-03-23 23:16     GNAT vs Matlab - operation on multidimensional complex matrices darek
2020-06-08 17:42  3% ` Shark8
2020-04-03 22:48     Proposal: Auto-allocation of Indefinite Objects Stephen Davies
2020-07-27  7:47     ` Yannick Moy
2020-07-27 17:48       ` Brian Drummond
2020-07-27 20:31  6%     ` Jeffrey R. Carter
2021-02-20 15:26     set_index and and end_of_file with just a stream reference Mehdi Saada
2021-02-20 16:04     ` Dmitry A. Kazakov
2021-02-20 16:22       ` Mehdi Saada
2021-02-20 16:30         ` Mehdi Saada
2021-02-20 17:59           ` Dmitry A. Kazakov
2021-02-20 19:08             ` Mehdi Saada
2021-02-23 17:21  5%           ` Shark8
2021-04-17 21:45     Unchecked_Deallocation with tagged types DrPi
2021-04-18  8:21     ` Dmitry A. Kazakov
2021-04-18  8:46       ` Gautier write-only address
2021-04-18  9:09         ` Jeffrey R. Carter
2021-04-18 10:20           ` J-P. Rosen
2021-04-18 10:34             ` Dmitry A. Kazakov
2021-04-18 15:14               ` J-P. Rosen
2021-04-18 15:23                 ` Gautier write-only address
2021-04-20 18:53                   ` Randy Brukardt
2021-04-20 19:35                     ` Dmitry A. Kazakov
2022-04-18  5:51  5%                   ` Thomas
2021-04-20 20:32                     ` Jeffrey R. Carter
2021-04-20 21:10                       ` Niklas Holsti
2021-04-24  0:49                         ` Randy Brukardt
2022-04-18  1:51  6%                       ` Thomas
2021-04-17 22:03     Ada and Unicode DrPi
2021-04-19  9:08     ` Stephen Leake
2021-04-19 11:56       ` Luke A. Guest
2021-04-19 12:52         ` Dmitry A. Kazakov
2021-04-19 13:00           ` Luke A. Guest
2021-04-20 19:06             ` Randy Brukardt
2022-04-03 18:37               ` Thomas
2022-04-04 23:52                 ` Randy Brukardt
2023-03-31  3:06  4%               ` Thomas
2023-04-01 10:18  0%                 ` Randy Brukardt
2021-05-03 16:08     GCC 11 bug? lawyer needed Simon Wright
2021-05-05  3:54     ` Randy Brukardt
2021-05-05 10:01       ` AdaMagica
2021-05-05 16:10         ` AdaMagica
2021-05-06  0:39           ` Randy Brukardt
2021-05-06 20:02  7%         ` Simon Wright
2021-05-06 20:51  0%           ` Dmitry A. Kazakov
2021-05-06 23:59  0%           ` Randy Brukardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox