4.4 Subtypes

[ Table of Contents ] Prev ] Chapter Overview ] Next ] [ Glossary/Index ]

A subtype specifies a subset of values of a previously declared type, typically having a smaller range of values. We have already seen two built-in subtypes of Integer, called Natural (integers starting at zero) and Positive (integers starting at one).

Subtype declarations are useful for two reasons. They cause the compiler to insert run-time checks for out-of-range conditions, and they can make programs easier to read. Consider the following declarations.

Type
type Apple_Type is range 0..100;
Type
type Orange_Type is range 0..100;
Subtype
subtype Apple_Subtype is Apple_Type range 0..20;
Object
Apples : Apple_Type;
Object
Oranges: Orange_Type;
Objects
A1, A2, A3 : Apple_Subtype;


We could not intermix Apples and Oranges. That is, we could not compare them, add them, assign the value of one to the other, etc. -- the compiler would reject the program. (We could, of course, mix them after performing explicit type conversions.) But we could assign Apples to the sum of A1, A2 and A3, because all are legal values of the base subtype, Apple_Type. Note that there are attributes, Base and Range, such that S'Base and S'Range provide the base type and range of a subtype named S.

Example Program Illustrating Subtypes

This example is adapted from a similar example from Chapter 2 of [Ben-Ari98]. It involves subtypes of an enumeration type.

Im4-5.gif (4636 bytes)

The Cars_And_Countries package depends upon Ada.Text_IO. It exports two enumeration types and two operations (a function and a procedure).

The body of the package declares a series of subtypes of Cars. These are used to advantage in the implementation of the Car_To_Country function.

Note that when we apply the Image attribute to an enumeration type value, the results are always displayed in upper case (based on an arbitrary decision that had to be made by the language designers).

Source Code Listing

----------------------------------------------------------
------------------- Cars_And_Countries -------------------
--  This package provides two capabilities to clients. It 
--  supplies the name of a country of manufacture given a 
--  make of car, and it displays car/country pairs. 
----------------------------------------------------------

package Cars_And_Countries is
    
  type Countries is (US, UK, France, Germany, Japan, Korea);
  
  type Cars is (Ford, Chevrolet, Pontiac, Chrysler, Dodge,
                Rover, Rolls_Royce, 
                Peugeot, Renault, Citroen, 
                BMW, Volkswagen, Opel, 
                Honda, Mitsubishi, Toyota, 
                Daewoo, Hyundai);
                
  function Car_To_Country(C : Cars) return Countries;
  
  procedure Display_Pair(Car : in Cars);
  
end Cars_And_Countries;
---------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
package body Cars_And_Countries is
  -- subtype declarations
  subtype US_Car       is Cars range Ford..Dodge;
  subtype UK_Car       is Cars range Rover..Rolls_Royce;
  subtype French_Car   is Cars range Peugeot..Citroen;
  subtype German_Car   is Cars range BMW..Opel;
  subtype Japanese_Car is Cars range Honda..Toyota;
  subtype Korean_Car   is Cars range Daewoo..Hyundai;
  -------------------------------------------------------  
  function Car_To_Country(C : Cars) return Countries is
  begin
    case C is
      when US_Car       => return US;
      when UK_Car       => return UK;
      when French_Car   => return France;
      when German_Car   => return Germany;
      when Japanese_Car => return Japan;
      when Korean_Car   => return Korea;
    end case;  
  end Car_To_Country;
  ------------------------------------------
  procedure Display_Pair(Car : in Cars) is
    Country : Countries;
  begin
    Country := Car_To_Country(Car);
    Put_Line(Cars'Image(Car) & " is made in " 
             & Countries'Image(Country));  
  end Display_Pair;
  ------------------------------------------
end Cars_And_Countries;
----------------------------------------------------------
------------------------- Test_Cars ----------------------
--  This test procedure calls the Display_Pair procedure 
--  with several values of Car, in order to display where 
--  each is made.  
----------------------------------------------------------
with Cars_And_Countries;
use  Cars_And_Countries;
procedure Test_Cars is
  Car : Cars;
begin
  Car := Rover;   Display_Pair(Car);
  Car := Hyundai; Display_Pair(Car);
  Car := Peugeot; Display_Pair(Car);   
end Test_Cars;
----------------------------------------------------------

The above program produces the following output:

     ROVER is made in UK
     HYUNDAI is made in KOREA
     PEUGEOT is made in FRANCE

Related Topics

4.1 Type System Overview A.2 List of Attributes

[ Back to top of pagePrev ] Next ]