* Renaming of procedures in a generic instantiation
@ 2010-09-26 0:43 Gene
2010-09-26 6:54 ` Niklas Holsti
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Gene @ 2010-09-26 0:43 UTC (permalink / raw)
I'm confused about an aspect of renaming. It boils out to this little
example:
with Ada.Containers.Ordered_Sets;
package Foo is
type Queue is private;
procedure Add(Q : in out Queue; Item : in Integer);
function Is_Empty(Q : Queue) return Boolean;
private
package Queues is
new Ada.Containers.Ordered_Sets(Integer, "<", "=");
type Queue is new Queues.Set with null record;
end Foo;
package body Foo is
procedure Add(Q : in out Queue; Item : in Integer)
renames Insert;
function Is_Empty(Q : Queue) return Boolean
renames Queues.Is_Empty;
end Foo;
The renaming in Add "finds" the correct procedure Insert, but the
renaming of Is_Empty fails:
gnatmake foo.adb
gcc -c foo.adb
foo.adb:6:04: no visible subprogram matches the specification for
"Is_Empty"
foo.adb:6:13: expected private type "Ada.Containers.Ordered_Sets.Set"
from insta
nce at foo.ads:14
foo.adb:6:13: found type "Queue" defined at foo.ads:16
gnatmake: "foo.adb" compilation error
I guess I can see this error because a parameter type conversion is
implied in the renaming. But then why does the renaming of Insert
work correctly?
Running Win7 64 bit with:
gcc (GCC) 4.3.4 20090511 for GNAT GPL 2009 (20090511)
Thanks.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-26 0:43 Renaming of procedures in a generic instantiation Gene
@ 2010-09-26 6:54 ` Niklas Holsti
2010-09-26 7:40 ` Jeffrey Carter
2010-09-26 14:52 ` Gene
2010-09-26 8:45 ` Stephen Leake
2010-09-27 19:23 ` Adam Beneschan
2 siblings, 2 replies; 13+ messages in thread
From: Niklas Holsti @ 2010-09-26 6:54 UTC (permalink / raw)
Gene wrote:
> I'm confused about an aspect of renaming. It boils out to this little
> example:
>
> with Ada.Containers.Ordered_Sets;
>
> package Foo is
>
> type Queue is private;
>
> procedure Add(Q : in out Queue; Item : in Integer);
>
> function Is_Empty(Q : Queue) return Boolean;
>
> private
>
> package Queues is
> new Ada.Containers.Ordered_Sets(Integer, "<", "=");
> type Queue is new Queues.Set with null record;
>
> end Foo;
>
> package body Foo is
>
> procedure Add(Q : in out Queue; Item : in Integer)
> renames Insert;
>
> function Is_Empty(Q : Queue) return Boolean
> renames Queues.Is_Empty;
>
> end Foo;
>
> The renaming in Add "finds" the correct procedure Insert, but the
> renaming of Is_Empty fails:
>
> gnatmake foo.adb
> gcc -c foo.adb
> foo.adb:6:04: no visible subprogram matches the specification for
> "Is_Empty"
> foo.adb:6:13: expected private type "Ada.Containers.Ordered_Sets.Set"
> from insta
> nce at foo.ads:14
> foo.adb:6:13: found type "Queue" defined at foo.ads:16
> gnatmake: "foo.adb" compilation error
>
> I guess I can see this error because a parameter type conversion is
> implied in the renaming. But then why does the renaming of Insert
> work correctly?
The type derivation
type Queue is new Queues.Set with null record;
makes type Queue inherit the primitive operations of Queues.Set by
implicitly declaring (within package Foo) corresponding operations on
type Queue. These include the operation Insert with the profile:
procedure Insert (
Container : in out Queue;
New_Item : in Integer);
This profile matches that of Foo.Add, and so Foo.Add can be a renaming
of this Insert. By the way, this implicitly declared Insert (on Queue)
has the qualified name Foo.Insert, not Queues.Insert.
The type derivation also "tries" to declare implicitly the Is_Empty
operation from Queues, with the profile:
function Is_Empty (Container : Queue) return Boolean;
but this operation clashes with (has the same name and same profile as)
the operation Is_Empty that was already and explicitly declared in Foo
(before the "private"), so they cannot both be visible. If I understand
correctly, the rule RM 8.3(10/1) says that the first, explicit
declaration overrides the second, implicit declaration (because the
first declaration is not "overridable").
So what saves you in the Insert/Add case is that the operation names are
different, which means there is no clash. It is a bit irritating that
the "simpler" case, with the same names, does not work in the same way.
I have at times had the same problem, where I have been disappointed
that implementing a private type as a derived type does not implicitly
complete the declarations of matching operations, such as Is_Empty in
this example. I would have liked to be able to write something like:
type Queue is new Queues.Set with null record
overriding Is_Empty (Q : Queue) return Boolean; -- Not Ada!
No doubt you have already found a solution for Is_Empty, but anyway here
is what I would do:
function Is_Empty (Q : Queue) return Boolean
is
begin
return Queues.Is_Empty (Queues.Set (Q));
end Is_Empty;
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-26 6:54 ` Niklas Holsti
@ 2010-09-26 7:40 ` Jeffrey Carter
2010-09-26 8:41 ` Niklas Holsti
2010-09-26 14:52 ` Gene
1 sibling, 1 reply; 13+ messages in thread
From: Jeffrey Carter @ 2010-09-26 7:40 UTC (permalink / raw)
On 09/25/2010 11:54 PM, Niklas Holsti wrote:
>
> No doubt you have already found a solution for Is_Empty, but anyway here
> is what I would do:
>
> function Is_Empty (Q : Queue) return Boolean
> is
> begin
> return Queues.Is_Empty (Queues.Set (Q));
> end Is_Empty;
Or change the name of the operation (Empty comes to mind). I would probably use
a wrapper record:
type Queue_Handle is
Value : Queues.Set;
end record;
procedure Put (Onto : in out Queue_Handle; Item : in Integer) is
-- null;
begin -- Put
Onto.Insert (New_Item => Item);
end Put;
function Is_Empty (Queue : in Queue_Handle) is
-- null;
begin -- Is_Empty
return Queue.Value.Is_Empty;
end Is_Empty;
--
Jeff Carter
"We'll make Rock Ridge think it's a chicken
that got caught in a tractor's nuts!"
Blazing Saddles
87
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-26 7:40 ` Jeffrey Carter
@ 2010-09-26 8:41 ` Niklas Holsti
2010-09-26 17:07 ` Jeffrey Carter
0 siblings, 1 reply; 13+ messages in thread
From: Niklas Holsti @ 2010-09-26 8:41 UTC (permalink / raw)
Jeffrey Carter wrote:
> On 09/25/2010 11:54 PM, Niklas Holsti wrote:
>>
>> No doubt you have already found a solution for Is_Empty, but anyway here
>> is what I would do:
>>
>> function Is_Empty (Q : Queue) return Boolean
>> is
>> begin
>> return Queues.Is_Empty (Queues.Set (Q));
>> end Is_Empty;
>
> Or change the name of the operation (Empty comes to mind). I would
> probably use a wrapper record:
>
> type Queue_Handle is
> Value : Queues.Set;
> end record;
>
> procedure Put (Onto : in out Queue_Handle; Item : in Integer) is
> -- null;
> begin -- Put
> Onto.Insert (New_Item => Item);
A nit: You surely meant
Onto.Value.Insert (New_Item => Item);
> end Put;
>
> function Is_Empty (Queue : in Queue_Handle) is
> -- null;
> begin -- Is_Empty
> return Queue.Value.Is_Empty;
> end Is_Empty;
>
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-26 0:43 Renaming of procedures in a generic instantiation Gene
2010-09-26 6:54 ` Niklas Holsti
@ 2010-09-26 8:45 ` Stephen Leake
2010-09-26 9:11 ` Niklas Holsti
2010-09-27 1:18 ` Gene
2010-09-27 19:23 ` Adam Beneschan
2 siblings, 2 replies; 13+ messages in thread
From: Stephen Leake @ 2010-09-26 8:45 UTC (permalink / raw)
Gene <gene.ressler@gmail.com> writes:
> I'm confused about an aspect of renaming. It boils out to this little
> example:
>
> with Ada.Containers.Ordered_Sets;
>
> package Foo is
>
> type Queue is private;
>
> procedure Add(Q : in out Queue; Item : in Integer);
>
> function Is_Empty(Q : Queue) return Boolean;
>
> private
>
> package Queues is
> new Ada.Containers.Ordered_Sets(Integer, "<", "=");
> type Queue is new Queues.Set with null record;
All primitive operations of Queues.Set are implicitly declared here,
with Queue replacing Queues.Set; that includes Set and Is_Empty. That's
what derived types are for.
> end Foo;
>
> package body Foo is
>
> procedure Add(Q : in out Queue; Item : in Integer)
> renames Insert;
This 'Insert' resolves to Foo.Insert (Container : in out Foo.Queue; ...);
> function Is_Empty(Q : Queue) return Boolean
> renames Queues.Is_Empty;
Queues.Is_Empty expects a Constainer of type Foo.Queues.Set, not Foo.Queue.
If you replace
type Queue is new Queues.Set with null record;
with
subtype Queue is Queues.Set;
Then the Add renames will fail (because the primitive operations are not
derived), and the Is_Empty will succeed.
--
-- Stephe
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-26 8:45 ` Stephen Leake
@ 2010-09-26 9:11 ` Niklas Holsti
2010-09-27 1:18 ` Gene
1 sibling, 0 replies; 13+ messages in thread
From: Niklas Holsti @ 2010-09-26 9:11 UTC (permalink / raw)
Stephen Leake wrote:
> Gene <gene.ressler@gmail.com> writes:
>
>> I'm confused about an aspect of renaming. It boils out to this little
>> example:
>>
>> with Ada.Containers.Ordered_Sets;
>>
>> package Foo is
>>
>> type Queue is private;
>>
>> procedure Add(Q : in out Queue; Item : in Integer);
>>
>> function Is_Empty(Q : Queue) return Boolean;
>>
>> private
>>
>> package Queues is
>> new Ada.Containers.Ordered_Sets(Integer, "<", "=");
>> type Queue is new Queues.Set with null record;
>
> All primitive operations of Queues.Set are implicitly declared here,
> with Queue replacing Queues.Set; that includes Set and Is_Empty. That's
> what derived types are for.
>
>> end Foo;
>>
>> package body Foo is
>>
>> procedure Add(Q : in out Queue; Item : in Integer)
>> renames Insert;
>
> This 'Insert' resolves to Foo.Insert (Container : in out Foo.Queue; ...);
>
>> function Is_Empty(Q : Queue) return Boolean
>> renames Queues.Is_Empty;
>
> Queues.Is_Empty expects a Constainer of type Foo.Queues.Set, not Foo.Queue.
>
> If you replace
>
> type Queue is new Queues.Set with null record;
>
> with
>
> subtype Queue is Queues.Set;
>
> Then the Add renames will fail (because the primitive operations are not
> derived), and the Is_Empty will succeed.
But the subtype declaration of Queue cannot complete the initial
declaration of Queue as private, so the subtype declaration must be the
first and only (and public) declaration of type Queue.
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-26 6:54 ` Niklas Holsti
2010-09-26 7:40 ` Jeffrey Carter
@ 2010-09-26 14:52 ` Gene
2010-09-26 15:04 ` Dmitry A. Kazakov
1 sibling, 1 reply; 13+ messages in thread
From: Gene @ 2010-09-26 14:52 UTC (permalink / raw)
On Sep 26, 2:54 am, Niklas Holsti <niklas.hol...@tidorum.invalid>
wrote:
> Gene wrote:
> > I'm confused about an aspect of renaming. It boils out to this little
> > example:
>
> > with Ada.Containers.Ordered_Sets;
>
> > package Foo is
>
> > type Queue is private;
>
> > procedure Add(Q : in out Queue; Item : in Integer);
>
> > function Is_Empty(Q : Queue) return Boolean;
>
> > private
>
> > package Queues is
> > new Ada.Containers.Ordered_Sets(Integer, "<", "=");
> > type Queue is new Queues.Set with null record;
>
> > end Foo;
>
> > package body Foo is
>
> > procedure Add(Q : in out Queue; Item : in Integer)
> > renames Insert;
>
> > function Is_Empty(Q : Queue) return Boolean
> > renames Queues.Is_Empty;
>
> > end Foo;
>
> > The renaming in Add "finds" the correct procedure Insert, but the
> > renaming of Is_Empty fails:
>
> > gnatmake foo.adb
> > gcc -c foo.adb
> > foo.adb:6:04: no visible subprogram matches the specification for
> > "Is_Empty"
> > foo.adb:6:13: expected private type "Ada.Containers.Ordered_Sets.Set"
> > from insta
> > nce at foo.ads:14
> > foo.adb:6:13: found type "Queue" defined at foo.ads:16
> > gnatmake: "foo.adb" compilation error
>
> > I guess I can see this error because a parameter type conversion is
> > implied in the renaming. But then why does the renaming of Insert
> > work correctly?
>
> The type derivation
>
> type Queue is new Queues.Set with null record;
>
> makes type Queue inherit the primitive operations of Queues.Set by
> implicitly declaring (within package Foo) corresponding operations on
> type Queue. These include the operation Insert with the profile:
>
> procedure Insert (
> Container : in out Queue;
> New_Item : in Integer);
>
> This profile matches that of Foo.Add, and so Foo.Add can be a renaming
> of this Insert. By the way, this implicitly declared Insert (on Queue)
> has the qualified name Foo.Insert, not Queues.Insert.
>
> The type derivation also "tries" to declare implicitly the Is_Empty
> operation from Queues, with the profile:
>
> function Is_Empty (Container : Queue) return Boolean;
>
> but this operation clashes with (has the same name and same profile as)
> the operation Is_Empty that was already and explicitly declared in Foo
> (before the "private"), so they cannot both be visible. If I understand
> correctly, the rule RM 8.3(10/1) says that the first, explicit
> declaration overrides the second, implicit declaration (because the
> first declaration is not "overridable").
>
> So what saves you in the Insert/Add case is that the operation names are
> different, which means there is no clash. It is a bit irritating that
> the "simpler" case, with the same names, does not work in the same way.
>
> I have at times had the same problem, where I have been disappointed
> that implementing a private type as a derived type does not implicitly
> complete the declarations of matching operations, such as Is_Empty in
> this example. I would have liked to be able to write something like:
>
> type Queue is new Queues.Set with null record
> overriding Is_Empty (Q : Queue) return Boolean; -- Not Ada!
>
> No doubt you have already found a solution for Is_Empty, but anyway here
> is what I would do:
>
> function Is_Empty (Q : Queue) return Boolean
> is
> begin
> return Queues.Is_Empty (Queues.Set (Q));
> end Is_Empty;
>
> --
> Niklas Holsti
> Tidorum Ltd
> niklas holsti tidorum fi
> . @ .- Hide quoted text -
Thanks for the clear and quick explanation. It makes sense, but, as
you say, is a bit unsatisfying. I've run into several cases where I
want to implement an abstraction with minor reshaping and restriction
of an Ada.Containers instance. (The current one is event queues for a
simulator.) As you've shown above, there are some quirks in this
approach.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-26 14:52 ` Gene
@ 2010-09-26 15:04 ` Dmitry A. Kazakov
0 siblings, 0 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2010-09-26 15:04 UTC (permalink / raw)
On Sun, 26 Sep 2010 07:52:58 -0700 (PDT), Gene wrote:
> I've run into several cases where I
> want to implement an abstraction with minor reshaping and restriction
> of an Ada.Containers instance. (The current one is event queues for a
> simulator.) As you've shown above, there are some quirks in this
> approach.
Delegation (in order to implement interfaces) is poorly supported in Ada.
In real projects we have huge problems with this. About 40% of the code are
wrappers, nasty, error prone, incredibly difficult to maintain.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-26 8:41 ` Niklas Holsti
@ 2010-09-26 17:07 ` Jeffrey Carter
0 siblings, 0 replies; 13+ messages in thread
From: Jeffrey Carter @ 2010-09-26 17:07 UTC (permalink / raw)
On 09/26/2010 01:41 AM, Niklas Holsti wrote:
> Jeffrey Carter wrote:
>>
>> type Queue_Handle is
>> Value : Queues.Set;
>> end record;
>>
>> procedure Put (Onto : in out Queue_Handle; Item : in Integer) is
>> -- null;
>> begin -- Put
>> Onto.Insert (New_Item => Item);
>
> A nit: You surely meant
>
> Onto.Value.Insert (New_Item => Item);
Yes, of course. Luckily, the compiler catches these for you.
--
Jeff Carter
"It's symbolic of his struggle against reality."
Monty Python's Life of Brian
78
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-26 8:45 ` Stephen Leake
2010-09-26 9:11 ` Niklas Holsti
@ 2010-09-27 1:18 ` Gene
2010-09-28 11:36 ` Stephen Leake
1 sibling, 1 reply; 13+ messages in thread
From: Gene @ 2010-09-27 1:18 UTC (permalink / raw)
On Sep 26, 4:45 am, Stephen Leake <stephen_le...@stephe-leake.org>
wrote:
> Gene <gene.ress...@gmail.com> writes:
> > I'm confused about an aspect of renaming. It boils out to this little
> > example:
>
> > with Ada.Containers.Ordered_Sets;
>
> > package Foo is
>
> > type Queue is private;
>
> > procedure Add(Q : in out Queue; Item : in Integer);
>
> > function Is_Empty(Q : Queue) return Boolean;
>
> > private
>
> > package Queues is
> > new Ada.Containers.Ordered_Sets(Integer, "<", "=");
> > type Queue is new Queues.Set with null record;
>
> All primitive operations of Queues.Set are implicitly declared here,
> with Queue replacing Queues.Set; that includes Set and Is_Empty. That's
> what derived types are for.
>
> > end Foo;
>
> > package body Foo is
>
> > procedure Add(Q : in out Queue; Item : in Integer)
> > renames Insert;
>
> This 'Insert' resolves to Foo.Insert (Container : in out Foo.Queue; ...);
>
> > function Is_Empty(Q : Queue) return Boolean
> > renames Queues.Is_Empty;
>
> Queues.Is_Empty expects a Constainer of type Foo.Queues.Set, not Foo.Queue.
>
> If you replace
>
> type Queue is new Queues.Set with null record;
>
> with
>
> subtype Queue is Queues.Set;
>
> Then the Add renames will fail (because the primitive operations are not
> derived), and the Is_Empty will succeed.
>
> --
> -- Stephe- Hide quoted text -
>
> - Show quoted text -
Thanks. This is one variation I tried. There is first a compiler
complaint that this private subtype declaration doesn't match the
earlier public "type Queue is private". I take it there is no way at
all to declare a type private and then specify it in the private
section as a subtype?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-26 0:43 Renaming of procedures in a generic instantiation Gene
2010-09-26 6:54 ` Niklas Holsti
2010-09-26 8:45 ` Stephen Leake
@ 2010-09-27 19:23 ` Adam Beneschan
2 siblings, 0 replies; 13+ messages in thread
From: Adam Beneschan @ 2010-09-27 19:23 UTC (permalink / raw)
On Sep 25, 5:43 pm, Gene <gene.ress...@gmail.com> wrote:
> I'm confused about an aspect of renaming. It boils out to this little
> example:
>
> with Ada.Containers.Ordered_Sets;
>
> package Foo is
>
> type Queue is private;
>
> procedure Add(Q : in out Queue; Item : in Integer);
>
> function Is_Empty(Q : Queue) return Boolean;
>
> private
>
> package Queues is
> new Ada.Containers.Ordered_Sets(Integer, "<", "=");
> type Queue is new Queues.Set with null record;
>
> end Foo;
>
> package body Foo is
>
> procedure Add(Q : in out Queue; Item : in Integer)
> renames Insert;
>
> function Is_Empty(Q : Queue) return Boolean
> renames Queues.Is_Empty;
>
> end Foo;
>
> The renaming in Add "finds" the correct procedure Insert, but the
> renaming of Is_Empty fails:
>
> gnatmake foo.adb
> gcc -c foo.adb
> foo.adb:6:04: no visible subprogram matches the specification for
> "Is_Empty"
> foo.adb:6:13: expected private type "Ada.Containers.Ordered_Sets.Set"
> from insta
> nce at foo.ads:14
> foo.adb:6:13: found type "Queue" defined at foo.ads:16
> gnatmake: "foo.adb" compilation error
>
> I guess I can see this error because a parameter type conversion is
> implied in the renaming. But then why does the renaming of Insert
> work correctly?
Because you didn't refer to the "Insert" defined in Queues, the way
you did with Is_Empty. If you had declared this, it would be illegal
in the same way:
procedure Add(Q : in out Queue; Item : in Integer)
renames Queues.Insert;
Obviously, you can't solve the problem for Is_Empty by removing the
"Queues." prefix:
function Is_Empty(Q : in out Queue) return Boolean
renames Is_Empty;
I found that this compiles, but it's obnoxious:
with Ada.Containers.Ordered_Sets;
package Foo is
type Queue is private;
procedure Add(Q : in out Queue; Item : in Integer);
function Is_Empty(Q : Queue) return Boolean;
private
package Queues is
new Ada.Containers.Ordered_Sets(Integer, "<", "=");
package Dummy_Package is
type Dummy_Queue is new Queues.Set with null record;
function Rename_Empty(Q : Dummy_Queue) return Boolean
renames Is_Empty;
end Dummy_Package;
type Queue is new Dummy_Package.Dummy_Queue with null record;
end Foo;
package body Foo is
procedure Add(Q : in out Queue; Item : in Integer)
renames Insert;
function Is_Empty(Q : Queue) return Boolean
renames Rename_Empty;
end Foo;
Just writing Is_Empty to call Queues.Is_Empty, as Niklas suggested,
seems better than this. I'd also add "pragma Inline(Is_Empty)" to the
private part of Foo to possibly prevent extraneous call code from
being generated.
I had thought that someone (possibly me) once proposed adding the
ability to declare that a subprogram renames the hidden subprogram
that it overrides, e.g.
function Is_Empty(Q : Queue) return Boolean renames <>;
but I can't find anything like that in my mail records. Randy did
once mention using something like Is_Empty'Parent as a stand-in for
the call to the parent routine; he wasn't thinking of a renaming
context, but it might work here:
function Is_Empty(Q : Queue) return Boolean renames
Is_Empty'Parent;
In any event, however, it seems to be a minor enough problem with a
simple enough workaround that it's not worthwhile to change the
language.
-- Adam
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-27 1:18 ` Gene
@ 2010-09-28 11:36 ` Stephen Leake
2010-09-29 1:25 ` Gene
0 siblings, 1 reply; 13+ messages in thread
From: Stephen Leake @ 2010-09-28 11:36 UTC (permalink / raw)
Gene <gene.ressler@gmail.com> writes:
> Thanks. This is one variation I tried. There is first a compiler
> complaint that this private subtype declaration doesn't match the
> earlier public "type Queue is private". I take it there is no way at
> all to declare a type private and then specify it in the private
> section as a subtype?
Ah; I had not realized the original problem you were having; how to
implement the body for Is_Empty. The simplest approach is this:
with Ada.Containers.Ordered_Sets;
package Foo is
type Queue is private;
procedure Add(Q : in out Queue; Item : in Integer);
function Is_Empty(Q : Queue) return Boolean;
private
package Queues is
new Ada.Containers.Ordered_Sets(Integer, "<", "=");
type Queue is new Queues.Set with null record;
end Foo;
package body Foo is
procedure Add(Q : in out Queue; Item : in Integer)
renames Insert;
function Is_Empty(Q : Queue) return Boolean
is begin
return Queues.Is_Empty (Queues.Set (Q));
end Is_Empty;
end Foo;
--
-- Stephe
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Renaming of procedures in a generic instantiation
2010-09-28 11:36 ` Stephen Leake
@ 2010-09-29 1:25 ` Gene
0 siblings, 0 replies; 13+ messages in thread
From: Gene @ 2010-09-29 1:25 UTC (permalink / raw)
On Sep 28, 7:36 am, Stephen Leake <stephen_le...@stephe-leake.org>
wrote:
> Gene <gene.ress...@gmail.com> writes:
> > Thanks. This is one variation I tried. There is first a compiler
> > complaint that this private subtype declaration doesn't match the
> > earlier public "type Queue is private". I take it there is no way at
> > all to declare a type private and then specify it in the private
> > section as a subtype?
>
> Ah; I had not realized the original problem you were having; how to
> implement the body for Is_Empty. The simplest approach is this:
>
> with Ada.Containers.Ordered_Sets;
> package Foo is
> type Queue is private;
> procedure Add(Q : in out Queue; Item : in Integer);
> function Is_Empty(Q : Queue) return Boolean;
> private
> package Queues is
> new Ada.Containers.Ordered_Sets(Integer, "<", "=");
> type Queue is new Queues.Set with null record;
> end Foo;
> package body Foo is
> procedure Add(Q : in out Queue; Item : in Integer)
> renames Insert;
>
> function Is_Empty(Q : Queue) return Boolean
> is begin
> return Queues.Is_Empty (Queues.Set (Q));
> end Is_Empty;
> end Foo;
>
> --
> -- Stephe
Right. Thanks. Understood that from the outset. Was just scratching
my head because Insert could be defined by renaming, but there was no
way to do the same for Is_Empty owing to the name clash. I thought
there had to be some dot-path that would work. In fact the only
recourses (using renaming) seem to be either to choose another name
for the public Is_Empty or to use the ingenous but truly crufty double
renaming trick shown by Adam Beneschan.
FWIW, I'm working out a framework for a student project, so the desire
for symmetry in the code is more pedantic than esthetic or anything
else.
Thanks guys.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2010-09-29 1:25 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-26 0:43 Renaming of procedures in a generic instantiation Gene
2010-09-26 6:54 ` Niklas Holsti
2010-09-26 7:40 ` Jeffrey Carter
2010-09-26 8:41 ` Niklas Holsti
2010-09-26 17:07 ` Jeffrey Carter
2010-09-26 14:52 ` Gene
2010-09-26 15:04 ` Dmitry A. Kazakov
2010-09-26 8:45 ` Stephen Leake
2010-09-26 9:11 ` Niklas Holsti
2010-09-27 1:18 ` Gene
2010-09-28 11:36 ` Stephen Leake
2010-09-29 1:25 ` Gene
2010-09-27 19:23 ` Adam Beneschan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox