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: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-16 15:00  0%             ` Marius Amado-Alves
  2022-09-16 15:42  8%               ` Egil H H
@ 2022-09-16 18:53  0%               ` Björn Lundin
  1 sibling, 0 replies; 52+ results
From: Björn Lundin @ 2022-09-16 18:53 UTC (permalink / raw)


On 2022-09-16 17:00, Marius Amado-Alves wrote:
>>>> "for X of M loop ... end loop".
>>>
>>> Not possible for maps.
>> but you can as
>>> https://programming-idioms.org/idiom/13/iterate-over-map-keys-and-value/1511/ada>
>>
>> with Ada.Containers.Indefinite_Hashed_Maps;
>> with Ada.Strings.Hash;
>> use Ada.Containers;
>> for C in My_Map.Iterate loop
>> Put_Line ("Key = " & Key (C) & ", Value = " & Element (C));
>> end loop;
> 
> Thanks, but this is "in", not "of", requires cursors, and DOES NOT COMPILE, as probably needs like ten lines of boiler plate not show.

well, yes . I thought the for looping stuff was the important part, 
since you done want to call Next.

in or of - does it really matter here?

   for C in My_Map.Iterate loop
or
   for C of My_Map loop
is not that hurtful to my eyes.

   for K,V in My_Map.Iterate loop
or
   for K,V of My_Map loop

getting Key and Value as a tuple would be nicer of course


Anyway, I forgot to instantiate the map. Here's a compileable variant



It outputs
Key = AA, Value =  1
Key = AB, Value =  5

----------------

with Ada.Containers.Hashed_Maps;
with Ada.Strings.Hash;
use Ada.Containers;
with Text_Io ; use Text_IO;

procedure Ite is

   subtype Test_Type is String(1..2);

   package Test_Map_Pkg is new Ada.Containers.Hashed_Maps
     (Test_Type,
      Integer,
      Ada.Strings.Hash,
      "=",
      "=");

   My_Map : Test_Map_Pkg.Map;
   use Test_Map_Pkg;
begin
   My_Map.Insert("AA",1);
   My_Map.Insert("AB",5);

   for C in My_Map.Iterate loop
     Put_Line ("Key = " & Key (C) & ", Value = " & Element (C)'Img);
   end loop;

end Ite;



-- 
/Björn

^ permalink raw reply	[relevance 0%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-16 15:00  0%             ` Marius Amado-Alves
@ 2022-09-16 15:42  8%               ` Egil H H
  2022-09-16 18:53  0%               ` Björn Lundin
  1 sibling, 0 replies; 52+ results
From: Egil H H @ 2022-09-16 15:42 UTC (permalink / raw)


On Friday, September 16, 2022 at 5:00:29 PM UTC+2, amado...@gmail.com wrote:
> > >> "for X of M loop ... end loop". 
> > > 
> > > Not possible for maps. 
> > but you can as 
> > >https://programming-idioms.org/idiom/13/iterate-over-map-keys-and-value/1511/ada> 
> >
> > with Ada.Containers.Indefinite_Hashed_Maps; 
> > with Ada.Strings.Hash; 
> > use Ada.Containers; 
> > for C in My_Map.Iterate loop 
> > Put_Line ("Key = " & Key (C) & ", Value = " & Element (C)); 
> > end loop;
> Thanks, but this is "in", not "of", requires cursors, and DOES NOT COMPILE, as probably needs like ten lines of boiler plate not show.

(sorry for any botched formatting...)

with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;
with Ada.Text_IO;

procedure Iteration is
   package My_Maps is 
      new Ada.Containers.Indefinite_Hashed_Maps
         (String, Integer, Ada.Strings.Hash, "=");
   
   My_Map : My_Maps.Map;
begin
   My_Map.Include("One", 1);
   My_Map.Include("Two", 2);
   My_Map.Include("Three", 3);

   for C in My_Map.Iterate loop
      Ada.Text_IO.Put_Line(My_Maps.Key(C) & My_Maps.Element(C)'Image);
   end loop;
   
   for Element of My_Map loop
      Ada.Text_IO.Put_Line(Element'Image);
   end loop;
   
   -- Ada_2022:
   -- for (C : My_Maps.Cursor) of My_Map.Iterate loop
   --    Ada.Text_IO.Put_Line(My_Maps.Key(C) & My_Maps.Element(C)'Image);
   -- end loop Ada_2022;
   
end Iteration;

I don't know why they left out a two-parameter version of the Iterate procedure for Ada 2022 Maps,
   -- for (Key, Element) of My_Map.Iterate loop
would've been nice, just like
   -- for (Name, Val) of Ada.Environment_Variables.Iterate(<>) loop



^ permalink raw reply	[relevance 8%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  2022-09-16 11:33  7%           ` Björn Lundin
@ 2022-09-16 15:00  0%             ` Marius Amado-Alves
  2022-09-16 15:42  8%               ` Egil H H
  2022-09-16 18:53  0%               ` Björn Lundin
  0 siblings, 2 replies; 52+ results
From: Marius Amado-Alves @ 2022-09-16 15:00 UTC (permalink / raw)


> >> "for X of M loop ... end loop". 
> > 
> > Not possible for maps.
> but you can as 
> >https://programming-idioms.org/idiom/13/iterate-over-map-keys-and-value/1511/ada> 
> 
> with Ada.Containers.Indefinite_Hashed_Maps; 
> with Ada.Strings.Hash; 
> use Ada.Containers; 
> for C in My_Map.Iterate loop 
> Put_Line ("Key = " & Key (C) & ", Value = " & Element (C)); 
> end loop; 

Thanks, but this is "in", not "of", requires cursors, and DOES NOT COMPILE, as probably needs like ten lines of boiler plate not show.

^ permalink raw reply	[relevance 0%]

* Re: Non-standard functions in GNAT's Ada.Containers packages?
  @ 2022-09-16 11:33  7%           ` Björn Lundin
  2022-09-16 15:00  0%             ` Marius Amado-Alves
  0 siblings, 1 reply; 52+ results
From: Björn Lundin @ 2022-09-16 11:33 UTC (permalink / raw)


On 2022-09-15 19:11, Marius Amado-Alves wrote:
> Thanks, Niklas.
> 
>> ... There are functions First and Next ... procedure Iterate ...
> 
> Too verbose and error-prone (forget the Next and you get an endless loop).
> 
>> "for X of M loop ... end loop".
> 
> Not possible for maps.


but you can as
 >https://programming-idioms.org/idiom/13/iterate-over-map-keys-and-value/1511/ada>

shows (as below)

--Access each key k with its value x from an associative array mymap,
-- and print them.

with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;

use Ada.Containers;

for C in My_Map.Iterate loop
    Put_Line ("Key = " & Key (C) & ", Value = " & Element (C));
end loop;



-- 
/Björn

^ permalink raw reply	[relevance 7%]

* Re: How to Iterate over all elements of a hashed_map.
  2019-10-29 15:02  0%   ` joakimds
@ 2019-10-29 21:56  0%     ` Randy Brukardt
  0 siblings, 0 replies; 52+ results
From: Randy Brukardt @ 2019-10-29 21:56 UTC (permalink / raw)


<joakimds@kth.se> wrote in message 
news:1559a685-7483-4f2f-8674-d7b61c23bfe8@googlegroups.com...
> Den tisdag 29 oktober 2019 kl. 15:20:43 UTC+1 skrev Alain De Vos:
>> I found code which takes a different approach, here there is a function 
>> .Iterate public ... ,
>>
>> with Ada.Containers.Indefinite_Hashed_Maps;
>> with Ada.Strings.Hash;
>>
>> with Ada.Text_IO; use Ada.Text_IO;
>>
>> procedure Show_Hashed_Map is
>>
>>    package Integer_Hashed_Maps is new
>>      Ada.Containers.Indefinite_Hashed_Maps
>>        (Key_Type        => String,
>>         Element_Type    => Integer,
>>         Hash            => Ada.Strings.Hash,
>>         Equivalent_Keys => "=");
>>
>>    use Integer_Hashed_Maps;
>>
>>    M : Map;
>>    --  Same as:  M : Integer_Hashed_Maps.Map;
>> begin
>>    M.Include ("Alice", 24);
>>    M.Include ("John",  40);
>>    M.Include ("Bob",   28);
>>
>>    if M.Contains ("Alice") then
>>       Put_Line ("Alice's age is "
>>                 & Integer'Image (M ("Alice")));
>>    end if;
>>
>>    --  Update Alice's age
>>    --  Key must already exist in M.
>>    --  Otherwise an exception is raised.
>>    M ("Alice") := 25;
>>
>>    New_Line; Put_Line ("Name & Age:");
>>    for C in M.Iterate loop
>>       Put_Line (Key (C) & ": " & Integer'Image (M (C)));
>>    end loop;
>>
>> end Show_Hashed_Map;
>
> I confirm that when you want to iterate over a hashed map and want both 
> key and value you need to use the .Iterate function as you do in the 
> example.

That's the reason it exists, of course. Not everything makes sense just with 
elements alone. (A cursor-based iterator is also much more like the existing 
iteration of Ada 95 than the element-based iterators of Ada 2005 and later.)

                          Randy. 



^ permalink raw reply	[relevance 0%]

* Re: How to Iterate over all elements of a hashed_map.
  2019-10-29 14:20  8% ` Alain De Vos
@ 2019-10-29 15:02  0%   ` joakimds
  2019-10-29 21:56  0%     ` Randy Brukardt
  0 siblings, 1 reply; 52+ results
From: joakimds @ 2019-10-29 15:02 UTC (permalink / raw)


Den tisdag 29 oktober 2019 kl. 15:20:43 UTC+1 skrev Alain De Vos:
> I found code which takes a different approach, here there is a function .Iterate public ... ,
> 
> with Ada.Containers.Indefinite_Hashed_Maps;
> with Ada.Strings.Hash;
> 
> with Ada.Text_IO; use Ada.Text_IO;
> 
> procedure Show_Hashed_Map is
> 
>    package Integer_Hashed_Maps is new
>      Ada.Containers.Indefinite_Hashed_Maps
>        (Key_Type        => String,
>         Element_Type    => Integer,
>         Hash            => Ada.Strings.Hash,
>         Equivalent_Keys => "=");
> 
>    use Integer_Hashed_Maps;
> 
>    M : Map;
>    --  Same as:  M : Integer_Hashed_Maps.Map;
> begin
>    M.Include ("Alice", 24);
>    M.Include ("John",  40);
>    M.Include ("Bob",   28);
> 
>    if M.Contains ("Alice") then
>       Put_Line ("Alice's age is "
>                 & Integer'Image (M ("Alice")));
>    end if;
> 
>    --  Update Alice's age
>    --  Key must already exist in M.
>    --  Otherwise an exception is raised.
>    M ("Alice") := 25;
> 
>    New_Line; Put_Line ("Name & Age:");
>    for C in M.Iterate loop
>       Put_Line (Key (C) & ": " & Integer'Image (M (C)));
>    end loop;
> 
> end Show_Hashed_Map;

I confirm that when you want to iterate over a hashed map and want both key and value you need to use the .Iterate function as you do in the example.

Best regards,
Joakim

^ permalink raw reply	[relevance 0%]

* Re: How to Iterate over all elements of a hashed_map.
  @ 2019-10-29 14:20  8% ` Alain De Vos
  2019-10-29 15:02  0%   ` joakimds
  0 siblings, 1 reply; 52+ results
From: Alain De Vos @ 2019-10-29 14:20 UTC (permalink / raw)


I found code which takes a different approach, here there is a function .Iterate public ... ,

with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;

with Ada.Text_IO; use Ada.Text_IO;

procedure Show_Hashed_Map is

   package Integer_Hashed_Maps is new
     Ada.Containers.Indefinite_Hashed_Maps
       (Key_Type        => String,
        Element_Type    => Integer,
        Hash            => Ada.Strings.Hash,
        Equivalent_Keys => "=");

   use Integer_Hashed_Maps;

   M : Map;
   --  Same as:  M : Integer_Hashed_Maps.Map;
begin
   M.Include ("Alice", 24);
   M.Include ("John",  40);
   M.Include ("Bob",   28);

   if M.Contains ("Alice") then
      Put_Line ("Alice's age is "
                & Integer'Image (M ("Alice")));
   end if;

   --  Update Alice's age
   --  Key must already exist in M.
   --  Otherwise an exception is raised.
   M ("Alice") := 25;

   New_Line; Put_Line ("Name & Age:");
   for C in M.Iterate loop
      Put_Line (Key (C) & ": " & Integer'Image (M (C)));
   end loop;

end Show_Hashed_Map;


^ permalink raw reply	[relevance 8%]

* Re: Can anyone build AWS on Windows?
       [not found]     <8ac0299b-1935-46f9-962a-57fb710e8cf7@googlegroups.com>
@ 2014-10-01 18:16  4% ` Björn Lundin
  0 siblings, 0 replies; 52+ results
From: Björn Lundin @ 2014-10-01 18:16 UTC (permalink / raw)


On 2014-10-01 18:34, David Botton wrote:
> Since I haven't found a volunteer to try gnoga on windows I setup a Win box and... AWS doesn't compile. Makefile issues. I am using CygWin and GNAT-GPL 2014.
> 
> Has anyone managed to get it to compile and run?
> 
> Thanks
> David Botton
> 

I run mingw

from a cmd-prompt, I start bash

c:\bnl\tmp>bash
I set the prefix in makefile.conf to

prefix	 = /c/bnl/tools/aws/3.1.0w

mkdir -p c:/bnl/tools/aws/3.1.0w

make setup
make
make install


this is with gnat pro 7.1.1


then I - in cmd-prompt

set ADA_PROJECT_PATH=%ADA_PROJECT_PATH%;c:\bnl\tools\aws\3.1.0w
cd to gnoga dir
make


>make
mkdir bin
mkdir obj
mkdir lib
cd src && gprbuild -Pgnoga.gpr
gcc -c -gnatyabcefhiklmnprst -E gnoga.adb
gnoga.adb:86:07: (style) misplaced "then"
gcc -c -gnatyabcefhiklmnprst -E gnoga-types.adb
gnoga-types.adb:111:15: warning: "Index" is only defined in Ada 2005
gnoga-types.ads:41:17: warning: "Ada.Strings.Hash" is an Ada 2005 unit
gnoga-types.ads:42:20: warning: "Ada.Containers.Indefinite_Vectors" is
an Ada 20
05 unit
gnoga-types.ads:43:20: warning: "Ada.Containers.Indefinite_Hashed_Maps"
is an Ad
a 2005 unit
gcc -c -gnatyabcefhiklmnprst -E gnoga-server.ads
gcc -c -gnatyabcefhiklmnprst -E gnoga-server-model.adb
gnoga-server-model.ads:49:20: access-to-constant is an Ada 2005 extension
gnoga-server-model.ads:49:20: unit should be compiled with -gnat05 switch
gnoga-server-model.ads:53:04: overriding indicator is an Ada 2005 extension
gnoga-server-model.ads:53:04: unit must be compiled with -gnat05 switch
gnoga-server-model.ads:121:20: access-to-constant is an Ada 2005 extension
gnoga-server-model.ads:121:20: unit should be compiled with -gnat05 switch
gprbuild: *** compilation phase failed
make: *** [gnoga] Error 4


added "-gnat05" in all .gpr files



>make
cd src && gprbuild -Pgnoga.gpr
cd demo/snake && gprbuild
using project file snake.gpr
gcc -c -E -gnat05 snake-main.adb
gcc -c -E -gnat05 snake.ads
gcc -c -E -gnat05 snake-connection.adb
gprbind snake-main.bexch
gnatbind snake-main.ali
gcc -c b__snake-main.adb
gcc snake-main.o -o snake.exe
cd demo/adablog && gprbuild
using project file adablog.gpr
gcc -c -E -gnat05 adablog-main.adb
gcc -c -E -gnat05 adablog.ads
gcc -c -E -gnat05 adablog-controller.adb
gcc -c -E -gnat05 adablog-migrations.adb
gcc -c -E -gnat05 adablog-model.ads
gcc -c -E -gnat05 adablog-view.adb
gprbind adablog-main.bexch
gnatbind adablog-main.ali
gcc -c b__adablog-main.adb
gcc adablog-main.o -o adablog.exe
c:/bnl/tools/gnat/7.1.1/bin/../libexec/gcc/i686-pc-mingw32/4.7.3/ld.exe:
cannot
find -lsqlite3
collect2.exe: error: ld returned 1 exit status
gprbuild: link of adablog-main.adb failed
make: *** [adablog] Error 4

well, I do not have sql-lite installed

I get snake.exe though.
Running that, it works - but I do have the same issues as Niklas Holsti
described, arrow keys are not working.
Score of 40...


I know that git is the coolest thing ever, but I've seen some projects
where one can choose between git and svn.

It would be nice to access the code via svn too.
I now got a tar.gz snapshot, that won't update easy



-- 
--
Björn


^ permalink raw reply	[relevance 4%]

* Re: Strange compile-time error  with Ada.Containers.Indefinite_Hashed_Maps
  2014-05-25 18:28  7%           ` björn lundin
@ 2014-05-26  8:53  7%             ` J-P. Rosen
  0 siblings, 0 replies; 52+ results
From: J-P. Rosen @ 2014-05-26  8:53 UTC (permalink / raw)


Le 25/05/2014 20:28, björn lundin a écrit :

>> ... and change some variables in the registry,
> ? What variables?
PATH, and some variables that I used to account for a bug workaround in
older Gnat versions (the latter is obsolete now).

>> and use the special program that I wrote (available on Adalog's
>> site) to notify all open windows that some registry variables have
>> changed. Doable, but it took me some time to figure out...
> 
> Hmm, perhaps open windows need that. But usually, I just start a new
> command prompt, and issue
> 
> set PATH=\path\to\the\gnat\I\like\to\use;%PATH%
> 
Different use case. Here you change your Gnat only for the current
terminal. I want it changed for all future sessions, including when I
start GPS by clicking on a .gpr file.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

^ permalink raw reply	[relevance 7%]

* Re: Strange compile-time error  with Ada.Containers.Indefinite_Hashed_Maps
  2014-05-21  5:04  7%         ` J-P. Rosen
@ 2014-05-25 18:28  7%           ` björn lundin
  2014-05-26  8:53  7%             ` J-P. Rosen
  0 siblings, 1 reply; 52+ results
From: björn lundin @ 2014-05-25 18:28 UTC (permalink / raw)


Den onsdagen den 21:e maj 2014 kl. 07:04:46 UTC+2 skrev J-P. Rosen:
> > But then again I just use gnat as cli tool, so managing
> > PATHS are simple
> 
> ... and change some variables in the registry, 

? What variables?

> and use the special
> program that I wrote (available on Adalog's site) to notify all open
> windows that some registry variables have changed. Doable, but it took
> me some time to figure out...

Hmm, perhaps open windows need that.
But usually, I just start a new command prompt,
and issue 

set PATH=\path\to\the\gnat\I\like\to\use;%PATH%

and then it works. That is it.
Of course other open windows lives in their own environment
so they do not see the path change.
But a .bat file that lets me pick a gnat version,
and then a suitable set command as above, is pretty simple.
And for cli, at least I find it to be enough.

--
/Björn

^ permalink raw reply	[relevance 7%]

* Re: Strange compile-time error  with Ada.Containers.Indefinite_Hashed_Maps
  2014-05-20 20:47  7%       ` björn lundin
@ 2014-05-21  5:04  7%         ` J-P. Rosen
  2014-05-25 18:28  7%           ` björn lundin
  0 siblings, 1 reply; 52+ results
From: J-P. Rosen @ 2014-05-21  5:04 UTC (permalink / raw)


Le 20/05/2014 22:47, björn lundin a écrit :
> Den måndagen den 19:e maj 2014 kl. 23:27:07 UTC+2 skrev J-P. Rosen:
>> (of course, managing several versions of Gnat under Windows > >is a bit more challenging...)
> 
> Not really, just change the PATH
> But then again I just use gnat as cli tool, so managing
> PATHS are simple

... and change some variables in the registry, and use the special
program that I wrote (available on Adalog's site) to notify all open
windows that some registry variables have changed. Doable, but it took
me some time to figure out...


-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

^ permalink raw reply	[relevance 7%]

* Re: Strange compile-time error  with Ada.Containers.Indefinite_Hashed_Maps
  2014-05-19 21:27  7%     ` J-P. Rosen
  2014-05-20  6:30  7%       ` Simon Wright
@ 2014-05-20 20:47  7%       ` björn lundin
  2014-05-21  5:04  7%         ` J-P. Rosen
  1 sibling, 1 reply; 52+ results
From: björn lundin @ 2014-05-20 20:47 UTC (permalink / raw)


Den måndagen den 19:e maj 2014 kl. 23:27:07 UTC+2 skrev J-P. Rosen:
> (of course, managing several versions of Gnat under Windows > >is a bit more challenging...)

Not really, just change the PATH
But then again I just use gnat as cli tool, so managing
PATHS are simple
--
/Björn

^ permalink raw reply	[relevance 7%]

* Re: Strange compile-time error  with Ada.Containers.Indefinite_Hashed_Maps
  2014-05-19 21:27  7%     ` J-P. Rosen
@ 2014-05-20  6:30  7%       ` Simon Wright
  2014-05-20 20:47  7%       ` björn lundin
  1 sibling, 0 replies; 52+ results
From: Simon Wright @ 2014-05-20  6:30 UTC (permalink / raw)


"J-P. Rosen" <rosen@adalog.fr> writes:

> Le 19/05/2014 18:00, mockturtle a écrit :
>> My setup is a bit peculiar: I have GNAT installed under /usr/gnat
>> which is actually a symbolic link to /usr/gnat-2014-05-15.  When I
>> install a new version of GNAT, I create a new directory under /usr
>> and move the link of /usr/gnat to the new version.  In this way, I
>> can keep the old version(s) (if something goes wrong I can go back to
>> the old setup), while avoiding (I hope) mix-up between versions.
>
> Well, I do that all the time (I have many versions of Gnat installed -
> all thosed used by my clients, + at least the current and the previous
> GPL). Never had any problem, a symbolic link is so convenient.
>
> (of course, managing several versions of Gnat under Windows is a bit
> more challenging...)

I wrote gnatef[1] many years ago when you needed to set several
environment variables to get things to work properly (PATH, of course,
C_INCLUDE_PATH, GCC_EXEC_PREFIX, possibly others). I still use it
(setting GNAT_PREFIX to the location of the version I want to use,
e.g. /opt/gcc-4.9.0) but in fact modern GNATs use the location of
gnatmake (or, I expect, gprbuild) to set things up: so you can either
set PATH or say e.g. /opt/gnat-gpl-2014/bin/gnatmake -P foo. On Unixes,
at any rate.

[1] http://gnuada.sourceforge.net/pmwiki.php/Packages/Gnatfe

^ permalink raw reply	[relevance 7%]

* Re: Strange compile-time error  with Ada.Containers.Indefinite_Hashed_Maps
  2014-05-19 16:00  6%   ` mockturtle
  2014-05-19 16:19  7%     ` G.B.
  2014-05-19 16:35  7%     ` Simon Wright
@ 2014-05-19 21:27  7%     ` J-P. Rosen
  2014-05-20  6:30  7%       ` Simon Wright
  2014-05-20 20:47  7%       ` björn lundin
  2 siblings, 2 replies; 52+ results
From: J-P. Rosen @ 2014-05-19 21:27 UTC (permalink / raw)


Le 19/05/2014 18:00, mockturtle a écrit :
> My setup is a bit peculiar: I have GNAT installed under /usr/gnat
> which is actually a symbolic link to /usr/gnat-2014-05-15.  When I
> install a new version of GNAT, I create a new directory under /usr
> and move the link of /usr/gnat to the new version.  In this way, I
> can keep the old version(s) (if something goes wrong I can go back to
> the old setup), while avoiding (I hope) mix-up between versions.

Well, I do that all the time (I have many versions of Gnat installed -
all thosed used by my clients, + at least the current and the previous
GPL). Never had any problem, a symbolic link is so convenient.

(of course, managing several versions of Gnat under Windows is a bit
more challenging...)
-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

^ permalink raw reply	[relevance 7%]

* Re: Strange compile-time error with Ada.Containers.Indefinite_Hashed_Maps
  2014-05-19 16:00  6%   ` mockturtle
  2014-05-19 16:19  7%     ` G.B.
@ 2014-05-19 16:35  7%     ` Simon Wright
  2014-05-19 21:27  7%     ` J-P. Rosen
  2 siblings, 0 replies; 52+ results
From: Simon Wright @ 2014-05-19 16:35 UTC (permalink / raw)


mockturtle <framefritti@gmail.com> writes:

> On Monday, May 19, 2014 3:49:45 PM UTC+2, Simon Wright wrote:
>> mockturtle <framefritti@gmail.com> writes:
>> 
>> 
>> 
>> > When I try to compile the body of the symbol table package I get in
>> > the .ads the error
>> 
>> >     instantiation error at a-cihama.adb:1043
>> >     invalid constraint: type has no discriminant
>> 
>> 
>> 
>> All of GNAT GPL 2013, FSF GCC 4.8.1 and FSF GCC 4.9.0 are happy with
>> your code.
>> 
>
> Strange...  
>
> I tried my code on my PC at work; I have the same version of GNAT
> installed also on my PCs at home.  I'll try there.

I should have said, I get the same error as you do with GNAT GPL 2014 on
Mac OS X.


^ permalink raw reply	[relevance 7%]

* Re: Strange compile-time error  with Ada.Containers.Indefinite_Hashed_Maps
  2014-05-19 16:00  6%   ` mockturtle
@ 2014-05-19 16:19  7%     ` G.B.
  2014-05-19 16:35  7%     ` Simon Wright
  2014-05-19 21:27  7%     ` J-P. Rosen
  2 siblings, 0 replies; 52+ results
From: G.B. @ 2014-05-19 16:19 UTC (permalink / raw)


On 19.05.14 18:00, mockturtle wrote:
> This makes me think: could it be some problem with my installation?

Same error here (GNAT GPL 2014).

^ permalink raw reply	[relevance 7%]

* Re: Strange compile-time error with Ada.Containers.Indefinite_Hashed_Maps
  2014-05-19 13:49 13% ` Simon Wright
@ 2014-05-19 16:00  6%   ` mockturtle
  2014-05-19 16:19  7%     ` G.B.
                       ` (2 more replies)
  0 siblings, 3 replies; 52+ results
From: mockturtle @ 2014-05-19 16:00 UTC (permalink / raw)


On Monday, May 19, 2014 3:49:45 PM UTC+2, Simon Wright wrote:
> mockturtle <framefritti@gmail.com> writes:
> 
> 
> 
> > When I try to compile the body of the symbol table package I get in
> > the .ads the error
> 
> >     instantiation error at a-cihama.adb:1043
> >     invalid constraint: type has no discriminant
> 
> 
> 
> All of GNAT GPL 2013, FSF GCC 4.8.1 and FSF GCC 4.9.0 are happy with
> your code.
> 

Strange...  

I tried my code on my PC at work; I have the same version of GNAT installed also on my PCs at home.  I'll try there.

> 
> 
> a-cihama.adb (Ada.Containers.Indefinite_Hashed_Maps) line 1043 is in
> Read_Node:
> 
> 
>    function Read_Node
>      (Stream : not null access Root_Stream_Type'Class) return Node_Access
>    is
>       Node : Node_Access := new Node_Type;
>    begin
>       begin
>          Node.Key := new Key_Type'(Key_Type'Input (Stream)); <<<<<<
> 
> and I don't see why GNAT thinks there (should be?) a discriminant there.
> 

I do not see it either... Nevertheless, I just c'n'p-ed the error message. 

This makes me think: could it be some problem with my installation?  Maybe some funny interaction with an older version?

[[ 

My setup is a bit peculiar: I have GNAT installed under /usr/gnat which is actually a symbolic link to /usr/gnat-2014-05-15.  When I install a new version of GNAT, I create a new directory under /usr and move the link of /usr/gnat to the new version.  In this way, I can keep the old version(s) (if something goes wrong I can go back to the old setup), while avoiding (I hope) mix-up between versions.  

]] 

> 
> 
> Is there a reason why you don't make Name_Type just String? You're
> forced to use indefinite hashed maps, so the stored Key is assumed to be
> indefinite and will be allocated. (I tried this and the compiler was
> happy).

Yes, there are few reasons for using a bounded string.  Basically, in other parts of the code it is more convenient (but not strictly necessary) to have a definite type for Type_Name.  Currently I solved the problem by making a "home-brew" version of Indefinite_Hashed_Maps by storing the access to the descriptor.   The change were just minimal.  The curiosity, however, remains.

Riccardo


^ permalink raw reply	[relevance 6%]

* Re: Strange compile-time error  with Ada.Containers.Indefinite_Hashed_Maps
  2014-05-19 10:10 12% Strange compile-time error with Ada.Containers.Indefinite_Hashed_Maps mockturtle
@ 2014-05-19 13:49 13% ` Simon Wright
  2014-05-19 16:00  6%   ` mockturtle
  0 siblings, 1 reply; 52+ results
From: Simon Wright @ 2014-05-19 13:49 UTC (permalink / raw)


mockturtle <framefritti@gmail.com> writes:

> I define the "identifier name" type in a package that is with-ed by
> the package that defines the symbol table.  The symbol table is just a
> Indefinite_Hash_Map (indefinite since the descriptor is indefinite).
> When I try to compile the body of the symbol table package I get in
> the .ads the error
>
>     instantiation error at a-cihama.adb:1043
>     invalid constraint: type has no discriminant

All of GNAT GPL 2013, FSF GCC 4.8.1 and FSF GCC 4.9.0 are happy with
your code.

a-cihama.adb (Ada.Containers.Indefinite_Hashed_Maps) line 1043 is in
Read_Node:

   function Read_Node
     (Stream : not null access Root_Stream_Type'Class) return Node_Access
   is
      Node : Node_Access := new Node_Type;

   begin
      begin
         Node.Key := new Key_Type'(Key_Type'Input (Stream)); <<<<<<

and I don't see why GNAT thinks there (should be?) a discriminant there.

Is there a reason why you don't make Name_Type just String? You're
forced to use indefinite hashed maps, so the stored Key is assumed to be
indefinite and will be allocated. (I tried this and the compiler was
happy).

^ permalink raw reply	[relevance 13%]

* Strange compile-time error  with Ada.Containers.Indefinite_Hashed_Maps
@ 2014-05-19 10:10 12% mockturtle
  2014-05-19 13:49 13% ` Simon Wright
  0 siblings, 1 reply; 52+ results
From: mockturtle @ 2014-05-19 10:10 UTC (permalink / raw)


Dear all,
I am stuck with an error that could be a compiler bug and I hope you could give me some help.  I am currently using GNAT 20140331 on 64 bit Linux.

A brief introduction about what I am trying to do: I want to implement a "symbol table" that maps identifiers (implemented as bounded strings) into "symbol descriptors" (implemented as records with a discriminant that identifies the symbol type).  

I define the "identifier name" type in a package that is with-ed by the package that defines the symbol table.  The symbol table is just a Indefinite_Hash_Map (indefinite since the descriptor is indefinite).   When I try to compile the body of the symbol table package I get in the .ads the error 

    instantiation error at a-cihama.adb:1043
    invalid constraint: type has no discriminant

I was able to replicate the error with a small set of files.  At the end of this message you will find three packages: Ginger (that defines the identifier type), Foo (that with-s Ginger) and Foo_2 (that is Foo merged together with Ginger, so that it is self-sufficient).

If I try to compile foo.adb, I get the error above; if I try to compile foo-2.adb, I get no error.  This makes me suspect that (i) I tripped over some subtlety of the language or (ii) this is a bug.

Any help?

Thank you.

Riccardo

---------

--------------------
--   GINGER.ADS   --
--------------------

with Ada.Strings.Bounded;

package ginger is
   type Name_Type is private;

   function To_String(X:Name_Type) return String;

private
   package Names is
     new Ada.Strings.Bounded.Generic_Bounded_Length (10);

   type Name_Type is new Names.Bounded_String;

   function To_String (X : Name_Type) return String
   is (Names.To_String (Names.Bounded_String (X)));
end ginger;

-----------------
--   FOO.ADS   --
-----------------


with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;
with Ginger;

package foo is
   type My_Map is tagged private;

   type Name_Class is (First, Second);

   type Descriptor (Class : Name_Class) is
      record
         case Class is
            when First =>
               null;

            when Second =>
               X : Float;
         end case;
      end record;

   procedure Zizi (X: My_Map);

private
   function Hash (Key : Ginger.Name_Type) return Ada.Containers.Hash_Type;

   function Equal (Left, Right : Ginger.Name_Type) return Boolean;

   package Maps is
     new Ada.Containers.Indefinite_Hashed_Maps
       (Key_Type        => Ginger.Name_Type,
        Element_Type    => Descriptor,
        Hash            => Hash,
        Equivalent_Keys => Equal);

   type My_Map is  new Maps.Map with null record;
end foo;

-----------------
--   FOO.ADB   --
-----------------

package body foo is

   ----------
   -- Zizi --
   ----------

   procedure Zizi (X: My_Map) is
   begin
      null;
   end Zizi;
   
   function Hash (Key : Ginger.Name_Type) return Ada.Containers.Hash_Type
   is
   begin
      return Ada.Strings.Hash (Ginger.To_String (Key));
   end Hash;

   function Equal (Left, Right : Ginger.Name_Type) return Boolean 
   is
   begin
      
      return Ginger.To_String (Left) = Ginger.To_String (Right);
   end Equal;
        


end foo;

-------------------
--   FOO_2.ADS   --
-------------------


with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;
with Ada.Strings.Bounded;


package Foo_2 is
   type My_Map is tagged private;

   type Name_Class is (First, Second);

   type Descriptor (Class : Name_Class) is
      record
         case Class is
            when First =>
               null;

            when Second =>
               X : Float;
         end case;
      end record;

   procedure Zizi (X: My_Map);

private
   package Names is
     new Ada.Strings.Bounded.Generic_Bounded_Length (10);

   type Name_Type is new Names.Bounded_String;

   function To_String (X : Name_Type) return String
   is (Names.To_String (Names.Bounded_String (X)));

   function Hash (Key : Name_Type) return Ada.Containers.Hash_Type
   is (Ada.Strings.Hash (To_String (Key)));

   function Equal (Left, Right : Name_Type) return Boolean
   is (Left = Right);

   package Maps is
     new Ada.Containers.Indefinite_Hashed_Maps
       (Key_Type        => Name_Type,
        Element_Type    => Descriptor,
        Hash            => Hash,
        Equivalent_Keys => Equal);

   type My_Map is tagged
      record
         M : Maps.Map;
      end record;
end Foo_2;


-------------------
--   FOO_2.ADB   --
-------------------

package body Foo_2 is

   ----------
   -- Zizi --
   ----------

   procedure Zizi (X: My_Map) is
   begin
      null;
   end Zizi;

end Foo_2;


^ permalink raw reply	[relevance 12%]

* Re: Little people supporting Ada, possibly through AdaCore?
  @ 2012-07-17 15:06  7%             ` Thomas Løcke
  0 siblings, 0 replies; 52+ results
From: Thomas Løcke @ 2012-07-17 15:06 UTC (permalink / raw)


On 07/17/2012 03:47 PM, Adrian Hoe wrote:
> Yeah, but looks like GNATColl.JSON has mixed up the order of objects. So, if objects are created in the order of company_name, vat_no, hours, product and web as in procedure Set_Core_Company_Data then it should be left as it is. The objects should be traversed in the same order as they were created but the output shows company_name, web, product, hours and vat_no. I don't mean it is the job of  GNATColl.JSON to sort the objects according to some orders. The question is: Why the objects cannot be traversed in the original order as they are created?


If you look at the code you'll see they are using a plain
Ada.Containers.Indefinite_Hashed_Maps for storage, and some simple
recursion in the Write function. The original order of the objects
are lost forever when they are added to a hashed map. There's no
sequence, only a collection of JSON_Value objects.

There's no way to sort the contents of an Indefinite_Hashed_Maps
container without "wasting" processing time, and since order doesn't
matter in JSON, I don't think the GNATColl devs have spent an awful lot
of time on making sure some sort of arbitrary order is maintained.

-- 
Thomas L�cke | thomas@12boo.net | http://12boo.net





^ permalink raw reply	[relevance 7%]

* Re: Little people supporting Ada, possibly through AdaCore?
  @ 2012-07-16 15:47  6%   ` Adrian Hoe
    0 siblings, 1 reply; 52+ results
From: Adrian Hoe @ 2012-07-16 15:47 UTC (permalink / raw)


On Friday, May 4, 2012 10:36:12 PM UTC+8, Marc C wrote:
> 
> - Report bugs and offer up patches. (Last week I submitted a patch to a GNATCOLL JSON package, which was accepted.)


Hi Marc,

I wonder what patch you have submitted. The AdaCore repository (http://svn.eu.adacore.com/anonsvn/Dev/trunk/gps/gnatlib/src/) does not show commits.

I followed Thomas Locke's example in his Ada-DK Wiki. As in the output example (as in Thomas Ada-DK wiki), the sequence of the objects in the output are not the same as when they are created. Let’s take the core company data as an example.

In procedure Set_Core_Company_Data, the sequence is company_name, vat_no, hours, product and web. But the output shows the order: company_name, web, [addresses], products, hours, [persons] and vat_no.

Is this a bug in GNATColl.JASON? I can’t find any bug. Perhaps it is the “Ada.Containers.Indefinite_Hashed_Maps” or I have missed something?

I have posted a comment at Thomas' blog (http://ada-dk.org/2011/11/getting-down-and-dirty-with-ada-and-json/#comment-107).

Thanks.
--
Adrian Hoe



^ permalink raw reply	[relevance 6%]

* Re: String_Holder ?
  @ 2011-12-19 11:12  6% ` Martin
  0 siblings, 0 replies; 52+ results
From: Martin @ 2011-12-19 11:12 UTC (permalink / raw)


On Dec 18, 12:34 pm, Natasha Kerensikova <lithium...@gmail.com> wrote:
> Hello,
>
> in my few Ada projects so far, I have quite often encountered the need
> of storing a string along with other information in records. So I went
> for discriminants containing the string size, and putting the string
> directly in the record.
>
> This works well when there is only one or two strings, but with several
> of them, or in variant records, I find it quite heavy. So I was thinking
> about something like that:
>
> type String_Holder is still to be defined;
>
> function Hold (S : String) return String_Holder;
>
> function To_String (Holder : String_Holder) return String;
>
> procedure Query (Holder : String_Holder;
>                  Process : not null access procedure (S : String));
>
> I'm still unsure on what kind of type String_Holder should be (private,
> tagged private or interface). It would basically be a constant-size
> reference to an immutable string that is stored "somewhere".
>
> The simplest implementation would be an Unbounded_String, though if
> needed it could be improved reference counting to make assignments
> cheaper, or with a hash table to deduplicate identical strings, etc.
>
> So my question is, does it make sense to have such objects? Or am I
> getting blinded by my C past, where strings are always manipulated
> through a char* object?
>
> Assuming it does make sense, am I right in thinking it's better to have
> such a type, even if it's a thin wrapper around Unbounded_String,
> instead of using directly Unbounded_String?
>
> Assuming it does make sense to have a String_Holder, would it be better
> to have it private, tagged private or interface?
> My guess is that tagged private has no advantage over interface,
> especially with a default implementation around Unbounded_String, which
> doesn't need to be controlled, but then controlled extension would be
> heavier. Then the choice between private and interface amounts to
> whether or not it could be useful to use simultaneously several
> implementations of String_Holder in the same project. I cannot think of
> any project where it would be the case, so I would lean towards private,
> but maybe I'm lacking imagination here.
>
> Still under the same assumption, is the above specification sane, or am
> I missing something? Query procedure is probably not absolutely
> necessary, but I guess it can be occasionally useful to save a string
> copy compared to To_String, and it seems to be a very small
> implementation burden anyway.
>
> Still under the same assumption, can it be useful to provide unary "+"
> functions to tersely convert String_Holder to String, and maybe
> vice-versa, or would it do more harm (obfuscation) than good?
>
> And lastly, is there any trick to allow a String_Holder object or
> similar to be pre-elaborable?
>
> Thanks in advance for your insights,
> Natasha

Have you considered a "Flyweight"?

Here's an example in Ada2012 (which is soooo much easier to acheive
than in previous Ada versions).

The coffee flavour string is repeated in each order but only unique
strings are stored and each order context contains a reference to the
string.

In a real application, you'd want probably want to add finalization.

-- Martin



-- main.adb
with Applications; use Applications;
procedure Main is
   App : Application := Create;
begin
   App.Execute;
end Main;

-- applications.ads
        private with Ada.Containers.Vectors;
        private with Coffee_Orders.Flavours;
        private with Coffee_Orders.Flavours.Factories;
limited private with Coffee_Order_Contexts;
package Applications is
   type Application (<>) is tagged limited private;
   function Create return Application;
   procedure Execute (A : in out Application);
private
   use Coffee_Orders.Flavours.Factories;
   type Order is record
      Context : access Coffee_Order_Contexts.Coffee_Order_Context;
      Flavour : access Coffee_Orders.Flavours.Flavour;
   end record;
   package Order_Vectors is
      new Ada.Containers.Vectors (Natural, Order);
   type Application is tagged limited record
      Orders          : Order_Vectors.Vector;
      Flavour_Factory : Coffee_Orders.Flavours.Factories.Factory;
   end record;
   procedure Take_Orders (A       : in out Application;
                          Flavour :        String;
                          Table   :        Integer);
end Applications;

-- applications.adb
with Ada.Text_IO;            use Ada.Text_IO;
with Coffee_Order_Contexts;  use Coffee_Order_Contexts;
with Coffee_Orders.Flavours; use Coffee_Orders.Flavours;
package body Applications is
   function Create return Application is
   begin
      return Result : Application do
         null;
      end return;
   end Create;
   procedure Take_Orders (A       : in out Application;
                          Flavour :        String;
                          Table   :        Integer) is
   begin
      A.Orders.Append ((Context => new Coffee_Order_Context'(Create
(Table)),
                        Flavour =>
Flavour_Ref'(A.Flavour_Factory.Get_Flavour (Flavour))));
   end Take_Orders;
   procedure Execute (A : in out Application) is
   begin
      A.Take_Orders ("Cappuccino", 2);
      A.Take_Orders ("Cappuccino", 2);
      A.Take_Orders ("Frappe", 1);
      A.Take_Orders ("Frappe", 1);
      A.Take_Orders ("Xpresso", 1);
      A.Take_Orders ("Frappe", 897);
      A.Take_Orders ("Cappuccino", 97);
      A.Take_Orders ("Cappuccino", 97);
      A.Take_Orders ("Frappe", 3);
      A.Take_Orders ("Xpresso", 3);
      A.Take_Orders ("Cappuccino", 3);
      A.Take_Orders ("Xpresso", 96);
      A.Take_Orders ("Frappe", 552);
      A.Take_Orders ("Cappuccino", 121);
      A.Take_Orders ("Xpresso", 121);
      for Order of A.Orders loop
         Order.Flavour.Serve_Coffee (Order.Context.all);
      end loop;
      Put_Line ("Total Coffee_Flavor objects made:" & Integer'Image
(A.Flavour_Factory.Total_Flavours_Made));
   end Execute;
end Applications;

-- coffee_order_contexts.ads
package Coffee_Order_Contexts is
   type Coffee_Order_Context (<>) is tagged private;
   function Create (Table : Integer) return Coffee_Order_Context;
   function Table_No (COC : Coffee_Order_Context) return Integer;
private
   type Coffee_Order_Context is tagged record
      Table : Integer := 0;
   end record;
end Coffee_Order_Contexts;

-- coffee_order_contexts.adb
package body Coffee_Order_Contexts is
   function Create (Table : Integer) return Coffee_Order_Context is
   begin
      return Result : Coffee_Order_Context do
         Result.Table := Table;
      end return;
   end Create;
   function Table_No (COC : Coffee_Order_Context) return Integer is
   begin
      return COC.Table;
   end Table_No;
end Coffee_Order_Contexts;

-- coffee_order_contexts-vectors.ads
with Ada.Containers.Indefinite_Vectors;
package Coffee_Order_Contexts.Vectors is
   new Ada.Containers.Indefinite_Vectors (Natural,
Coffee_Order_Context);

-- coffee_orders.ads
with Coffee_Order_Contexts; use Coffee_Order_Contexts;
package Coffee_Orders is
   type Coffee_Order is interface;
   procedure Serve_Coffee (CO  : Coffee_Order;
                           COC : Coffee_Order_Context) is abstract;
end Coffee_Orders;

-- coffee_orders-flavours.ads
private with Ada.Strings.Unbounded;
        with Coffee_Order_Contexts; use Coffee_Order_Contexts;
package Coffee_Orders.Flavours is
   type Flavour (<>) is new Coffee_Order with private;
   type Flavour_Ref is access all Flavour'Class;
   function Create (Name : String) return Flavour;
   function "=" (L, R : Flavour) return Boolean;
   overriding
   procedure Serve_Coffee (F   : Flavour;
                           COC : Coffee_Order_Context);
private
   use Ada.Strings.Unbounded;
   type Flavour is new Coffee_Order with record
      Name : Unbounded_String;
   end record;
end Coffee_Orders.Flavours;

-- coffee_orders-flavours.adb
with Ada.Strings.Equal_Case_Insensitive;
with Ada.Text_IO; use Ada.Text_IO;
package body Coffee_Orders.Flavours is
   function Create (Name : String) return Flavour is
   begin
      return Result : Flavour do
         Result.Name := To_Unbounded_String (Name);
      end return;
   end Create;
   function "=" (L, R : Flavour) return Boolean is
   begin
      return Ada.Strings.Equal_Case_Insensitive (To_String (L.Name),
To_String (R.Name));
   end "=";
   procedure Serve_Coffee (F   : Flavour;
                           COC : Coffee_Order_Context) is
   begin
      Put_Line ("Serving Coffee flavor " & To_String (F.Name)
                & " to table number " & Integer'Image (COC.Table_No));
   end Serve_Coffee;
end Coffee_Orders.Flavours;

-- coffee_orders-flavours-vectors.ads
with Ada.Containers.Vectors;
package Coffee_Orders.Flavours.Vectors is
   new Ada.Containers.Vectors (Natural, Flavour_Ref);

-- coffee_orders-flavours-factories.ads
private with Ada.Containers.Indefinite_Hashed_Maps;
private with Ada.Strings.Equal_Case_Insensitive;
private with Ada.Strings.Hash_Case_Insensitive;
private with Ada.Strings.Unbounded;
package Coffee_Orders.Flavours.Factories is
   type Factory is tagged private;
   function Get_Flavour (F    : in out Factory;
                         Name :        String)
                         return not null access Flavour;
   function Total_Flavours_Made (F : Factory) return Natural;
private
   use Ada.Strings.Unbounded;
   package Maps is
     new Ada.Containers.Indefinite_Hashed_Maps (Key_Type        =>
String,
                                                Element_Type    =>
Flavour,
                                                Hash            =>
Ada.Strings.Hash_Case_Insensitive,
                                                Equivalent_Keys =>
Ada.Strings.Equal_Case_Insensitive);
   type Factory is tagged record
      Flavours : Maps.Map;
   end record;
end Coffee_Orders.Flavours.Factories;

-- coffee_orders-flavours-factories.adb
package body Coffee_Orders.Flavours.Factories is
   function Get_Flavour (F    : in out Factory;
                         Name :        String) return not null access
Flavour is
      use type Maps.Cursor;
      C : constant Maps.Cursor := F.Flavours.Find (Name);
   begin
      if C /= Maps.No_Element then
         return F.Flavours.Constant_Reference (Name).Element;
      end if;
      F.Flavours.Insert (Name, Create (Name));
      return F.Flavours.Constant_Reference (Name).Element;
   end Get_Flavour;
   function Total_Flavours_Made (F : Factory) return Natural is
   begin
      return Natural (F.Flavours.Length);
   end Total_Flavours_Made;
end Coffee_Orders.Flavours.Factories;



^ permalink raw reply	[relevance 6%]

* Re: Bug in GCC ?
  @ 2008-05-19 15:57  9% ` Matthew Heaney
  0 siblings, 0 replies; 52+ results
From: Matthew Heaney @ 2008-05-19 15:57 UTC (permalink / raw)


On May 19, 11:50 am, Sébastien <seb.mor...@gmail.com> wrote:
>
> with Ada.Containers.Hashed_Maps;

Why didn't you use the indefinite form?  That would allow you to ditch
the Unbounded_String.

with Ada.Containers.Indefinite_Hashed_Maps;
pragma Elaborate_All (Ada.Containers.Indefinite_Hashed_Maps);

package SCMAL.Tools.HashedMaps is

     package HashedStrStr is
         new Ada.Containers.Indefinite_Hashed_Maps(
         Key_Type => String,
         Element_Type => String,
         Hash => Ada.Strings.Hash,
         Equivalent_Keys => "=");

end SCMAL.Tools.HashedMaps;





^ permalink raw reply	[relevance 9%]

* Re: OO Style with Ada Containers
  @ 2007-11-19  2:24  5%       ` Matthew Heaney
  0 siblings, 0 replies; 52+ results
From: Matthew Heaney @ 2007-11-19  2:24 UTC (permalink / raw)


braver <deliverable@gmail.com> writes:

> As you can see, I've managed to do prefix notation everywhere except
> cursors.  How do they coexist with prefix notation -- or are they
> replaced by something cooler already, too?  :)

No, cursors aren't tagged because an operation can only be primitive for a
single tagged type, and the container type is already tagged.


> I'd appreciate any improvements to the above, which I deduced from ARM
> and Rosetta Stone examples in an hour and then prefix'ised thanks to
> Adam's hint!  (Well I've followed Ada since 1987 so the spirit is easy
> to follow...)

The problem with your code is here:

   Ngram_Cursor := Ngram_Counts.Find(s);

   if not Has_Element(Ngram_Cursor) then
       Ngram_Counts.Insert(s, 1);
       New_Word_Count := New_Word_Count + 1;
   else -- a valid position in Ngram_Pos
       Count := Element(Ngram_Cursor);
       Ngram_Counts.Replace_Element(Ngram_Cursor, Count+1);
  end if;


The issue is that Find duplicates the search that must already be performed by
Insert. You don't want to be doing this if the map has many elements.

The solution is to use the conditional form of Insert, which does an atomic
search-and-insert and reports back the result of the search.  If the key is
already in the map, the cursor returned designates the existing key/element
pair (which is not modified); if the key is not in the map, the key/element
pair is inserted and the cursor passed back designates the newly-inserted pair.

What you do here is insert a count of 0 for the word, and then increment the
count. If the word is already in the map, the existing count is increment.  If
the word is not already in the map, the count is 0, so it gets incremented to
the value 1 (which is the desired value).

I have included an example program below.  Also included is a simple scanner
that returns a lexeme for each whitespace-delimited word on a line of text.

Feel free to write if you have any comments or questions.

Regards,
Matt


--STX
with Ada.Command_Line;  use Ada.Command_Line;
with Ada.Text_IO;  use Ada.Text_IO;
with Ada.Integer_Text_IO;  use Ada.Integer_Text_IO;
with Scanners;     use Scanners;
with Ada.Containers.Indefinite_Hashed_Maps;  use Ada.Containers;
with Ada.Strings.Hash_Case_Insensitive;
with Ada.Strings.Equal_Case_Insensitive;  use Ada.Strings;

procedure Count_Words is
   Line      : String (1 .. 256);
   Line_Last : Natural;

   package Map_Types is new Indefinite_Hashed_Maps
     (String,
      Natural,
      Hash_Case_Insensitive,
      Equal_Case_Insensitive);
   
   M : Map_Types.Map;
   use Map_Types;

   F : File_Type;

begin
   Open (F, In_File, Argument (1));

   while not End_Of_File (F) loop
      Get_Line(F, Line, Line_Last);

      declare
         procedure Increment_Count 
           (Word  : String; 
            Count : in out Natural)
         is
         begin
            Count := Count + 1;
         end;

         S : Scanner := Scan (Line (Line'First .. Line_Last));
         
         C : Map_Types.Cursor;
         B : Boolean;

      begin
         while S.Has_Word loop
            M.Insert (S.Word, 0, C, B);
            M.Update_Element (C, Increment_Count'Access);
         end loop;
      end;
   end loop;

   declare
      procedure Process (C : Map_Types.Cursor) is
         Word  : constant String := Key (C);
         Count : constant Natural := Element (C);

      begin
         Put (Word);
         Put (':');
         Put (Count, Width => 0);
         New_Line;
      end Process;

   begin
      M.Iterate (Process'Access);
   end;

end Count_Words;

package Scanners is
   pragma Pure;

   type Scanner (<>) is tagged limited private;

   function Scan (Line : String) return Scanner;

   function Has_Word (S : Scanner) return Boolean;
   function Word (S : Scanner) return String;

private

   type Handle (S : not null access Scanner) is limited null record;

   type Scanner (Last : Natural) is tagged limited record
      H          : Handle (Scanner'Access);
      Line       : String (1 .. Last);
      Word_First : Positive;
      Word_Last  : Natural;
   end record;

end Scanners;

with Ada.Characters.Latin_1;  use Ada.Characters;

package body Scanners is

   function Is_Whitespace (C : Character) return Boolean is
   begin
      case C is
         when ' ' | Latin_1.HT => 
            return True;
         when others =>
            return False;
      end case;
   end Is_Whitespace;
      

   procedure Next (S : in out Scanner) is
      I : Integer renames S.Word_First;
      J : Integer renames S.Word_Last;
      
   begin
      I := J + 1;
      while I <= S.Last 
        and then Is_Whitespace (S.Line (I))
      loop
         I := I + 1;
      end loop;
      
      if I > S.Last then
         return;  -- no more words on this line
      end if;
      
      J := I;
      while J < S.Last 
        and then not Is_Whitespace (S.Line (J + 1))
      loop
         J := J + 1;
      end loop;
   end Next;
      

   function Scan (Line : String) return Scanner is
   begin
      return S : Scanner (Line'Length) do
        S.Line := Line;
        -- S.Word_First := 1;
        S.Word_Last := 0;
        Next (S);
      end return;
   end Scan;


   function Has_Word (S : Scanner) return Boolean is
   begin
      return S.Word_First <= S.Word_Last;
   end Has_Word;


   function Word (S : Scanner) return String is
      L : constant Positive := S.Word_Last - S.Word_First + 1;
      
   begin
      return Result : String (1 .. L) do
        Result := S.Line (S.Word_First .. S.Word_Last);
        Next (S.H.S.all);
      end return;
   end Word;

end Scanners;



^ permalink raw reply	[relevance 5%]

* Re: Ada.Containers.Indefinite_Hashed_Maps
  2007-04-26 12:12  7%   ` Ada.Containers.Indefinite_Hashed_Maps Maciej Sobczak
  2007-04-26 12:55  7%     ` Ada.Containers.Indefinite_Hashed_Maps Stefan Bellon
@ 2007-04-27  4:39  7%     ` Jeffrey R. Carter
  1 sibling, 0 replies; 52+ results
From: Jeffrey R. Carter @ 2007-04-27  4:39 UTC (permalink / raw)


Maciej Sobczak wrote:
> 
> You do the same key search once for Contains and once for Find. That 
> gives twice the same work. Is there a way to make the search once?

As it was a quick example about using Update_Element, I didn't really 
care. In real code I might pay that kind of thing more attention.

-- 
Jeff Carter
"I fart in your general direction."
Monty Python & the Holy Grail
05



^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Hashed_Maps
  2007-04-26 15:52  5% ` Ada.Containers.Indefinite_Hashed_Maps Matthew Heaney
@ 2007-04-26 19:56  7%   ` Matthew Heaney
  0 siblings, 0 replies; 52+ results
From: Matthew Heaney @ 2007-04-26 19:56 UTC (permalink / raw)


On Apr 26, 11:52 am, Matthew Heaney <mhea...@on2.com> wrote:
>
> Update_Element works fine if you already have a cursor, and you want
> to modify an element in-place.  Something like:
>
> procedure My_Update (M : in out Map; C : Cursor) is
>    procedure Process (K : KT; E : in out ET) is
>    begin
>       ... -- modify E as necessary
>    end;
> begin
>    M.Update_Element (C);
> end;

Oops!  Of course I meant:

M.Update_Element (C, Process'Access);




^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Hashed_Maps
  2007-04-26 12:55  7%     ` Ada.Containers.Indefinite_Hashed_Maps Stefan Bellon
@ 2007-04-26 16:13  7%       ` Matthew Heaney
  0 siblings, 0 replies; 52+ results
From: Matthew Heaney @ 2007-04-26 16:13 UTC (permalink / raw)


On Apr 26, 8:55 am, Stefan Bellon <sbel...@sbellon.de> wrote:
>
>    Position := Maps.Find (Map, Key => Some_Key);
>    if Position /= Maps.No_Element then

Or:

   C := M.Find (K);
   if Has_Element (C) then ... ;





^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Hashed_Maps
  2007-04-25 14:13 14% Ada.Containers.Indefinite_Hashed_Maps markp
  2007-04-25 17:43 12% ` Ada.Containers.Indefinite_Hashed_Maps Jeffrey R. Carter
  2007-04-26 15:52  5% ` Ada.Containers.Indefinite_Hashed_Maps Matthew Heaney
@ 2007-04-26 16:12  7% ` Matthew Heaney
  2 siblings, 0 replies; 52+ results
From: Matthew Heaney @ 2007-04-26 16:12 UTC (permalink / raw)


On Apr 25, 10:13 am, markp <markwor...@yahoo.com> wrote:
> I am using a hash table via Ada.Containers.Indefinite_Hashed_Maps to
> hash an array of records. We have a predfined array of records called
> X. The insert function works fine by passing in X(1), X(2), etc. I am
> having trouble with the syntax of the Update call, specifically the
> Process parameter. Could somebody provide a quick snippet of code that
> show how to setup this code and how the procedure actually looks to
> update the data?

Given map M and cursor C you would say:

declare
   procedure Process (K : KT; E : in out ET) is
   begin
      ... -- modify E as necessary
   end;
begin
   M.Update_Element (C, Process'Access);
end;





^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Hashed_Maps
  2007-04-25 14:13 14% Ada.Containers.Indefinite_Hashed_Maps markp
  2007-04-25 17:43 12% ` Ada.Containers.Indefinite_Hashed_Maps Jeffrey R. Carter
@ 2007-04-26 15:52  5% ` Matthew Heaney
  2007-04-26 19:56  7%   ` Ada.Containers.Indefinite_Hashed_Maps Matthew Heaney
  2007-04-26 16:12  7% ` Ada.Containers.Indefinite_Hashed_Maps Matthew Heaney
  2 siblings, 1 reply; 52+ results
From: Matthew Heaney @ 2007-04-26 15:52 UTC (permalink / raw)


On Apr 25, 10:13 am, markp <markwor...@yahoo.com> wrote:
> I am using a hash table via Ada.Containers.Indefinite_Hashed_Maps to
> hash an array of records.

What do you mean by "hash an array of records"?  Does the data live
inside an array, or inside a map?  What is the key type?  What is the
element type?


> We have a predfined array of records called
> X. The insert function works fine by passing in X(1), X(2), etc.

What is the map key type?

Are you inserting an array component value into the map?  Does this
mean the data is getting stored twice (first as an array element, and
again as a map element)?


> I am
> having trouble with the syntax of the Update call, specifically the
> Process parameter.

Update_Element works fine if you already have a cursor, and you want
to modify an element in-place.  Something like:

procedure My_Update (M : in out Map; C : Cursor) is
   procedure Process (K : KT; E : in out ET) is
   begin
      ... -- modify E as necessary
   end;
begin
   M.Update_Element (C);
end;

If you want to simply replace what's there (instead of modifying the
element in-place), then you can use Replace_Element:

M.Replace_Element (C, E);

If you don't have a cursor, then you can use Insert:

M.Insert (K, E);

Note that Insert will raise an exception if K is already in the map.

You could also use Replace:

M.Replace (K, E);

Note that Replace will raise an exception if K is not in the map.

You could also use Include:

M.Include (K. E);

Note that Include does not raise an exception.  If K is in the map,
then E will replace what's already there, and if K is not in the map,
then E will be inserted.

There is also a conditional form of Insert, that does not raise an
exception.  It reports back (with a status value) whether the key/
element pair was actually inserted ("successful" insertion depends on
whether the key was already in the map).




^ permalink raw reply	[relevance 5%]

* Re: Ada.Containers.Indefinite_Hashed_Maps
  2007-04-26 12:12  7%   ` Ada.Containers.Indefinite_Hashed_Maps Maciej Sobczak
@ 2007-04-26 12:55  7%     ` Stefan Bellon
  2007-04-26 16:13  7%       ` Ada.Containers.Indefinite_Hashed_Maps Matthew Heaney
  2007-04-27  4:39  7%     ` Ada.Containers.Indefinite_Hashed_Maps Jeffrey R. Carter
  1 sibling, 1 reply; 52+ results
From: Stefan Bellon @ 2007-04-26 12:55 UTC (permalink / raw)


Maciej Sobczak wrote:

> Jeffrey R. Carter wrote:
> 
> > if Maps.Contains (Map, Some_Key) then
> >    Position := Maps.Find (Map, Key => Some_Key);
> 
> You do the same key search once for Contains and once for Find. That 
> gives twice the same work. Is there a way to make the search once?

   Position := Maps.Find (Map, Key => Some_Key);
   if Position /= Maps.No_Element then
      ...

Untested, but this is how I understand it.

-- 
Stefan Bellon



^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Hashed_Maps
  2007-04-25 17:43 12% ` Ada.Containers.Indefinite_Hashed_Maps Jeffrey R. Carter
@ 2007-04-26 12:12  7%   ` Maciej Sobczak
  2007-04-26 12:55  7%     ` Ada.Containers.Indefinite_Hashed_Maps Stefan Bellon
  2007-04-27  4:39  7%     ` Ada.Containers.Indefinite_Hashed_Maps Jeffrey R. Carter
  0 siblings, 2 replies; 52+ results
From: Maciej Sobczak @ 2007-04-26 12:12 UTC (permalink / raw)


Jeffrey R. Carter wrote:

> if Maps.Contains (Map, Some_Key) then
>    Position := Maps.Find (Map, Key => Some_Key);

You do the same key search once for Contains and once for Find. That 
gives twice the same work. Is there a way to make the search once?

-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



^ permalink raw reply	[relevance 7%]

* Re: Ada.Containers.Indefinite_Hashed_Maps
  2007-04-25 14:13 14% Ada.Containers.Indefinite_Hashed_Maps markp
@ 2007-04-25 17:43 12% ` Jeffrey R. Carter
  2007-04-26 12:12  7%   ` Ada.Containers.Indefinite_Hashed_Maps Maciej Sobczak
  2007-04-26 15:52  5% ` Ada.Containers.Indefinite_Hashed_Maps Matthew Heaney
  2007-04-26 16:12  7% ` Ada.Containers.Indefinite_Hashed_Maps Matthew Heaney
  2 siblings, 1 reply; 52+ results
From: Jeffrey R. Carter @ 2007-04-25 17:43 UTC (permalink / raw)


markp wrote:
> I am using a hash table via Ada.Containers.Indefinite_Hashed_Maps to
> hash an array of records. We have a predfined array of records called
> X. The insert function works fine by passing in X(1), X(2), etc. I am
> having trouble with the syntax of the Update call, specifically the
> Process parameter. Could somebody provide a quick snippet of code that
> show how to setup this code and how the procedure actually looks to
> update the data?

There is no update; I presume you mean Update_Element.

Given a map:

package Maps is new Ada.Containers.Indefinite_Hashed_Maps
    (Key_Type => Key_Value, Element_Type => Integer, ...);

procedure Process (Key : in Key_Value; Item : in out Integer) is
    -- null;
begin -- Process
    if Some_Quality (Key) then
       Item := Item + 1;
    end if;
end Process;

Map      : Maps.Map;
Some_Key : Key_Value;
Position : Maps.Cursor;

-- Put some values in Map.

Some_Key := Get;

if Maps.Contains (Map, Some_Key) then
    Position := Maps.Find (Map, Key => Some_Key);
    Maps.Update_Element (Container => Map,
                         Position  => Position,
                         Process   => Process'access);
end if;

If you've put a value in Map for the key with the value in Some_Key, and 
Some_Quality (Some_Key) returns True, then this will increment the value 
associated with that key value.

For this kind of situation, you'd probably use Element and Replace 
rather than Find and Update_Element. Update_Element is more useful when 
you've got a cursor without knowing the key value, and want to modify 
the corresponding element.

-- 
Jeff Carter
"Apart from the sanitation, the medicine, education, wine,
public order, irrigation, roads, the fresh water system,
and public health, what have the Romans ever done for us?"
Monty Python's Life of Brian
80



^ permalink raw reply	[relevance 12%]

* Ada.Containers.Indefinite_Hashed_Maps
@ 2007-04-25 14:13 14% markp
  2007-04-25 17:43 12% ` Ada.Containers.Indefinite_Hashed_Maps Jeffrey R. Carter
                   ` (2 more replies)
  0 siblings, 3 replies; 52+ results
From: markp @ 2007-04-25 14:13 UTC (permalink / raw)


I am using a hash table via Ada.Containers.Indefinite_Hashed_Maps to
hash an array of records. We have a predfined array of records called
X. The insert function works fine by passing in X(1), X(2), etc. I am
having trouble with the syntax of the Update call, specifically the
Process parameter. Could somebody provide a quick snippet of code that
show how to setup this code and how the procedure actually looks to
update the data?

Thanks a lot!




^ permalink raw reply	[relevance 14%]

* Re: How to use associative arrays in Ada 2005?
  2006-11-26 19:05  5%           ` snoopysalive
@ 2006-11-26 20:30  0%             ` Matthew Heaney
  0 siblings, 0 replies; 52+ results
From: Matthew Heaney @ 2006-11-26 20:30 UTC (permalink / raw)


"snoopysalive" <matthias.kistler@gmx.de> writes:

> Sadly, Matt's solution didn't work. The statement "Ages.Insert ("family
> name", C, B);" brought a compilation error: "no selector 'Insert' for
> private type "Ada.Containers.Indefinite_Hashed_Maps.Map" from instance
> at line 16". I found out that no procedure "Insert(String, Cursor,
> Boolean)" exists. But it exists a procedure "Insert(String,
> Element_Type, Cursor, Boolean)".

Yes, you're right.  I was thinking of the definite form of the hashed map.  The
indefinite form doesn't include the operation I used in my example.  Sorry for
the confusion.


>   So, I'm trying to combine Matt's and Georg's ideas now. I'll write a
> line, if I'd be successfull. Otherwise, I'll also write a line. ;-)

Right, all you need to do is change my example to say:

   Ages.Insert
     (Key => "family name",
      New_Item => Str_Int_Maps.Empty_Map,
      Position => C,
      Inserted => B);




^ permalink raw reply	[relevance 0%]

* Re: How to use associative arrays in Ada 2005?
  @ 2006-11-26 19:05  5%           ` snoopysalive
  2006-11-26 20:30  0%             ` Matthew Heaney
  0 siblings, 1 reply; 52+ results
From: snoopysalive @ 2006-11-26 19:05 UTC (permalink / raw)


Hi!

First, I want to thank all of you for your examples and ideas. But they
don't work, sorry! So, I took your ideas and am trying to implement an
own procedure creating "hashes" like I need them.

The problem is that I need maps of maps of maps ... It's logical that a
container is able to get another container as element and it's no
problem to instanciate these containers and then put them one into the
other.
  In my example code I tried to create a table of family names, names
and their ages. Let's make it a little more complex and create another
first key called "nation":

Nation    | Family Name   |  Name               | Age*
----------|---------------|---------------------|------
German    | Goethe        | Johann Wolfgang     | 60
          |               | Catharina Elisabeth | 80
          |               | Johann Caspar       | 90
          | Hesse         | Hermann             | 51
Japanese  | Kusanagi      | Motoko              | 29
American  | Ford          | Henry               | 45
          |               | Harrison            | 41
Finnish   | Torvalds      | Linus               | 35
----------|---------------|----------------------------
* All ages are fictional because I don't know the real
  ages of these persons or they are dead or fictional

The problem: Every single key needs a separate container map. We need 1
first-level, 4 second-level and 5 third-level key maps.

First-level  = 1x map of string-map
Second-level = 4x map of string-map
Third-level  = 5x map of string-integer

It would be necessary to create every single map and to put them one
into the other all manually for transforming the given table into a
"hash". That's easy and possible but not flexible. When posting the
code of my impossible programme, I had the idea of "anonymous"
container maps contained in maps. Because of this I wrote
"Ages.Insert("family name", Insert("name", 23));".

Sadly, Matt's solution didn't work. The statement "Ages.Insert ("family
name", C, B);" brought a compilation error: "no selector 'Insert' for
private type "Ada.Containers.Indefinite_Hashed_Maps.Map" from instance
at line 16". I found out that no procedure "Insert(String, Cursor,
Boolean)" exists. But it exists a procedure "Insert(String,
Element_Type, Cursor, Boolean)".
  So, I'm trying to combine Matt's and Georg's ideas now. I'll write a
line, if I'd be successfull. Otherwise, I'll also write a line. ;-)

Once more: Thank you all. I'm commencing to have an idea of Ada-syntax
and philosphy and that's more than my professors at universitiy could
give me.

Greetings,
Matthias




^ permalink raw reply	[relevance 5%]

* Re: How to use associative arrays in Ada 2005?
  2006-11-23 19:27  9%     ` snoopysalive
  2006-11-24  0:33  8%       ` Georg Bauhaus
  @ 2006-11-24 11:35  0%       ` Matthew Heaney
  2 siblings, 0 replies; 52+ results
From: Matthew Heaney @ 2006-11-24 11:35 UTC (permalink / raw)


"snoopysalive" <matthias.kistler@gmx.de> writes:

> And now, my next question: How to handle "hashes of hashes" in Ada?

You have to make two distinct instantiations.


> procedure book is
>     package Str_Int_Maps is
>         new Ada.Containers.Indefinite_Hashed_Maps
>             (String,
>              Integer,
>              Ada.Strings.Hash,
>              "=");
>     use Str_Int_Maps;
>     package Str_Map_Maps is
>         new Ada.Containers.Indefinite_Hashed_Maps
>             (String,
>              Str_Int_Maps.Map,
>              Ada.Strings.Hash,
>              "=");
> 
>     Ages : Str_Map_Maps.Map; -- That's the "hash of a hash"
> 
> begin
>     Ages.Insert("family name",Insert("name",23));
> end book;
> -- Here, the code ends

You have to make two distinct insertions.  The first uses the form of Insert
that inserts a key and a default element value (the element here is itself
another map), and the second uses an in-place update to insert a key/elem pair
into the secondary map.  Something like:

declare
   C : Str_Map_Maps.Cursor;
   B : Boolean;
begin
   -- this is the insert that inserts an element with its
   -- "default value" into the map:
   Ages.Insert ("family name", C, B);  -- first insert

   -- C now designates the map we care about (note that
   -- it doesn't matter what value B has)

   declare
     procedure Update 
      (S : String;  -- the family name
       M : in out Str_Int_Maps.Map) is
     begin
       M.Insert ("name", 23);  -- second insert
     end;
   begin
     Ages.Update_Element (C, Update'Access);
   end;
end;
   

> The statement "Ages.Insert("family name",Insert("name",23));" doesn't
> work. So, how is it possible to do something like this in C++:
> "...
> map<string, map<string,int>> ages;
> ages["family name"]["name"] = 23;
> ..."

Ada doesn't have an index operator, so it's not going to be as concise as the
C++.  If you're doing this a lot then you can always refactor the code above
into its own stand-alone operation.  Something like:

procedure Insert
  (M : in out Str_Map_Maps.Map;
   Family_Name : String;
   Name : String;
   Age  : Integer) is ... -- as above



^ permalink raw reply	[relevance 0%]

* Re: How to use associative arrays in Ada 2005?
  2006-11-23 19:27  9%     ` snoopysalive
@ 2006-11-24  0:33  8%       ` Georg Bauhaus
    2006-11-24 11:35  0%       ` Matthew Heaney
  2 siblings, 0 replies; 52+ results
From: Georg Bauhaus @ 2006-11-24  0:33 UTC (permalink / raw)


On Thu, 2006-11-23 at 11:27 -0800, snoopysalive wrote:

> 
> The statement "Ages.Insert("family name",Insert("name",23));" doesn't
> work. So, how is it possible to do something like this in C++:
> "...
> map<string, map<string,int>> ages;
> ages["family name"]["name"] = 23;
> ..."

I think that in this case the Ada.Containers requirement
of being minimal building blocks applies. And probably also
the principle of query/command separation, which is not followed
by std::map::operator[].  [] does many things at the same time,
hence it is not minimal.

If I remember Matt's tutorial correctly, there is an example showing how
to manipulate items in containers in situ. Barnes' book has this, too.

If the elements in a map are containers themselves (or are
otherwise big), you may want to use Update_Element.

If you have                +-----------+
                      +--> |   ...     |
   +-------------+    |    +-----------+
   |    ...      |  --+    |   ...     |  +-->  ...
   +-------------+       +----------+     |
   | family name |  -->  |   ...    |  ---+
   +-------------+       +----------+
   |    ...      |       |   name   |  ------>  23
                         +----------+
                         |   ...    |

That is in order to manipulate one of the 2nd level maps,
you could either:

- Get the element at key "family name", which is a map.
  This creates a copy of the map.
- Manipulate the copied map.
- Put the map back to where it had been (at key "family name"),
  again copying.

Or,

- Get a cursor for the element at key "family name".
- Define a subprogram that manipulates the 2nd level map
  (the one containing "name" as key).
- Call Update_Element with the cursor and the subprogram.

with Ada.Text_IO,
     Ada.Strings.Hash,
     Ada.Containers.Indefinite_Hashed_Maps;
use  Ada.Text_IO,
     Ada.Strings,
     Ada.Containers;

procedure book2 is
    package Str_Int_Maps is
        new Ada.Containers.Indefinite_Hashed_Maps
            (String,
             Integer,
             Ada.Strings.Hash,
             "=");
    use Str_Int_Maps;
    package Str_Map_Maps is
        new Ada.Containers.Indefinite_Hashed_Maps
            (String,
             Str_Int_Maps.Map,
             Ada.Strings.Hash,
             "=");

    Ages : Str_Map_Maps.Map; -- That's the "hash of a hash"
    Named_Age: Str_Int_Maps.Map;


    -- life by population statistics:

    Average: constant Natural := 80;
    function Grow_Older(Now: Integer) return Integer is separate;
        -- used to compute a new `Age` from `Now`

    Age: Integer := 0;

    procedure Set_Age(name: String; value: in out Str_Int_Maps.Map) is
    begin
        Named_Age.Include("name", Age);  -- Note how `Age` is used here
    end Set_Age;

begin
    Ages.Insert("family name", Named_Age);

    while Age < Average loop
        Age := Grow_Older(Age);

        -- 
        Ages.Update_Element(position => Ages.Find("family name"),
                            process => Set_Age'access); -- in situ
    end loop;
end book2;

This might seem like a lot, but once you have your setup, you
can reuse it, or write []-style wrappers, if you need them
etc..  Scope is important in this example, because the `Age`
variable is visible to Set_Age, and need not be passed around.





^ permalink raw reply	[relevance 8%]

* Re: How to use associative arrays in Ada 2005?
  @ 2006-11-23 19:27  9%     ` snoopysalive
  2006-11-24  0:33  8%       ` Georg Bauhaus
                         ` (2 more replies)
  0 siblings, 3 replies; 52+ results
From: snoopysalive @ 2006-11-23 19:27 UTC (permalink / raw)


Hi!

First: @Matt: Thank you for the pdf. It's really useful, but I couldn't
write you back because of the email filter.

And now, my next question: How to handle "hashes of hashes" in Ada?
Here's the code which should contain a package representing a hash of a
hash:

-- Here, the code begins
with Ada.Text_IO,
     Ada.Strings.Hash,
     Ada.Containers.Indefinite_Hashed_Maps;
use  Ada.Text_IO,
     Ada.Strings,
     Ada.Containers;

procedure book is
    package Str_Int_Maps is
        new Ada.Containers.Indefinite_Hashed_Maps
            (String,
             Integer,
             Ada.Strings.Hash,
             "=");
    use Str_Int_Maps;
    package Str_Map_Maps is
        new Ada.Containers.Indefinite_Hashed_Maps
            (String,
             Str_Int_Maps.Map,
             Ada.Strings.Hash,
             "=");

    Ages : Str_Map_Maps.Map; -- That's the "hash of a hash"

begin
    Ages.Insert("family name",Insert("name",23));
end book;
-- Here, the code ends


The statement "Ages.Insert("family name",Insert("name",23));" doesn't
work. So, how is it possible to do something like this in C++:
"...
map<string, map<string,int>> ages;
ages["family name"]["name"] = 23;
..."

Thank you and greetings,
Matthias




^ permalink raw reply	[relevance 9%]

* Re: How to use associative arrays in Ada 2005?
  @ 2006-11-21 14:18  7% ` Matthew Heaney
    0 siblings, 1 reply; 52+ results
From: Matthew Heaney @ 2006-11-21 14:18 UTC (permalink / raw)


"snoopysalive" <matthias.kistler@gmx.de> writes:

> Can anybody explain me how to use associative arrays in Ada 2005? I
> mean hashes like in Perl. 

There are actually two kinds of "associative arrays" in Ada05: ordered maps and
hashed maps.  Each of these container types accept both a key and element as
generic formal types.  (There are also sets, that accept just an element type.)

If both the key and element are "definite" types (types that don't require a
constraint to specify the size), then you can use:

ada.containers.hashed_maps
ada.containers.ordered_maps

If either the key or element is an "indefinite" type (such as String), then you
can use:

ada.containers.indefinite_hashed_maps
ada.containers.indefinite_ordered_maps

If you use the hashed version, you'll need a hash function for your key type.
The library comes with a hash function for type String (and Wide_String, etc);
see Ada.Strings.Hash.

If you use the ordered version, you'll need a relation operation ("<") for your
key type.


> In my opinion, C++ is cool but Ada's syntax is
> better to avoid dirty code.

If you're familiar with the STL, then you should have no trouble with the Ada
container library.


> So, when I say "hash", I mean something Perl-like like
> "$hashname{key1}{key2} = 'something' ". Or something C++-like like "map
> <string,int> hashname; hashname["key1"] = 42;".

Right.  People often say "hash" but in reality that's just one way of
implementing an associative container.  In Ada05 you can use either the hashed
version or the ordered version.

Your example above would be:

package String_Integer_Maps is
  new Ada.Containers.Indefinite_Hashed_Maps
    (String,
     Integer,
     Ada.Strings.Hash,
     Equivalent_Keys => "=");

Note that there's no index operator (operator[]()) in Ada, so you say:

  procedure Op (M : in out String_Integer_Maps.Map) is
  begin
    M.Include ("key1", 42);
  end;

Note that this is not exactly equivalent to the C++ operation, since in Ada the
key is replaced too (if it already exists).  That's unnecessary here so a
slightly more efficient technique might be:

  procedure Op (M : in out String_Integer_Maps.Map) is
    C : Cursor;
    B : Boolean;
  begin
    M.Insert ("key1", 42, C, B);
    if not B then
      M.Replace_Element (C, 42);
    end if;
  end Op;


> Is there anything similar in Ada 2005, too? I bought the book
> "Programming in Ada 2005" by John Barnes but I don't understand the
> author's way of explaining a programming language (for me, the book is
> more confusing than explaining).

That book has a chapter (17?) on the container library.  If you have a specific
question just post here or send me some email.


> Or does anybody know a good tutorial similar to the lots of C- and
> Perl-tutorials? I found many Ada-tutorials but most of them just list
> the contents of the built-in packages and don't explain how to use
> them. As a beginner this is confusing.

If just gave a tutorial on the Ada05 container library.  I can give you the
power-point slides or send you a pdf version.  Drop me a line if you're
interested.

But as a said above, the Ada standard container library is very similar to the
C++ STL, so if you already know the latter than the former shouldn't be much of
a stretch.

-Matt



^ permalink raw reply	[relevance 7%]

* Re: puzzled re hyperthreaded performance
  @ 2005-09-20  0:26  7% ` tmoran
  0 siblings, 0 replies; 52+ results
From: tmoran @ 2005-09-20  0:26 UTC (permalink / raw)


> I think the hypertreading is more like multiplexing the cpu over different
> threads without the
> cost of taskswitching but t does not give you additional CPU performance.
> This effect can make measurements very confusing.
>
> I whould like to know if anyone has a different experience.
  Running a sort on 100K floats (so about 400K bytes) I find a substantial
speedup (about 30%) if it's split into two simultaneous tasks, the main
program and an Ada task.
  Using Ada.Containers.Hashed_Maps to find all the n-character strings in
a given 50K string of just 4 letters (simulated DNA) with the main
program doing it for n=12 and the extra Ada task for n=18, there is no
improvement, and in fact a loss.  But the same program run with n=6 and
n=8 does show significant speedup.  In the former case, there are roughly
50K strings of the indicated sizes, so the hash table presumably has about
50000*18 bytes of key data or roughly 1MB, so the second task, which needs
another 1MB hash table, is probably fighting over the processor's total 1MB
cache space, while in the latter case there is probably room for both in
cache.  If I switch to Ada.Containers.Indefinite_Hashed_Maps, then even
the small one shows no multitasking speedup.  I haven't analyzed
Indefinite_Hashed_Maps to see why that might be the case.
  Running a word counting program, there was a substantial speedup by
processing alternate buffer loads via the environment task and a second
task.  In that case there was probably no cache contention, and one
task was probably processing its bufferload while the other was doing
IO (which probably did not come off disk except on the first run of
the program).
  The above is on a hyperthreaded Pentium under Windows 2000. YMMV



^ permalink raw reply	[relevance 7%]

* Re: puzzled re hyperthreaded performance
  @ 2005-09-15 21:43  8% ` tmoran
  0 siblings, 0 replies; 52+ results
From: tmoran @ 2005-09-15 21:43 UTC (permalink / raw)


Further data:

>     Cache thrashing certainly comes to mind as a possible problem with
> multi-threading.  But the program at hand is small.  I cut the problem
> size so there are at most two simultaneous hash tables of Length 4091 for
> 6 character Strings, which, assuming 20 bytes/entry would be 2*4000*20 or
> 160K, plus 50K input String = 210K which I would think would fit well
> inside the cache without thrashing.  But it's still slower (about 10%) to
> run multithreaded than sequential.
   Since this used exclusively 6 character Strings, I changed from
Ada.Containers.Indefinite_Hashed_Maps to
Ada.Containers.Hashed_Maps
Now the parallel version runs 30% faster than the sequential one.
Increasing the string (and thus hash table) size to more probably
thrash the cache brings it back to parallel being slower than sequential.
So part of the problem is cache thrashing, but there's still some
remaining problem when using Indefinite_Hashed_Maps.



^ permalink raw reply	[relevance 8%]

* Re: puzzled re hyperthreaded performance
  2005-09-15  5:10  6% puzzled re hyperthreaded performance tmoran
@ 2005-09-15  6:08  0% ` jtg
  0 siblings, 0 replies; 52+ results
From: jtg @ 2005-09-15  6:08 UTC (permalink / raw)


tmoran@acm.org wrote:
>   I have a multitasking program that runs faster if I insert a "delay d;"
> statement to prevent some of the multitasking overlap.
>   This is a version of the Shootout k-nucleotide program, which involves
> a series of create/fill/lookup in hash tables, using the Ada 95 version
> of Ada.Containers.Indefinite_Hashed_Maps  I let the operations run in
> two tasks, each with their own hash table.  Memory requirement are minor.
>     Alt_Task.Start;
>     delay d;
>     Compute;
>     Alt_Task.Finish;
> Alt_Task performs the same computations as Compute, reading the same
> String, but sharing no other data.  There are no obvious task interactions,
> and I don't see any in Ada.Containers
>   For every additional 1.0 seconds of "d", the sequence runs about 1.5
> seconds faster.  This is Gnat 3.15p on W2k on a hyperthreaded Pentium
> (two virtual CPUs).
>   Any suggestions what's going on?

For every second of parallel processing 1.5 second is lost.
So parallel processing slows the computations 2.5 times!
There may be several reasons, more or less obvious.
I guess the most important may be inefficient cache usage.
You may try to perform both operations in sequence, or make them
share the same hash table (if they perform the same computations on
the same data), or split the computations in other way (one
task with hash table and one for calculations only).
Other factor may be task switching, but I can't believe it can
slow the processing so hard!

By the way, when you have "proper" multiprocessor environment, where each
processor has its own cache, in certain circumstances you may observe the
opposite phenomenon: for example problem solving on two processors can run
MORE than two times faster.

I suggest you run a test in some "proper" multiprocessor environment,
i.e. two processors or a true multicore processor (with separate caches),
but not virtual MP.

One more thing: ensure Alt_Task is not terminated on Finish, but
the computations are completed.



^ permalink raw reply	[relevance 0%]

* puzzled re hyperthreaded performance
@ 2005-09-15  5:10  6% tmoran
  2005-09-15  6:08  0% ` jtg
  0 siblings, 1 reply; 52+ results
From: tmoran @ 2005-09-15  5:10 UTC (permalink / raw)


  I have a multitasking program that runs faster if I insert a "delay d;"
statement to prevent some of the multitasking overlap.
  This is a version of the Shootout k-nucleotide program, which involves
a series of create/fill/lookup in hash tables, using the Ada 95 version
of Ada.Containers.Indefinite_Hashed_Maps  I let the operations run in
two tasks, each with their own hash table.  Memory requirement are minor.
    Alt_Task.Start;
    delay d;
    Compute;
    Alt_Task.Finish;
Alt_Task performs the same computations as Compute, reading the same
String, but sharing no other data.  There are no obvious task interactions,
and I don't see any in Ada.Containers
  For every additional 1.0 seconds of "d", the sequence runs about 1.5
seconds faster.  This is Gnat 3.15p on W2k on a hyperthreaded Pentium
(two virtual CPUs).
  Any suggestions what's going on?



^ permalink raw reply	[relevance 6%]

* Re: Hash table
  @ 2005-08-13 23:58  6% ` Matthew Heaney
  0 siblings, 0 replies; 52+ results
From: Matthew Heaney @ 2005-08-13 23:58 UTC (permalink / raw)


David Trudgett <wpower@zeta.org.au.nospamplease>  writes:

> I'm looking for a Free Software Ada95 container library, or in
> particular, a hash table (or associative list).

Ada 2005 will have both sets and maps.  You're asking specifically for a
hashed version, but keep in mind that an ordered container (having an
identical interface, but different time complexity) might satisfy your
needs just as well.

The hashed containers are:

ada.containers.hashed_sets
ada.containers.indefinite_hashed_sets
ada.containers.hashed_maps
ada.containers.indefinite_hashed_maps

The ordered forms are:

ada.containers.ordered_sets
ada.containers.indefinite_ordered_sets
ada.containers.ordered_maps
ada.containers.indefinite_ordered_maps


> I noticed that Ada 2005 may include a standard Ada.Containers library,
> but is there a working prototype of this available now?

Yes, there's a public reference implementation available here:

http://charles.tigris.org/

Follow the links to the CVS repository, to the ai302 subdirectory.  The
names use gnat run-time syntax, so you're looking for:

a-cohama.ad[sb]
a-cihama.ad[sb]
a-cohase.ad[sb]
a-cihase.ad[sb]

Note that these will only compile with an Ada 2005 compiler.  If you're
using the latest version of gnat, use the -gnat05 switch to compile them.

If you don't have an Ada 2005 compiler, then you can modify the sources
to your liking.  That will mean replacing an anonymous access subprogram
parameters with something else, typically a generic operation that
passes the subprogram as a generic formal.  For example, the procedure:

procedure Iterate
  (Container : in Map;
   Process   : not null access procedure (Position : Cursor));

should be re-written as:

generic
   with procedure Process (Position : Cursor);
procedure Generic_Iteration (Container : in Map);

(Note that replacing the anonymous access subprogram parameters with
named access parameters is probably not what you want, because of the
accessibility rules.  Hence the generic declaration above.)


> A bit of searching found the ASL (Ada Structured Library --
> http://sourceforge.net/projects/adasl), which hasn't had a new release
> since 2001 (which means it must be perfect ;-)). Should I use ASL, and
> if I do, will it be completely different from the proposed
> Ada.Containers standard?

I would try to use a reference implementation of the standard library,
modified as necessary to run under pure Ada 95.  I can help you make the
necessary modifications.

In general, we prefer that users use the standard library now, since
that helps us find bugs in the design of the library (early adopters
have been extremely helpful here), and in the actual implementation of
the library.


> I'm using Gnat (3.15p) on Debian Linux.

Do you have access to gcc 4.x?  The standard container library is
already bundled with the gcc 4 release.

-Matt



^ permalink raw reply	[relevance 6%]

* Re: GCC 4.0 Ada.Containers Cursor danger.
  2005-07-04 11:01  7% GCC 4.0 Ada.Containers Cursor danger Dmitriy Anisimkov
@ 2005-07-16 23:24  8% ` Matthew Heaney
  0 siblings, 0 replies; 52+ results
From: Matthew Heaney @ 2005-07-16 23:24 UTC (permalink / raw)


"Dmitriy Anisimkov" <anisimkov@yahoo.com> writes:

> IMHO the cursors in the Ada.Containers implemented in GCC 4.0
> dangerouse like pointers in C/C++.
> 
> Look at the code below.

Here is a simplified version of your example:

with Ada.Containers.Indefinite_Hashed_Maps;  use Ada.Containers;
with Ada.Strings.Hash;                       use Ada.Strings;

procedure Test_HM is
   package Map_Types is
      new Indefinite_Hashed_Maps (String, Integer, Hash, "=");
   use Map_Types;

   M     : Map;
   C, C2 : Cursor;
   B     : Boolean;

begin

   M.Insert ("one", 1);

   M.Insert ("two", 2, C, B);
   pragma Assert (B);

   M.Insert ("three", 3);

   pragma Assert (Has_Element (C));
   pragma Assert (Key (C) = "two");
   pragma Assert (Element (C) = 2);

   C2 := M.Find ("two");
   pragma Assert (Has_Element (C2));
   pragma Assert (Key (C) = "two");
   pragma Assert (Element (C) = 2);

   M.Delete (C2);
   pragma Assert (not Has_Element (C2));
   pragma Assert (not M.Contains ("two"));

   Replace_Element (C, -2);  -- dangling cursor

end Test_HM;


When I compile it as follows (on WinXP):

gnatmake -gnata -g -gnat05 test_hm

and then run it, I get this output:

raised SYSTEM.ASSERTIONS.ASSERT_FAILURE : bad cursor in Replace_Element


Does this behavior adequately satisfy your needs?



^ permalink raw reply	[relevance 8%]

* GCC 4.0 Ada.Containers Cursor danger.
@ 2005-07-04 11:01  7% Dmitriy Anisimkov
  2005-07-16 23:24  8% ` Matthew Heaney
  0 siblings, 1 reply; 52+ results
From: Dmitriy Anisimkov @ 2005-07-04 11:01 UTC (permalink / raw)


IMHO the cursors in the Ada.Containers implemented in GCC 4.0
dangerouse like pointers in C/C++.

Look at the code below.
----------------------------------------------
with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;

package HTab is new Ada.Containers.Indefinite_Hashed_Maps
                      (String, Integer, Ada.Strings.Hash, "=", "=");
-----------------------------------------------------------------
with Ada.Text_IO;
with HTab;

procedure AC1 is
   use Ada.Text_IO;

   package Table renames HTab;

   Cursor    : Table.Cursor;
   Cursor2   : Table.Cursor;
   Container : Table.Map;
   Success   : Boolean;
begin
   Table.Insert (Container, "one", 11111, Cursor, Success);
   pragma Assert (Success);
   Table.Insert (Container, "two", 22222, Cursor, Success);
   pragma Assert (Success);
   Table.Insert (Container, "three", 33333, Cursor, Success);
   pragma Assert (Success);

   Table.Insert (Container, "two", 2222, Cursor, Success);
   pragma Assert (not Success);

   --  Delete element "two" independently.

   Cursor2 := Table.Find (Container, "two");
   Table.Delete (Container, Cursor2);

   --  The erroreneous line below do nothing and do not raise any
exception.

   Table.Replace_Element (Cursor, -22222);

   Cursor := Table.First (Container);

   --  Print all lines, and see that we do not have a key "two".

   while Table.Has_Element (Cursor) loop
      Put_Line (Table.Key (Cursor) & ' ' & Integer'Image (Table.Element
(Cursor)));
      Table.Next (Cursor);
   end loop;
end AC1;
------------------------------------------------------------
The code above have to raise at least runtime error at
Table.Replace_Element (Cursor, -22222); but it do nothing and do not
raise any exception.

valgrind showing the memory corruption
---------------------------
==24602== Invalid read of size 4
==24602==    at 0x804F1EC: htab__replace_element (a-cihama.adb:630)
==24602==    by 0x805024D: _ada_ac1 (ac1.adb:31)
==24602==    by 0x8049C2F: main (b~ac1.adb:157)
==24602==  Address 0x1BA4EAF8 is 8 bytes inside a block of size 16
free'd
==24602==    at 0x1B903B0D: free (vg_replace_malloc.c:152)
==24602==    by 0x805D257: __gnat_free (s-memory.adb:113)
==24602==    by 0x804D8CD: htab(float, long double,...)(...)
(a-cihama.adb:338)
==24602==    by 0x804CAE5: htab__delete__2 (a-cihama.adb:205)
==24602==    by 0x805021E: _ada_ac1 (ac1.adb:27)
==24602==    by 0x8049C2F: main (b~ac1.adb:157)
==24602==
==24602== Invalid write of size 4
==24602==    at 0x804F223: htab__replace_element (a-cihama.adb:632)
==24602==    by 0x805024D: _ada_ac1 (ac1.adb:31)
==24602==    by 0x8049C2F: main (b~ac1.adb:157)
==24602==  Address 0x1BA4EAF8 is 8 bytes inside a block of size 16
free'd
==24602==    at 0x1B903B0D: free (vg_replace_malloc.c:152)
==24602==    by 0x805D257: __gnat_free (s-memory.adb:113)
==24602==    by 0x804D8CD: htab(float, long double,...)(...)
(a-cihama.adb:338)
==24602==    by 0x804CAE5: htab__delete__2 (a-cihama.adb:205)
==24602==    by 0x805021E: _ada_ac1 (ac1.adb:27)
==24602==    by 0x8049C2F: main (b~ac1.adb:157)
---------------------------

I am using "ADT Components" from
http://lgl.epfl.ch/ada/components/index.html too.
I'm writting in ADT but have to use code with AI302.
I did not found so much errors with ADT as with AI302 and with
Ada.Containers cursors.

ADT do not have a cursors at all. All get/put operations from container
is just per key. All iterations via the containers are with simple
generic procedures.

I'm not sure that it is possible to implement runtime error detection
in such cursor situation.

I think that ADT is much more on the Ada way then proposed
Ada.Containers with cursors.




^ permalink raw reply	[relevance 7%]

* Re: Newbie - HashMap!
  @ 2005-03-21  0:19  5% ` Matthew Heaney
  0 siblings, 0 replies; 52+ results
From: Matthew Heaney @ 2005-03-21  0:19 UTC (permalink / raw)


fphsml@gmail.com writes:

> What is the equivalent of the following C++ STL code?
> 
> hash_map<string, string> hm;
> hm["key"] = "value";

Ada doesn't have a user-definable index operator, so to find the Ada
analog of the C++ code fragment above you have to unwind it a bit.  The
code above is equivalent to:

   typedef hash_map<string, string> hm_t;

   hm_t hm;

   typedef hm_t::iterator iter_t;
   typedef pair<iter_t, bool> status_t;

   const hm_t::value_type value(string("key"), string());

   const status_t status = hm.insert(value);

   status.first->second = "value";

The Ada equivalent is:

declare
   package Hashed_Map_Types is
      new Ada.Containers.Indefinite_Hashed_Maps
        (Key_Type     => String,
         Element_Type => String,
         Hash         => Ada.Strings.Hash,
         Equivalent_Keys => "=");

   use Hashed_Map_Types;

   HM : Map;

   C  : Cursor;
   B  : Boolean;
begin
   Insert (HM, "Key", "", C, B);
   Replace_Element (C, By => "Value");
end;

Note that in both the C++ and Ada cases, an element with a default value
is allocated, and then immediately assigned a new value.  It's probably
easier to say instead:

  Include (HM, "Key", "Value");

This inserts value "Value" if "Key" doesn't exist, and replaces the
existing value with "Value" if "Key" does exist.

The operations Insert, Include, and Replace all insert elements, but
vary by their exception behavior.


> I just need simple key lookup. Which library should I use?

You can use a reference implementation of the Ada 2005 standard
container library:

http://charles.tigris.org/source/browse/charles/src/ai302/

You want the indefinite hashed map: a-cihama.ad[sb] .

However, this library is written in Ada 2005, so it might not compile
for you.  (Check with your vendor.)

You could try using the Charles library, which is based on the STL, and
is written in Ada95:

http://charles.tigris.org/source/browse/charles/src/

The file is: charles-maps-hashed-strings-unbounded.ads .

However, the generic formal Element_Type is definite, so you'd probably
have to use an unbounded string:

package Hashed_Map_Types is
  new Charles.Maps.Hashed.Strings.Unbounded 
    (Unbounded_String);  --default everthing else

declare
   HM : Hashed_Map_Types.Container_Type;
begin
   Replace (HM, "Key", To_Unbounded_String ("Value"));
begin



-Matt



^ permalink raw reply	[relevance 5%]

* Most up to date AI302 implementation?
@ 2005-02-16 17:50  7% Alex R. Mosteo
  0 siblings, 0 replies; 52+ results
From: Alex R. Mosteo @ 2005-02-16 17:50 UTC (permalink / raw)


Hello, I'm trying to get the subject thing and I'm a bit confused. At 
charles.tigris.org I'm directed to Mr Heaney website. There's a zip file 
almost a year old.

Files inside are named ai302.blah... but I detect some differences with 
the ones used in, for example, AWS, which I have around.

In AWS:

AI302.Indefinite_Hashed_Maps;

In Heaney's website:

AI302.Hashed_Indefinite_Maps;

Finally, in the CVS of tigris I see the files have the name:

Ada.Containers.Indefinite_Hashed_Maps;

So I'm a bit puzzled. My first intention was to use the zip at Mr Heaney 
site, but now I don't know.

Or maybe the best option is to export the CVS version?



^ permalink raw reply	[relevance 7%]

* Re: Bye, bye?
  @ 2005-02-09 19:04  7%     ` mheaney
  0 siblings, 0 replies; 52+ results
From: mheaney @ 2005-02-09 19:04 UTC (permalink / raw)



Wes Groleau wrote:
>
> But much of what I do depends on hashes
> (associative arrays), which are built-in to perl.
> Plus I attach the hash to a DBM file.
>
> To do that in Ada, I'd have to not only upgrade Xcode
> (not an option right now) and install Ada (easy, but
> requires Xcode), but I'd also have to find or build
> a hash package (not hard) and/or a DBM binding (a little
> harder).


Associative arrays will be included in the next version of Ada, as part
of the standard container library:

ada.containers.hashed_maps
ada.containers.indefinite_hashed_maps

There will also be an ordered version (which does the same thing as the
hashed version, but with a different time complexity; it's also a bit
simpler to instantiate):

ada.containers.ordered_maps
ada.containers.indefinite_ordered_maps

There are also hashed and ordered sets (for use when you don't need a
separate key and element).

You can get a reference implementation in the ai302 subdirectory at the
charles.tigris.org website.

Look for the files named a-c*.ad[sb] .

-Matt




^ permalink raw reply	[relevance 7%]

* Re: Missing features in Ada.Containers
    2004-10-08 10:07  6% ` Martin Dowie
@ 2004-10-08 14:57  8% ` Matthew Heaney
  1 sibling, 0 replies; 52+ results
From: Matthew Heaney @ 2004-10-08 14:57 UTC (permalink / raw)



"Alex R. Mosteo" <devnull@mailinator.com> wrote in message
news:416657E2.9050503@mailinator.com...
>
> Of the top of my head I find notable the absence of the "hashed strings"
> container. Now it seems you're alone with a "hashed map" whose keys are
> generic of constrained nature. Thus you must make some leaps to have the
> old (and in my case, most used) hashed string container. Indeed it
> requires ugly conversions between the key type, String, defining the
> hashing function simply to reuse the Ada.Hash_String, etc. It smells so
> wrong to me that I'm almost sure I'm missing something obvious here.

The container ada.containers.indefinite_hashed_maps allows both the key and
element types to be indefinite.  All you need to do is instantiate the
indefinite_hashed_maps with type String as the generic actual key type, and
all will be well.


> Another bizarre (I suppose it was discussed in the mettings) novelty
> (but really of minor relevance as I see it) is that the "sorted maps"
> functionality is now a child package of the "sorted sets". Not only this
> requires now two instantiations to get a "sorted map" but it imposes the
> use of a "sorted set" even if you don't want one?

We made a tentative agreement to add both ordered_maps and hashed_sets to
the API.

I suggest you post a note on the ada-comment list to let the ARG know that
you want these containers.


> I know these comments, accurate or not, come too late... but I've just
> started to use these new containers and even if I did read the past
> discussions about the AI.302, I didn't know the specifics.

See the a-c*.ad[sb] files at the http://charles.tigris.org/.

(Don't confuse the a-c*.ad[sb] files with the ai302.containers.* files.
Only the a-c* files are up-to-date.)






^ permalink raw reply	[relevance 8%]

* Re: Missing features in Ada.Containers
  2004-10-08 10:07  6% ` Martin Dowie
@ 2004-10-08 12:43  0%   ` Alex R. Mosteo
  0 siblings, 0 replies; 52+ results
From: Alex R. Mosteo @ 2004-10-08 12:43 UTC (permalink / raw)


Martin Dowie wrote:
> Alex R. Mosteo wrote:
> 
>>Of the top of my head I find notable the absence of the "hashed
>>strings" container. Now it seems you're alone with a "hashed map"
>>whose keys are generic of constrained nature. Thus you must make some
>>leaps to have the old (and in my case, most used) hashed string
>>container. Indeed it requires ugly conversions between the key type,
>>String, defining the hashing function simply to reuse the
>>Ada.Hash_String, etc. It smells so wrong to me that I'm almost sure
>>I'm missing something obvious here.
> 
> 
> Can't you use "Ada.Containers.Indefinite_Hashed_Maps"?

That's it. I knew I was missing something :( When I looked at the 
package I missed that the Key was unconstrained too.



^ permalink raw reply	[relevance 0%]

* Re: Missing features in Ada.Containers
  @ 2004-10-08 10:07  6% ` Martin Dowie
  2004-10-08 12:43  0%   ` Alex R. Mosteo
  2004-10-08 14:57  8% ` Matthew Heaney
  1 sibling, 1 reply; 52+ results
From: Martin Dowie @ 2004-10-08 10:07 UTC (permalink / raw)


Alex R. Mosteo wrote:
> Of the top of my head I find notable the absence of the "hashed
> strings" container. Now it seems you're alone with a "hashed map"
> whose keys are generic of constrained nature. Thus you must make some
> leaps to have the old (and in my case, most used) hashed string
> container. Indeed it requires ugly conversions between the key type,
> String, defining the hashing function simply to reuse the
> Ada.Hash_String, etc. It smells so wrong to me that I'm almost sure
> I'm missing something obvious here.

Can't you use "Ada.Containers.Indefinite_Hashed_Maps"?





^ permalink raw reply	[relevance 6%]

Results 1-52 of 52 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2004-10-08  9:03     Missing features in Ada.Containers Alex R. Mosteo
2004-10-08 10:07  6% ` Martin Dowie
2004-10-08 12:43  0%   ` Alex R. Mosteo
2004-10-08 14:57  8% ` Matthew Heaney
2005-02-02  2:48     Bye, bye? Wes Groleau
2005-02-02 21:12     ` Ludovic Brenta
2005-02-03  4:24       ` Wes Groleau
2005-02-09 19:04  7%     ` mheaney
2005-02-16 17:50  7% Most up to date AI302 implementation? Alex R. Mosteo
2005-03-17 12:03     Newbie - HashMap! fphsml
2005-03-21  0:19  5% ` Matthew Heaney
2005-07-04 11:01  7% GCC 4.0 Ada.Containers Cursor danger Dmitriy Anisimkov
2005-07-16 23:24  8% ` Matthew Heaney
2005-08-13  0:43     Hash table David Trudgett
2005-08-13 23:58  6% ` Matthew Heaney
2005-09-15  5:10  6% puzzled re hyperthreaded performance tmoran
2005-09-15  6:08  0% ` jtg
2005-09-15 20:44     tmoran
2005-09-15 21:43  8% ` tmoran
2005-09-19 20:21     Wiljan Derks
2005-09-20  0:26  7% ` tmoran
2006-11-21 10:11     How to use associative arrays in Ada 2005? snoopysalive
2006-11-21 14:18  7% ` Matthew Heaney
2006-11-21 23:35       ` snoopysalive
2006-11-23 19:27  9%     ` snoopysalive
2006-11-24  0:33  8%       ` Georg Bauhaus
2006-11-24  8:27           ` Dmitry A. Kazakov
2006-11-24 11:51             ` Matthew Heaney
2006-11-26 19:05  5%           ` snoopysalive
2006-11-26 20:30  0%             ` Matthew Heaney
2006-11-24 11:35  0%       ` Matthew Heaney
2007-04-25 14:13 14% Ada.Containers.Indefinite_Hashed_Maps markp
2007-04-25 17:43 12% ` Ada.Containers.Indefinite_Hashed_Maps Jeffrey R. Carter
2007-04-26 12:12  7%   ` Ada.Containers.Indefinite_Hashed_Maps Maciej Sobczak
2007-04-26 12:55  7%     ` Ada.Containers.Indefinite_Hashed_Maps Stefan Bellon
2007-04-26 16:13  7%       ` Ada.Containers.Indefinite_Hashed_Maps Matthew Heaney
2007-04-27  4:39  7%     ` Ada.Containers.Indefinite_Hashed_Maps Jeffrey R. Carter
2007-04-26 15:52  5% ` Ada.Containers.Indefinite_Hashed_Maps Matthew Heaney
2007-04-26 19:56  7%   ` Ada.Containers.Indefinite_Hashed_Maps Matthew Heaney
2007-04-26 16:12  7% ` Ada.Containers.Indefinite_Hashed_Maps Matthew Heaney
2007-11-14 23:28     OO Style with Ada Containers braver
2007-11-14 23:50     ` Adam Beneschan
2007-11-14 23:59       ` braver
2007-11-15  0:24         ` braver
2007-11-19  2:24  5%       ` Matthew Heaney
2008-05-19 15:50     Bug in GCC ? Sébastien
2008-05-19 15:57  9% ` Matthew Heaney
2011-12-18 12:34     String_Holder ? Natasha Kerensikova
2011-12-19 11:12  6% ` Martin
2012-05-04 13:26     Little people supporting Ada, possibly through AdaCore? Patrick
2012-05-04 14:36     ` Marc C
2012-07-16 15:47  6%   ` Adrian Hoe
2012-07-16 18:13         ` Marc C
2012-07-17  1:58           ` Adrian Hoe
2012-07-17  6:00             ` Thomas Løcke
2012-07-17 13:47               ` Adrian Hoe
2012-07-17 15:06  7%             ` Thomas Løcke
2014-05-19 10:10 12% Strange compile-time error with Ada.Containers.Indefinite_Hashed_Maps mockturtle
2014-05-19 13:49 13% ` Simon Wright
2014-05-19 16:00  6%   ` mockturtle
2014-05-19 16:19  7%     ` G.B.
2014-05-19 16:35  7%     ` Simon Wright
2014-05-19 21:27  7%     ` J-P. Rosen
2014-05-20  6:30  7%       ` Simon Wright
2014-05-20 20:47  7%       ` björn lundin
2014-05-21  5:04  7%         ` J-P. Rosen
2014-05-25 18:28  7%           ` björn lundin
2014-05-26  8:53  7%             ` J-P. Rosen
     [not found]     <8ac0299b-1935-46f9-962a-57fb710e8cf7@googlegroups.com>
2014-10-01 18:16  4% ` Can anyone build AWS on Windows? Björn Lundin
2019-10-29 13:43     How to Iterate over all elements of a hashed_map Alain De Vos
2019-10-29 14:20  8% ` Alain De Vos
2019-10-29 15:02  0%   ` joakimds
2019-10-29 21:56  0%     ` Randy Brukardt
2022-09-14 12:36     Non-standard functions in GNAT's Ada.Containers packages? G.B.
2022-09-14 16:04     ` Egil H H
2022-09-15  7:13       ` G.B.
2022-09-15 14:26         ` Marius Amado-Alves
2022-09-15 15:03           ` Niklas Holsti
2022-09-15 17:11             ` Marius Amado-Alves
2022-09-16 11:33  7%           ` Björn Lundin
2022-09-16 15:00  0%             ` Marius Amado-Alves
2022-09-16 15:42  8%               ` Egil H H
2022-09-16 18:53  0%               ` Björn Lundin

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