comp.lang.ada
 help / color / mirror / Atom feed
* I need a little help - it's been a long time - with enumeration type and for use representation
@ 2009-11-13 16:03 Harry Tucker
  2009-11-13 17:24 ` Niklas Holsti
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Harry Tucker @ 2009-11-13 16:03 UTC (permalink / raw)


I haven't played with Ada for many years. I've read John Barnes' book,
Programming in Ada 2005, and picked through the ARM on my problem.

I have a piece of data which represents a enumeration as a hexadecimal
value. It is a bit field but I see the data most usefull as an
enumeration. for example in the CSV file the data is represented as
'0x1'. So I defined the enum as:

<code>
   type Spell_School_Type is (
      UNKNOWN,
      PHYSICAL,
      HOLY,
      FIRE,
    ...
</code>

And since the data has a value I use a represetation clause as:
<code>
   for Spell_School_Type use
     (UNKNOWN     => 2#0000_0000#,
      PHYSICAL      => 2#0000_0001#,
      HOLY             => 2#0000_0010#,
      FIRE              => 2#0000_0100#,
    ...
</code>

Is the best way to parse the raw info (i.e. 0x1)  into the enumeration
(i.e PHYSICAL) to use a if/elsif and assign the enum position or is
there an attribute which works best.

Harry



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: I need a little help - it's been a long time - with enumeration type  and for use representation
  2009-11-13 16:03 I need a little help - it's been a long time - with enumeration type and for use representation Harry Tucker
@ 2009-11-13 17:24 ` Niklas Holsti
  2009-11-13 17:24 ` Dmitry A. Kazakov
  2009-11-13 18:46 ` Jeffrey R. Carter
  2 siblings, 0 replies; 10+ messages in thread
From: Niklas Holsti @ 2009-11-13 17:24 UTC (permalink / raw)


Harry Tucker wrote:
> I haven't played with Ada for many years. I've read John Barnes' book,
> Programming in Ada 2005, and picked through the ARM on my problem.
> 
> I have a piece of data which represents a enumeration as a hexadecimal
> value. It is a bit field but I see the data most usefull as an
> enumeration. for example in the CSV file the data is represented as
> '0x1'. So I defined the enum as:
> 
> <code>
>    type Spell_School_Type is (
>       UNKNOWN,
>       PHYSICAL,
>       HOLY,
>       FIRE,
>     ...
> </code>
> 
> And since the data has a value I use a represetation clause as:
> <code>
>    for Spell_School_Type use
>      (UNKNOWN     => 2#0000_0000#,
>       PHYSICAL      => 2#0000_0001#,
>       HOLY             => 2#0000_0010#,
>       FIRE              => 2#0000_0100#,
>     ...
> </code>
> 
> Is the best way to parse the raw info (i.e. 0x1)  into the enumeration
> (i.e PHYSICAL) to use a if/elsif and assign the enum position or is
> there an attribute which works best.

I would use an enumeration representation clause only in very limited 
circumstances: when the input and output is binary (not text), and the 
enumerated type is not used as an array index or case-statement index.

In Harry's case, the input seems to be text (CSV) so I would not use a 
representation clause.

I would use an if/elsif sequence if the number of possible values is 
small (say not more than 5). Otherwise, given an input such as Str(1..3) 
= "0x1",  I would:

- define an integer type, say Code_Type, to represent the hex value,
- check and remove the "0x" prefix: Str(1..2) = "0x"
- enclose the rest in the Ada hex brackets "16#" and "#",
- use the 'Value attribute to get the hex value:
   Code : Code_Type := Code_Type'Value ("16#" & Str(3..Str'Last) & '#');
- define a constant array to map the hex value to the enumeration
value:

  To_Spell_School : constant array (Code_Type) of Spell_School_Type := (
    16#0# => UNKNOWN,
    16#1# => PHYSICAL,
    16#2# => HOLY,
    16#4# => FIRE,
    ..
    others => INVALID_CODE);

where INVALID_CODE is added to Spell_School_Type.

If you use an enumeration representation clause on Spell_School_Type, to 
read textual input you have to get the Code value as above (using 
'Value), then use Unchecked_Conversion from Code_Type to 
Spell_School_Type (taking care that the sizes match), and then check the 
validity of the result using the 'Valid attribute. I prefer the above 
solution, using a mapping array, because it avoids Unchecked_Conversion.

HTH,

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: I need a little help - it's been a long time - with enumeration type  and for use representation
  2009-11-13 16:03 I need a little help - it's been a long time - with enumeration type and for use representation Harry Tucker
  2009-11-13 17:24 ` Niklas Holsti
@ 2009-11-13 17:24 ` Dmitry A. Kazakov
  2009-11-13 18:48   ` Jeffrey R. Carter
  2009-11-13 18:46 ` Jeffrey R. Carter
  2 siblings, 1 reply; 10+ messages in thread
From: Dmitry A. Kazakov @ 2009-11-13 17:24 UTC (permalink / raw)


On Fri, 13 Nov 2009 08:03:23 -0800 (PST), Harry Tucker wrote:

> I have a piece of data which represents a enumeration as a hexadecimal
> value. It is a bit field but I see the data most usefull as an
> enumeration. for example in the CSV file the data is represented as
> '0x1'. So I defined the enum as:
> 
> <code>
>    type Spell_School_Type is (
>       UNKNOWN,
>       PHYSICAL,
>       HOLY,
>       FIRE,
>     ...
> </code>
> 
> And since the data has a value I use a represetation clause as:
> <code>
>    for Spell_School_Type use
>      (UNKNOWN     => 2#0000_0000#,
>       PHYSICAL      => 2#0000_0001#,
>       HOLY             => 2#0000_0010#,
>       FIRE              => 2#0000_0100#,
>     ...
> </code>

For bit fields modular types are better:

   type Spell_School_Type is mod 2**3;
       -- 3 is the number of independent bits
   Unknown  : constant Spell_School_Type := 0;
   Physical : constant Spell_School_Type := 2**0;
   Holy     : constant Spell_School_Type := 2**1;
   Fire     : constant Spell_School_Type := 2**2;
   Any    : constant Spell_School_Type := Spell_School_Type'Last;

> Is the best way to parse the raw info (i.e. 0x1)  into the enumeration
> (i.e PHYSICAL) to use a if/elsif and assign the enum position or is
> there an attribute which works best.

You parse "0x", then you do a hexadecimal number following it, then you
pass that number (x) to:

   Spell_School_Type'Val (x)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: I need a little help - it's been a long time - with enumeration type  and for use representation
  2009-11-13 16:03 I need a little help - it's been a long time - with enumeration type and for use representation Harry Tucker
  2009-11-13 17:24 ` Niklas Holsti
  2009-11-13 17:24 ` Dmitry A. Kazakov
@ 2009-11-13 18:46 ` Jeffrey R. Carter
  2 siblings, 0 replies; 10+ messages in thread
From: Jeffrey R. Carter @ 2009-11-13 18:46 UTC (permalink / raw)


Harry Tucker wrote:
> 
> I have a piece of data which represents a enumeration as a hexadecimal
> value. It is a bit field but I see the data most usefull as an
> enumeration. for example in the CSV file the data is represented as
> '0x1'. So I defined the enum as:

Since your input is text, not binary, a non-default representation doesn't 
really buy you anything. You'll have to parse and interpret the text, as others 
have explained.

-- 
Jeff Carter
"Son of a window-dresser."
Monty Python & the Holy Grail
12



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: I need a little help - it's been a long time - with enumeration type  and for use representation
  2009-11-13 17:24 ` Dmitry A. Kazakov
@ 2009-11-13 18:48   ` Jeffrey R. Carter
  2009-11-13 19:13     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 10+ messages in thread
From: Jeffrey R. Carter @ 2009-11-13 18:48 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> 
> You parse "0x", then you do a hexadecimal number following it, then you
> pass that number (x) to:
> 
>    Spell_School_Type'Val (x)

This doesn't work with a non-default representation. 'Val reverses 'Pos, and 
'Pos gives sequential values starting with zero, regardless of the representation.

-- 
Jeff Carter
"Son of a window-dresser."
Monty Python & the Holy Grail
12



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: I need a little help - it's been a long time - with enumeration type  and for use representation
  2009-11-13 18:48   ` Jeffrey R. Carter
@ 2009-11-13 19:13     ` Dmitry A. Kazakov
  2009-11-13 20:32       ` Jeffrey R. Carter
  0 siblings, 1 reply; 10+ messages in thread
From: Dmitry A. Kazakov @ 2009-11-13 19:13 UTC (permalink / raw)


On Fri, 13 Nov 2009 11:48:12 -0700, Jeffrey R. Carter wrote:

> Dmitry A. Kazakov wrote:
>> 
>> You parse "0x", then you do a hexadecimal number following it, then you
>> pass that number (x) to:
>> 
>>    Spell_School_Type'Val (x)
> 
> This doesn't work with a non-default representation. 'Val reverses 'Pos, and 
> 'Pos gives sequential values starting with zero, regardless of the representation.

But it works with the modular type proposed. An enumeration type was not
meant. For enumeration types one should parse names, rather than arbitrary
bit patterns.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: I need a little help - it's been a long time - with enumeration type  and for use representation
  2009-11-13 19:13     ` Dmitry A. Kazakov
@ 2009-11-13 20:32       ` Jeffrey R. Carter
  2009-11-13 20:53         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 10+ messages in thread
From: Jeffrey R. Carter @ 2009-11-13 20:32 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> On Fri, 13 Nov 2009 11:48:12 -0700, Jeffrey R. Carter wrote:
> 
>> Dmitry A. Kazakov wrote:
>>> You parse "0x", then you do a hexadecimal number following it, then you
>>> pass that number (x) to:
>>>
>>>    Spell_School_Type'Val (x)
>> This doesn't work with a non-default representation. 'Val reverses 'Pos, and 
>> 'Pos gives sequential values starting with zero, regardless of the representation.
> 
> But it works with the modular type proposed. An enumeration type was not
> meant. For enumeration types one should parse names, rather than arbitrary
> bit patterns.

I see. I cannot imagine using 'Val in this case. Since you start with a String 
containing the hexadecimal image of a value, I'd simply do

Numeric_Type_Name'Value ("16#" & Source (Start .. Stop) & '#');

-- 
Jeff Carter
"Son of a window-dresser."
Monty Python & the Holy Grail
12



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: I need a little help - it's been a long time - with enumeration type  and for use representation
  2009-11-13 20:32       ` Jeffrey R. Carter
@ 2009-11-13 20:53         ` Dmitry A. Kazakov
  2009-11-13 21:30           ` Jeffrey R. Carter
  0 siblings, 1 reply; 10+ messages in thread
From: Dmitry A. Kazakov @ 2009-11-13 20:53 UTC (permalink / raw)


On Fri, 13 Nov 2009 13:32:52 -0700, Jeffrey R. Carter wrote:

> Dmitry A. Kazakov wrote:
>> On Fri, 13 Nov 2009 11:48:12 -0700, Jeffrey R. Carter wrote:
>> 
>>> Dmitry A. Kazakov wrote:
>>>> You parse "0x", then you do a hexadecimal number following it, then you
>>>> pass that number (x) to:
>>>>
>>>>    Spell_School_Type'Val (x)
>>> This doesn't work with a non-default representation. 'Val reverses 'Pos, and 
>>> 'Pos gives sequential values starting with zero, regardless of the representation.
>> 
>> But it works with the modular type proposed. An enumeration type was not
>> meant. For enumeration types one should parse names, rather than arbitrary
>> bit patterns.
> 
> I see. I cannot imagine using 'Val in this case. Since you start with a String 
> containing the hexadecimal image of a value, I'd simply do
> 
> Numeric_Type_Name'Value ("16#" & Source (Start .. Stop) & '#');

I do it differently. I have the pattern:

procedure Get (Text : String; Pointer : in out Integer; Value : out Type)

which I consistently deploy everywhere. Get takes a textual representation
of Type from Text at Pointer and advances Pointer to the first position
following it. The result is returned though Value.

However, yes, usually I use a plain type conversion:

   Get (Text, Pointer, Integer (Value));

rather than Type'Val (when I am too lazy to instantiate the generic
packages once again with Type)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: I need a little help - it's been a long time - with enumeration type  and for use representation
  2009-11-13 20:53         ` Dmitry A. Kazakov
@ 2009-11-13 21:30           ` Jeffrey R. Carter
  2009-11-14  9:24             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 10+ messages in thread
From: Jeffrey R. Carter @ 2009-11-13 21:30 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> 
> I do it differently. I have the pattern:
> 
> procedure Get (Text : String; Pointer : in out Integer; Value : out Type)
> 
> which I consistently deploy everywhere. Get takes a textual representation
> of Type from Text at Pointer and advances Pointer to the first position
> following it. The result is returned though Value.
> 
> However, yes, usually I use a plain type conversion:
> 
>    Get (Text, Pointer, Integer (Value));
> 
> rather than Type'Val (when I am too lazy to instantiate the generic
> packages once again with Type)

I still don't see where you would use 'Val.

-- 
Jeff Carter
"Son of a window-dresser."
Monty Python & the Holy Grail
12



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: I need a little help - it's been a long time - with enumeration type  and for use representation
  2009-11-13 21:30           ` Jeffrey R. Carter
@ 2009-11-14  9:24             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 10+ messages in thread
From: Dmitry A. Kazakov @ 2009-11-14  9:24 UTC (permalink / raw)


On Fri, 13 Nov 2009 14:30:44 -0700, Jeffrey R. Carter wrote:

> Dmitry A. Kazakov wrote:
>> 
>> I do it differently. I have the pattern:
>> 
>> procedure Get (Text : String; Pointer : in out Integer; Value : out Type)
>> 
>> which I consistently deploy everywhere. Get takes a textual representation
>> of Type from Text at Pointer and advances Pointer to the first position
>> following it. The result is returned though Value.
>> 
>> However, yes, usually I use a plain type conversion:
>> 
>>    Get (Text, Pointer, Integer (Value));
>> 
>> rather than Type'Val (when I am too lazy to instantiate the generic
>> packages once again with Type)
> 
> I still don't see where you would use 'Val.

As I said in place of type conversion. If you have some bit pattern as a
number you can use either Val or type conversion:

   declare
      N : Integer;
   begin
      Get (Text, Pointer, N);
      Value := Type'Val (N);   --- or Value := Type (N)
      ...

Type'Val is probably semantically cleaner than conversion. Then there are
cases where conversion cannot be used, e.g. for formal discrete types in
generics. There you have to use 'Val instead of conversion, 'Suc instead of
+1 etc.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-11-14  9:24 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-13 16:03 I need a little help - it's been a long time - with enumeration type and for use representation Harry Tucker
2009-11-13 17:24 ` Niklas Holsti
2009-11-13 17:24 ` Dmitry A. Kazakov
2009-11-13 18:48   ` Jeffrey R. Carter
2009-11-13 19:13     ` Dmitry A. Kazakov
2009-11-13 20:32       ` Jeffrey R. Carter
2009-11-13 20:53         ` Dmitry A. Kazakov
2009-11-13 21:30           ` Jeffrey R. Carter
2009-11-14  9:24             ` Dmitry A. Kazakov
2009-11-13 18:46 ` Jeffrey R. Carter

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