[comp.lang.pascal] Enumerated types in TP40

pilgrimk@lafcol.UUCP (Guru Jee) (01/03/89)

How can the number of elements in an enumerated type be determined?

 e.g. type
          Enum1 = (One, Two, Three, Four);
          Enum2 = (_One, _Two, _Three);

I would like to get a value of 4 for the no. of elements in any 
variable declared as "Enum1" and 3 for those declared as "Enum2". Is
this possible?

dmurdoch@watdcsu.waterloo.edu (D.J. Murdoch - Statistics) (01/04/89)

In article <363@lafcol.UUCP> pilgrimk@lafcol.UUCP (Guru Jee) writes:
>How can the number of elements in an enumerated type be determined?
>
> e.g. type
>          Enum1 = (One, Two, Three, Four);
>          Enum2 = (_One, _Two, _Three);
>
>I would like to get a value of 4 for the no. of elements in any 
>variable declared as "Enum1" and 3 for those declared as "Enum2". Is
>this possible?

Not easily - TP doesn't give any min and max functions that work on variables,
let alone types.  However, if you are really desperate, it can be done, sort
of.  If you enable range checking, then assigning a byte with value 4 to a
variable of type Enum1 will cause an error.  So, one way to count an enumerated
type is to see how far you get in assigning values starting with 0 to it.
 
There's a faster but even worse way to do it, however.  The way range checking
works in TP4 (I'm not sure about any other version) is to store the upper and 
lower limits as longints somewhere in the code segment, and pass the address
of these limits, along with the value to be checked, to a little subroutine
in the system unit.  I once wrote an inline routine that could look back through
the code until it found the pointer to the limits, and returned that.   Then
you could find out (and even change) the limits that the range checker was 
using.  I was applying this to checking the limits on the subscripts of an
array, but I imagine the same idea would work to find the limits on any type.

After I wrote it, I couldn't find any situation where I was desperate enough
to want to use it, and I've lost it now.

Duncan Murdoch

david@ms.uky.edu (David Herron -- One of the vertebrae) (01/07/89)

In article <363@lafcol.UUCP> pilgrimk@lafcol.UUCP (Guru Jee) writes:
>How can the number of elements in an enumerated type be determined?
>
> e.g. type
>          Enum1 = (One, Two, Three, Four);
>          Enum2 = (_One, _Two, _Three);

If you must do this at runtime, then something like 

var
    DummyArr = array[Enum1] of byte

...

HowManyEnums = sizeof(DummyArr);

ought to work.  Another method which requires some attention if you change
the declaration of Enum1 would be:

const
     Enum1Max:Enum1 = Four;

...

HowManyEnums = ord(Enum1Max) + 1;

The best solution would be simply to define a constant with the value
you want:

const
     HowManyEnums = 4;

TP 5.0 allows expressions to define constants so something like

const
     Enum1Max:Enum1 = Four;
     HowManyEnums:byte = succ(ord(Enum1Max));

Would also work (though this solution and its runtime counterpart above
depend on how TP implements enumerated types, and may break in the future).
There may be an even better solution available under 5.0 (I don't have
it, myself).

Kenneth Herron
-- 
<-- David Herron; an MMDF guy                              <david@ms.uky.edu>
<-- ska: David le casse\*'      {rutgers,uunet}!ukma!david, david@UKMA.BITNET
<-- Now I know how Zonker felt when he graduated ...
<--          Stop!  Wait!  I didn't mean to!

d87-jse@nada.kth.se (Joakim Sernbrant) (01/11/89)

In article <363@lafcol.UUCP> pilgrimk@lafcol.UUCP (Guru Jee) writes:
>How can the number of elements in an enumerated type be determined?
>
> e.g. type
>          Enum1 = (One, Two, Three, Four);
>          Enum2 = (_One, _Two, _Three);
>
>I would like to get a value of 4 for the no. of elements in any 
>variable declared as "Enum1" and 3 for those declared as "Enum2". Is
>this possible?

I believe something like sizeof(Enum1) div sizeof(Enum1(ord(One))) will do the
trick, but I'm unable to test this right now...
-- 
--  Joakim Sernbrant, Royal Institute of Technology, Stockholm, Sweden
--  Internet:  d87-jse@nada.kth.se
--

mark@hpcllmr.HP.COM (Mark Rozhin) (02/04/89)

>I believe something like sizeof(Enum1) div sizeof(Enum1(ord(One))) will do the
>trick, but I'm unable to test this right now...

what does sizeof( <constant> ) mean? consider the following:

   const
      a = 1;
   var
      w : packed record
	     x : 0..1;
	     y : 0..1;
	     z : integer;
	     end;
   being
      w.x := a;
      w.z := a;
   end

somehow, i can only make sense of the size of a constant where the
constant is a structure. any thoughts?

mr

milne@ics.uci.edu (Alastair Milne) (02/11/89)

In article <950016@hpcllmr.HP.COM> mark@hpcllmr.HP.COM (Mark Rozhin) writes:
>>I believe something like sizeof(Enum1) div sizeof(Enum1(ord(One))) will do the
>>trick, but I'm unable to test this right now...
>
>what does sizeof( <constant> ) mean? 

    The same as "sizeof(anything-else)": the amount of memory, typically in
    bytes, required to store that value; or if the argument is a type, then
    the amount needed for a value of that type.

    I'm not quite following the proposed use of "sizeof" here.  On the one
    hand, it looks as if it's being used to measure the ordinality (right
    term?) of an enumeration -- which it won't do.  And the expression 
    "sizeof(Enum1) div sizeof(Enum1(ord(One)))" looks as if it should yield
    one, since the arguments being passed to "sizeof" are equivalent.

    I have yet to encounter a way dynamically to determine the number of
    values in an enumeration, short of having a dialect which provides a 
    MAX function.  A fix that's not too hard to use is to have a constant
    "lastValue" declared as the final value in the enumeration.  Besides
    providing an upper limit for scans, its ordinal is the number of values in
    the type, less 1.  Of course, this takes advantage of TP4/5's relaxed
    ordering and counting of CONST, TYPE, and VAR sections.

    If anybody has a better way, I'd be interested to hear.


    Alastair Milne

abcscnuk@csuna.UUCP (Naoto Kimura) (02/13/89)

In article <7250@paris.ics.uci.edu> Alastair Milne <milne%ics.uci.edu@orion.cf.uci.edu> writes:
> ... (text deleted) ...
>    I have yet to encounter a way dynamically to determine the number of
>    values in an enumeration, short of having a dialect which provides a 
>    MAX function.

PASCAL/VS has functions (really more like a inline macro like sizeof)
that returns the maximum and minimum values of a type.  They were called
something like LoValue() and HiValue().  Another thing that it had a
method by which you can get the upper and lower bounds of an array.

> ... (text deleted) ...
>    Alastair Milne

                //-n-\\				Naoto Kimura
        _____---=======---_____			(csun!csuna!abcscnuk)
    ====____\   /.. ..\   /____====
  //         ---\__O__/---         \\	Enterprise... Surrender or we'll
  \_\                             /_/	send back your *&^$% tribbles !!

scl@virginia.acc.virginia.edu (Steve Losen) (02/15/89)

>In article <7250@paris.ics.uci.edu> Alastair Milne <milne%ics.uci.edu@orion.cf.uci.edu> writes:
> ... (text deleted) ...
>    I have yet to encounter a way dynamically to determine the number of
>    values in an enumeration, short of having a dialect which provides a 
>    MAX function.


Here is a way to do what you want using perfectly legal ISO Standard Pascal
(but I'm not saying it's pretty)

program prog(output);
type
	enum = (rocky, bullwinckle, boris, natasha, fearless);
var
	junk : array[enum] of integer;
	i : enum;

function maxenum(var array[low..high : enum] of integer) : enum;
begin
	maxenum := high;
end;

function minenum(var array[low..high : enum] of integer) : enum;
begin
	minenum := low;
end;

begin
	for i := minenum(junk) to maxenum(junk) do
		writeln('nothing up my sleeve');
end.
-- 
Steve Losen     scl@virginia.edu
University of Virginia Academic Computing Center