* Confused about class-wide types
@ 2016-03-20 11:15 Mart van de Wege
2016-03-20 12:29 ` Dmitry A. Kazakov
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Mart van de Wege @ 2016-03-20 11:15 UTC (permalink / raw)
Hi,
I'm finding myself a little confused about the interaction between
class-wide types.
Here's some example code:
Spec:
with Ada.Containers.Vectors;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
package Types_Test is
type Event is abstract tagged null record;
type Event_Ptr is access Event'Class;
type Message_Event is new Event with private;
type Message_Event_Ptr is access Message_Event'Class;
procedure Message (M : in out Message_Event_Ptr;
Mess : in String);
package Events is new Ada.Containers.Vectors ( Index_Type => Natural,
Element_Type => Event_Ptr);
private
type Message_Event is new Event with record
Message : Unbounded_String;
end record;
end Types_Test;
Test program:
with Types_Test; use Types_Test;
procedure Test_Type
is
M : Message_Event_Ptr;
Log : Events.Vector;
begin
M := new Message_Event;
Message(M,"Test Message");
Log.Append(M);
end Test_Type;
The idea is that Events.Vector should be able to hold different types of
Events. Yet if I compile it this way, GNAT bombs out with:
test_type.adb:9:15: expected type "Event_Ptr" defined at types_test.ads:5
test_type.adb:9:15: found type "Message_Event_Ptr" defined at types_test.ads:7
Obviously, I'm doing something wrong; I'm probably misunderstanding
something, but what?
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Confused about class-wide types
2016-03-20 11:15 Confused about class-wide types Mart van de Wege
@ 2016-03-20 12:29 ` Dmitry A. Kazakov
2016-03-20 13:58 ` Mart van de Wege
2016-03-20 12:46 ` Simon Wright
2016-03-20 13:18 ` Shark8
2 siblings, 1 reply; 9+ messages in thread
From: Dmitry A. Kazakov @ 2016-03-20 12:29 UTC (permalink / raw)
On 2016-03-20 12:15, Mart van de Wege wrote:
> I'm finding myself a little confused about the interaction between
> class-wide types.
>
> Here's some example code:
>
> Spec:
>
> with Ada.Containers.Vectors;
> with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
> package Types_Test is
> type Event is abstract tagged null record;
> type Event_Ptr is access Event'Class;
> type Message_Event is new Event with private;
> type Message_Event_Ptr is access Message_Event'Class;
> procedure Message (M : in out Message_Event_Ptr;
> Mess : in String);
function Message (Mess : in String) return Event_Ptr;
> package Events is new Ada.Containers.Vectors ( Index_Type => Natural,
> Element_Type => Event_Ptr);
> private
> type Message_Event is new Event with record
> Message : Unbounded_String;
> end record;
> end Types_Test;
>
> Test program:
>
> with Types_Test; use Types_Test;
> procedure Test_Type
> is
> M : Message_Event_Ptr;
> Log : Events.Vector;
> begin
> M := new Message_Event;
> Message(M,"Test Message");
> Log.Append(M);
> end Test_Type;
>
> The idea is that Events.Vector should be able to hold different types of
> Events. Yet if I compile it this way, GNAT bombs out with:
Log.Append (Message ("Test Message"));
> test_type.adb:9:15: expected type "Event_Ptr" defined at types_test.ads:5
> test_type.adb:9:15: found type "Message_Event_Ptr" defined at types_test.ads:7
>
> Obviously, I'm doing something wrong; I'm probably misunderstanding
> something, but what?
Ada has named types equivalence. Event_Ptr and Message_Event_Ptr are two
independent types regardless what they point to. If you declared
type Message_Event_Ptr is access Event'Class;
It would not work. Event if you did
type Message_Event_Ptr is new Event_Ptr;
It still would not.
All this is unrelated to class-wide vs specific types.
BTW, it is a bad idea to use pointers, as bad as using vectors for a
FIFO or Unbounded_String to keep constant strings. To dynamically
allocate Unbounded_String which contents is again dynamically allocated
is quite bizarre. Pointers could be used with queues when messages are
pre-allocated elsewhere, in order to avoid copying overhead.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Confused about class-wide types
2016-03-20 11:15 Confused about class-wide types Mart van de Wege
2016-03-20 12:29 ` Dmitry A. Kazakov
@ 2016-03-20 12:46 ` Simon Wright
2016-03-20 14:01 ` Mart van de Wege
2016-03-20 13:18 ` Shark8
2 siblings, 1 reply; 9+ messages in thread
From: Simon Wright @ 2016-03-20 12:46 UTC (permalink / raw)
Mart van de Wege <mvdwege@gmail.com> writes:
> with Ada.Containers.Vectors;
> with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
> package Types_Test is
> type Event is abstract tagged null record;
> type Event_Ptr is access Event'Class;
> type Message_Event is new Event with private;
> type Message_Event_Ptr is access Message_Event'Class;
You don't need this; Event_Ptr covers Message_Event'Class.
> procedure Message (M : in out Message_Event_Ptr;
> Mess : in String);
M should be of type Message_Event.
> Test program:
>
> with Types_Test; use Types_Test;
> procedure Test_Type
> is
> M : Message_Event_Ptr;
This should be of type Event_Ptr.
> Log : Events.Vector;
> begin
> M := new Message_Event;
> Message(M,"Test Message");
Now it gets tricky.
Message(Message_Event(M.all),"Test Message");
works, because M.All is of type Event'Class and we can do a view
conversion to Message_Event (that's what it was created as in the first
place; we'd get CE if it wasn't).
I think this is difficult because you've introduced operations for the
child (Message_Event) of which the parent (Event) has no analogue at
all. What is the common operation that all Events must support?
Maybe something like
procedure Handle (E : Event) is abstract;
Your procedure Message is a factory, I think; it might be better as
function Message (Mess : in String) return Message_Event;
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Confused about class-wide types
2016-03-20 11:15 Confused about class-wide types Mart van de Wege
2016-03-20 12:29 ` Dmitry A. Kazakov
2016-03-20 12:46 ` Simon Wright
@ 2016-03-20 13:18 ` Shark8
2016-03-20 13:56 ` Mart van de Wege
2016-03-21 21:54 ` Randy Brukardt
2 siblings, 2 replies; 9+ messages in thread
From: Shark8 @ 2016-03-20 13:18 UTC (permalink / raw)
On Sunday, March 20, 2016 at 5:16:24 AM UTC-6, Mart van de Wege wrote:
> package Events is new Ada.Containers.Vectors ( Index_Type => Natural,
> Element_Type => Event_Ptr);
If you are using Ada 2012, then you can change "Events" to Ada.Containers.Indefinite_Vectors with an Element_Type of Event'Class... which should, in turn, eliminate the need for any pointer-types in the test. (It also has the advantage of not needing to check the vector for Null.)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Confused about class-wide types
2016-03-20 13:18 ` Shark8
@ 2016-03-20 13:56 ` Mart van de Wege
2016-03-21 21:54 ` Randy Brukardt
1 sibling, 0 replies; 9+ messages in thread
From: Mart van de Wege @ 2016-03-20 13:56 UTC (permalink / raw)
Shark8 <onewingedshark@gmail.com> writes:
> On Sunday, March 20, 2016 at 5:16:24 AM UTC-6, Mart van de Wege wrote:
>> package Events is new Ada.Containers.Vectors ( Index_Type => Natural,
>> Element_Type => Event_Ptr);
>
>
> If you are using Ada 2012, then you can change "Events" to
> Ada.Containers.Indefinite_Vectors with an Element_Type of
> Event'Class... which should, in turn, eliminate the need for any
> pointer-types in the test. (It also has the advantage of not needing
> to check the vector for Null.)
So *that* is what Indefinite_Vectors is for. That would solve my issues,
yes.
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Confused about class-wide types
2016-03-20 12:29 ` Dmitry A. Kazakov
@ 2016-03-20 13:58 ` Mart van de Wege
2016-03-20 14:26 ` Dmitry A. Kazakov
0 siblings, 1 reply; 9+ messages in thread
From: Mart van de Wege @ 2016-03-20 13:58 UTC (permalink / raw)
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>
> Ada has named types equivalence. Event_Ptr and Message_Event_Ptr are
> two independent types regardless what they point to. If you declared
>
Yes, that's what threw me off.
> type Message_Event_Ptr is access Event'Class;
>
> It would not work. Event if you did
>
> type Message_Event_Ptr is new Event_Ptr;
>
> It still would not.
>
> All this is unrelated to class-wide vs specific types.
>
> BTW, it is a bad idea to use pointers, as bad as using vectors for a
> FIFO or Unbounded_String to keep constant strings. To dynamically
> allocate Unbounded_String which contents is again dynamically
> allocated is quite bizarre. Pointers could be used with queues when
> messages are pre-allocated elsewhere, in order to avoid copying
> overhead.
Yeah, but when I want to have a number of different Event types with
some common operations that I want to store in a Vector, I either need
pointers, or, as Shark8 points out, an Indefinite_Vector, which I
overlooked.
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Confused about class-wide types
2016-03-20 12:46 ` Simon Wright
@ 2016-03-20 14:01 ` Mart van de Wege
0 siblings, 0 replies; 9+ messages in thread
From: Mart van de Wege @ 2016-03-20 14:01 UTC (permalink / raw)
Simon Wright <simon@pushface.org> writes:
> I think this is difficult because you've introduced operations for the
> child (Message_Event) of which the parent (Event) has no analogue at
> all. What is the common operation that all Events must support?
> Maybe something like
>
> procedure Handle (E : Event) is abstract;
>
> Your procedure Message is a factory, I think; it might be better as
>
> function Message (Mess : in String) return Message_Event;
>
I was over-designing a bit. At current I only need two classes: an event
with a unstructured String as a Message, and a child event with a bit
more metadata in the record, so I thought I'd start out with an abstract
Event class in my Vector definition, and build the generic operations
first.
Shark8 pointed out the right solution: use an Indefinite_Vector, but
your and Dimitri's posts help a lot with understanding where I went
wrong, thanks.
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Confused about class-wide types
2016-03-20 13:58 ` Mart van de Wege
@ 2016-03-20 14:26 ` Dmitry A. Kazakov
0 siblings, 0 replies; 9+ messages in thread
From: Dmitry A. Kazakov @ 2016-03-20 14:26 UTC (permalink / raw)
On 2016-03-20 14:58, Mart van de Wege wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>> BTW, it is a bad idea to use pointers, as bad as using vectors for a
>> FIFO or Unbounded_String to keep constant strings. To dynamically
>> allocate Unbounded_String which contents is again dynamically
>> allocated is quite bizarre. Pointers could be used with queues when
>> messages are pre-allocated elsewhere, in order to avoid copying
>> overhead.
>
> Yeah, but when I want to have a number of different Event types with
> some common operations that I want to store in a Vector,
Variant record is also an option, but not for strings.
> I either need
> pointers, or, as Shark8 points out, an Indefinite_Vector, which I
> overlooked.
A vector is still not a ring buffer / FIFO.
If messages are large you might use handles/pointers to the
reference-counted object. The FIFO holds handles instead of objects.
That prevents multiple copying on enqueue/dequeue. Upon enqueue you
increase the count, upon dequeue you decrease it.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Confused about class-wide types
2016-03-20 13:18 ` Shark8
2016-03-20 13:56 ` Mart van de Wege
@ 2016-03-21 21:54 ` Randy Brukardt
1 sibling, 0 replies; 9+ messages in thread
From: Randy Brukardt @ 2016-03-21 21:54 UTC (permalink / raw)
"Shark8" <onewingedshark@gmail.com> wrote in message
news:c5f5d5ac-89c4-4b60-9388-f461ed69eb0e@googlegroups.com...
>On Sunday, March 20, 2016 at 5:16:24 AM UTC-6, Mart van de Wege wrote:
>> package Events is new Ada.Containers.Vectors ( Index_Type => Natural,
>> Element_Type => Event_Ptr);
>
>If you are using Ada 2012, then you can change "Events" to
>Ada.Containers.Indefinite_Vectors ...
Indefinite_Vectors was actually introduced with the original containers
library in Ada 2005; you don't need Ada 2012 to use it. (Since there are a
number of non-GNAT compilers that claim to support Ada 2005, using it
doesn't lock you in quite as much.)
Randy.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2016-03-21 21:54 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-20 11:15 Confused about class-wide types Mart van de Wege
2016-03-20 12:29 ` Dmitry A. Kazakov
2016-03-20 13:58 ` Mart van de Wege
2016-03-20 14:26 ` Dmitry A. Kazakov
2016-03-20 12:46 ` Simon Wright
2016-03-20 14:01 ` Mart van de Wege
2016-03-20 13:18 ` Shark8
2016-03-20 13:56 ` Mart van de Wege
2016-03-21 21:54 ` Randy Brukardt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox