Enumerated Types
Introduction to Enumerated Types
Concept
Enumerated Types Create New Literals!
- We have created new literals in the language!
- What is a literal in a language?
- Something that can be represented directly
- Examples: 3 vs 2 + 1, "Hi Mom", true vs not false
Enumerated Types - Questions
- Questions:
- What operations are available
- Case sensitive?
- Can two types mix names
- Can variables and types mix names
- Rules for keeping sets of names distinct
- Motivation and approach of other languages
Operations Available with Enumerated Types
Some Basic Operations
Example (prettified)
-- Illustrates:
-- declaring variables, assignment, relational operators, in, ranges
with Ada.Text_io; use Ada.Text_io;
procedure enum1 is
type Day is (Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday);
today: Day;
begin
today := Thursday;
if today = Friday then
put("We made it!");
end if;
for d in Sunday .. Saturday loop
if d in Monday .. Friday then
put("It's a work day.");
if < Wednesday then
put("Just started the week!.");
end if;
else
put("It's the weekend!");
end if;
end loop;
end enum1;
I/O of Enumerated Types
type Color is (Red, Blue, Green);
c: color := red;
begin
put(c);
- Which version of
put
would be needed here?
- Since type
Color
is newly created, no put
for
it can already exist
- Instead, we must create a new IO library for type
Color
A new i/o packages must be created for each new type!
with Ada.Text_io; use Ada.Text_IO;
procedure enum2 is
type Color is (Red, Blue, Green);
type Day is (Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday);
-- Declare 2 new I/O packages
package Color_IO is new Ada.Text_IO.Enumeration_IO(Color);
package Day_IO is new Enumeration_IO(Day);
-- Use the new packages
use Color_IO;
use Day_IO;
c: Color;
d: Day;
begin
c := Red;
d := Monday;
put(c);
new_line;
put(d);
end enum2;
SAMPLE RUN:
RED
MONDAY
Advantages of Enumeration_IO
- Operates similar to integer IO:
- Skips white space to find input value (ie enumeration literal)
- Error if can't find valid enumeration literal
Package Enumeration_IO
- Enumeration_IO is known as a generic package
- because it has a type as a parameter
- Java 1.5 introduces parameterized types, which are similar to generic packages
- We will study generic packages in detail later
- Color_IO.Get is also provided by the generic package
- A slightly more complex example
(enum2a.adb)
[and prettified]
that inputs enumerated type values and strings from the file
this data file
- Important: Don't forget that your input file needs to be
created using the same operating system that your program is
compiled for! (For example, don't create your file using PFE on a
PC and then compile using SSH, which creates an executable for a
SPARC.)
More Operations: Attributes of Enumerated Types
- Example 1 and (prettified)
- The usual: Range, First, Last
- Are plus, minus, etc available No, but these are:
- Sequence Functions: Succ, Pred
- Example 2 and (prettified)
- Functions to convert to/from Naturals: Pos, Val
- Functions to convert to/from Strings: Image, Value
- Relops
- Example 3 and (prettified)
Type Checking with Enumerated Types
Enumerated Types are Strongly Typed
- Types that are distinct cannot be mixed!
with Ada.Text_io; use Ada.Text_io;
procedure enum1a is
type Color is (Red, Blue, Green);
type Day is (Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday);
c: Color;
d: Day;
n: Natural := 1;
begin
c := Red;
d := Friday;
c := Friday; -- Compile error
c := d; -- Compile error
c := 1; -- Compile error
d := 1; -- Compile error
n := c; -- Compile error
c := n; -- Compile error
if d = Blue then -- Compile error
put("It's Friday!");
end if;
end enum1a;
Ambiguous Values
- What happens when the sets are not distinct
- Example: with Color Blue and Mood Blue?
- Example and (prettified)
Enumerated Type Values and Variables, etc
Array Indices and Subranges
Enumerated Types as Array Indices
- An enumerated type range can be an array index
type Day is (Sunday, Monday, Tuesday,
Wednesday, Thursday, Friday, Saturday);
type HoursArray is array(Monday .. Saturday) of Float;
hoursWorked: HoursArray := (others => 0.0);
...
for d in Monday .. Friday loop
totalHours := totalHours + hoursWorked(d);
end loop
totalHours := totalHours + 1.5 * (hoursWorked(Saturday));
Subtypes (ie Subranges) of Enumeration
Predefined Enumeration Types
Types Boolean and Character
- Types Boolean and Character are effectively defined as follows:
type Boolean is (True, False);
type Character is (..., 'A', 'B', ..., 'a', 'b', ...);
Yes, Enumeration literals can be characters (but this is not quite as useful
as you might think)
Boolean and Character are said to be defined in package Ada.Standard
- Package Ada.Standard defines what is automatically available
- but
with ada.standard
not allowed
Enumerated Types in Other Languages
Java 1.4 and Earlier (and Sometimes Later)
- Java uses
final static int
for constant values that act as
enumeration values
- This does not provide type checking
- Example: Class Calendar has method
void set(int field, int value)
for setting a specific field in a calendar
myCalendar.set(DAY_OF_WEEK, SUNDAY); // set day of week of myCalendar to 1
myCalendar.set(MONTH, JANUARY ); // set month of myCalendar to 0
For the parameter field
, class Calendar has int
constants
for which field to set and for field values:
class Calendar{
public static final int YEAR=1, MONTH=2, ..., DAY_OF_WEEK=7, ...;
public static final int SUNDAY=1, MONDAY=2, ..., SATURDAY=7;
public static final int JANUARY=0, FEBRUARY=1, ..., DECEMBER=11;
How good is the compile time error checking:
myCalendar.set(MONTH, 1); // January, or February?
myCalendar.set(SUNDAY, DAY_OF_WEEK); // Which is correct?
myCalendar.set(DAY_OF_WEEK, SUNDAY); // Can compiler catch error?
myCalendar.set(MONTH, MONDAY); // Can error even be caught at runtime?
In Java 1.4 and earlier, this was the only way to get enumeration-like
values. Java 1.5 added enums (see below)
C and C++
- C, C++ have same problems described above for Java, plus ...
- C has enums which are really are essentially ints,
thus little to no type checking
typedef
enum {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}
week_days;
week_days today = FRIDAY, tomorrow, dayAfter;
tomorrow = today + 1;
dayAfter = today * 2;
int someInt = tomorrow;
printf("%d %d %d %d\n", today, tomorrow, dayAfter, someInt);
// Output: 5 6 10 6
C++ has enums which give some type checking
-
tomorrow = today + 1;
gives an error, but ...
-
int someInt = tomorrow ;
is allowed
Java 1.5 and Later
- Java 1.5 added enums which are similar to Ada enumerated types
enum WeekDay { Monday, Tuesday, Wednesday, Thursday, Friday }
WeekDay today = Weekday.Monday;
Java enums are implemented using a parameterized class (ie generic)
called Enum
Java enums are objects, not primitive values.
Motivation for Enumerated Types
Motivation
- Write program at level of problem rather than level of machine
- Example: possible to write
if roomcolor == blue
rather than if roomcolor == 3
- Result: code is easier to write and more readable
- Better type checking to catch more errors
roomColor *= 3;
void setDate(int day, int month, int year){...}
...
// How to call setDate for September 8, 2003?
setDate(9, 8, 2003); // Which is correct?
setDate(8, 9, 2003);
// The compiler would not detect the error
- If there were a type for Months, the compiler would flag
one of these as invalid:
setDate(September, 8, 2003);
setDate(8, September, 2003);
A Final Example using Enumerated Types
An Example Using Enumeration Types
- Table5.adb
- Pretty version of Table5.adb
- Purpose: Read desired table bounds and alignment option and then print a table of powers
- Alignment option can be left, center, or right
- Features:
- Define a new Enumerated Type: Alignment
- Enumeration IO
- Global constant: ColumnWidth
- Visible from point of declaration on - thus inside
all procedures
- Global constants are okay