Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

I want 'Class'Input back!

1 view
Skip to first unread message

Ted Dennison

unread,
Oct 12, 1999, 3:00:00 AM10/12/99
to
I'm experimenting with making a private type limited. Unfortunately
doing this toasts the default definitions for the stream attributes for
that type. But I *liked* the default definitions for the stream
attributes. In fact, I need 'Input, 'Output, 'Class'Input, and
'Class'Output.

So just write my own clones of those attributes, then do a "for
typename'{Attribute} use", right? Well, the problem is I can't figure
out is how to (re)make 'Class'Input myself. Its definition from the LRM
is:

First reads the external tag from Stream and determines the
corresponding internal tag (by calling
Tags.Internal_Tag(String'Input(Stream)) -- see 3.9) and then dispatches
to the subprogram denoted by the Input attribute of the specific type
identified by the internal tag; returns that result.

So how do I write Ada code to do this? I hope I'm missing something
simple.

--
T.E.D.


Sent via Deja.com http://www.deja.com/
Before you buy.

Matthew Heaney

unread,
Oct 12, 1999, 3:00:00 AM10/12/99
to
In article <7u0as6$fmm$1...@nnrp1.deja.com> , Ted Dennison
<denn...@telepath.com> wrote:

> I'm experimenting with making a private type limited.

Good choice.

> Unfortunately doing this toasts the default definitions for the stream
> attributes for that type. But I *liked* the default definitions for the stream
> attributes. In fact, I need 'Input, 'Output, 'Class'Input, and 'Class'Output.

I think you only need to replace the stream attribute operations of the
*specific* type T.

The stream attributes T'Class'Input and T'Class'Output describe the
attributes of the *class-wide* type, which the compiler supplies for
you.

The compiler implements T'Class'<whatever> by calling the ops you supply
for the specific type. (I think.)


> So just write my own clones of those attributes, then do a "for
> typename'{Attribute} use", right? Well, the problem is I can't figure
> out is how to (re)make 'Class'Input myself. Its definition from the LRM
> is:

You don't have to. Just supply ops for T'Input and T'Output.


> First reads the external tag from Stream and determines the
> corresponding internal tag (by calling
> Tags.Internal_Tag(String'Input(Stream)) -- see 3.9) and then dispatches
> to the subprogram denoted by the Input attribute of the specific type
> identified by the internal tag; returns that result.

This is explaining how the compiler implements T'Class'Input -- by
calling your T'Input op.

> So how do I write Ada code to do this? I hope I'm missing something
> simple.

I think it is simple -- you don't have to do anything to get
T'Class'<op>, because the compiler does it for you.


Matt

--
If we let the Creationists have their way, we may as well go whole hog.
Let us reintroduce the flat-earth theory, the chemistry of the four
elements, and mediaeval astrology. For these outworn doctrines have
just as much claim to rival current scientific views as Creationism does
to challenge evolutionary biology.

Abusing Science: The Case Against Creationism
Philip Kitcher

Ted Dennison

unread,
Oct 13, 1999, 3:00:00 AM10/13/99
to
In article <3803c...@news1.prserv.net>,

"Matthew Heaney" <matthew...@acm.org> wrote:
> In article <7u0as6$fmm$1...@nnrp1.deja.com> , Ted Dennison
> <denn...@telepath.com> wrote:

> > attributes. In fact, I need 'Input, 'Output, 'Class'Input, and
> > 'Class'Output.

Yikes! What was I thinking? I meant 'Read and 'Write. 'Input is clearly
nonsense on a limited type (as using it would require assignment).

> I think you only need to replace the stream attribute operations of
> the *specific* type T.
>
> The stream attributes T'Class'Input and T'Class'Output describe the
> attributes of the *class-wide* type, which the compiler supplies for
> you.

That's what I thought too after a cursory look at the literature.
However, according to both Gnat and my TFFE-based compiler, that is not
the case. Without a redefinition of "Instance'Class'Read", both
compilers yack at me with essentially the same error message. Here's the
Gnat example; a line reading:
Instance'Class'Read (Ada.Streams.Stream_Io.Stream(File),
Table);

Gets flagged with the following error message:
interpolation_table.adb:92:18: limited type "Instance'Class" has no
stream attributes

Even though I *do* have the following:
procedure Read (Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : out Instance);
type Instance is abstract tagged limited record
...
for Instance'Read use Read;

If I also add the following lines, the error goes away (with both
compilers):
procedure Read (Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : out Instance'Class);
...
for Instance'Class'Read use Read;

But the problem (as I mis-said before), is that I can't figure out how I
could possibly code my classwide "Read" function to do what 'Class'Read
does.

Ted Dennison

unread,
Oct 18, 1999, 3:00:00 AM10/18/99
to
In article <7u2377$mvf$1...@nnrp1.deja.com>,
Ted Dennison <denn...@telepath.com> wrote:
> In article <3803c...@news1.prserv.net>,

> But the problem (as I mis-said before), is that I can't figure out how
> I could possibly code my classwide "Read" function to do what
> 'Class'Read does.

So it *is* the case that the act of making a type limited private looses
'Class'Read irretrievably? Going once...

Mark Lundquist

unread,
Oct 25, 1999, 3:00:00 AM10/25/99
to
Ted Dennison wrote:
I'm experimenting with making a private type limited. Unfortunately
doing this toasts the default definitions for the stream attributes for
that type. But I *liked* the default definitions for the stream
attributes. In fact, I need 'Input, 'Output, 'Class'Input, and
'Class'Output.
I think there's a workaround that will let you get back the default 'Input and 'Output.  Give this a shot:
 
    with Ada.Streams;
    
    package Foo is
    
        type T_Base is private;
    
        type T is limited private;
    
    private
    
        type T_Base is tagged null record;
    
        type T is new T_Base with null record;
    
        function Input
                    (Stream : access Ada.Streams.Root_Stream_Type'Class) return T;
    
        procedure Output (Stream : access Ada.Streams.Root_Stream_Type'Class;
                          Item : in T);
    
    
        for T'Input use Input;
        for T'Output use Output;
    
    end Foo;
    package body Foo is
    
        function Input
                    (Stream : access Ada.Streams.Root_Stream_Type'Class) return T is
        begin
            return (T_Base'Input (Stream) with null record);
        end Input;
    
        procedure Output (Stream : access Ada.Streams.Root_Stream_Type'Class;
                          Item : in T) is
        begin
            T_Base'Output (Stream, T_Base (Item));
        end Output;
    
    end Foo;

Here we encapsulate and re-export T_Base's default 'Input and 'Output, downcasting the return value in Input and upcasting the Item parameter in Output.  Type T_Base is non-limited, but useless to clients of the package since you don't declare any operations on it, and the derivation of T from T_Base is  hidden in the private part.
 
 

Ted Dennison

unread,
Oct 26, 1999, 3:00:00 AM10/26/99
to
In article <3814EF36...@rational.com>,
Mark Lundquist <ma...@rational.com> wrote:

> function Input
> (Stream : access
Ada.Streams.Root_Stream_Type'Class) return T is
> begin
> return (T_Base'Input (Stream) with null record);
> end Input;

I have to admit I'm not too sure what is going on here. The "return"
line is particularly perplexing. what does "T_Base'Input(Stream) with
null record" do?

> procedure Output (Stream : access
Ada.Streams.Root_Stream_Type'Class;
> Item : in T) is
> begin
> T_Base'Output (Stream, T_Base (Item));
> end Output;

This OTOH looks completely wrong. 'Output doesn't write the type's
tag to the output stream like 'Class'Output does. How is 'Class'Input
going to know which 'Input routine to dispatch to, if it doesn't know
the type's tag?

0 new messages