comp.lang.ada
 help / color / mirror / Atom feed
From: Shark8 <onewingedshark@gmail.com>
Subject: Re: Variant record limitation - what's a better solution?
Date: Wed, 3 Jul 2013 11:35:32 -0700 (PDT)
Date: 2013-07-03T11:35:32-07:00	[thread overview]
Message-ID: <5f82ded8-fd50-41fa-8c0e-c16203fb032f@googlegroups.com> (raw)
In-Reply-To: <0606a658-9816-4611-84dd-4f999bf6018e@googlegroups.com>

On Wednesday, July 3, 2013 1:52:12 AM UTC-6, Peter Brooks wrote:
> 
> Here's an example:
> 
> type
> 
> my_object(X : size_type) is
>        record
>               name : string(1..80);
>               case X is
>                  when small  => Y : small_type; -- line 20
>                  when medium => Y : medium_type; -- line 21
>                  when large  => Y : large_type; -- line 22
>               end case;
> 
>        end record;
> 
> 
> I was hoping to have a different type depending on the case, but this doesn't seem allowed. What would achieve this?

Well, you can use subtypes as you might originally think (but there's a bit of a hiccup) -- example:
    type small_type  is range 0..2**8-1;
    type medium_type is range 0..2**16-1;
    type large_type  is range 0..2**32-1;
    
    
    type size_type is ( small, medium, large );
    
    type my_object(Size : size_type) is
	record
	    name : string(1..80);
	    case Size is
		when small  => small_data : small_type;
		when medium => med_data   : medium_type;
		when large  => large_data : large_type;
	    end case;
	end record;

    subtype small_object  is my_object( Size => small );
    subtype medium_object is my_object( Size => medium );
    subtype large_object  is my_object( Size => large );
    
    
    -- Using Ada 2012 expression-functions for brevity.
    function Get_Data( Item : in small_object ) return small_type is
	( Item.small_data );
    function Get_Data( Item : in medium_object ) return medium_type is
	( Item.med_data );
    function Get_Data( Item : in large_object ) return large_type is
	( Item.large_data );
    
    J : my_object:= ( Size => small,
		      small_data => 128,
		      Name => ('B','o','b', others => ASCII.NUL) 
		    );
    K :  constant integer := Integer(  Get_Data( J )  );

Now the assignment to K shows the problem with this approach, as the compiler points out: ambiguous operand in conversion.

This is because even though the compiler knows the types involved a differing subtypes it cannot [generally] distinguish between them like it would with a case-statement's case coverage. (That is, subtypes in-general aren't mutually exclusive.)

At this point there are two obvious ways to go about addressing this:
1)  add a qualification: e.g. Integer(  Small'(Get_Data( J ))  ); 
    -- The above will make the assignment to K work.
2)  go to a tagged record-type and use standard OO-methodologies there.




  parent reply	other threads:[~2013-07-03 18:35 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-03  7:52 Variant record limitation - what's a better solution? Peter Brooks
2013-07-03  8:11 ` Georg Bauhaus
2013-07-03  9:39   ` Peter Brooks
2013-07-03 16:23 ` Jeffrey Carter
2013-07-03 18:35 ` Shark8 [this message]
2013-07-03 19:26 ` Adam Beneschan
2013-07-09 11:48   ` Peter Brooks
2013-07-09 15:11     ` Adam Beneschan
2013-07-10  1:11       ` Peter Brooks
2013-07-03 20:55 ` Per Sandberg
2013-07-09  6:38 ` Peter Brooks
2013-07-09  7:49   ` Simon Wright
2013-07-09  8:22   ` Georg Bauhaus
2013-07-09 14:12   ` Eryndlia Mavourneen
replies disabled

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