Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ada subtype equivalent in C++

Does C++ offer something similar to Ada's subtype to narrow a type?

E.g.:

type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
subtype Working_Day is Weekday range Monday .. Friday;
like image 957
sornbro Avatar asked May 09 '19 21:05

sornbro


People also ask

What is a subtype in Ada?

A subtype is a type together with a constraint; a value is said to belong to a subtype of a given type if it belongs to the type and satisfies the constraint; the given type is called the base type of the subtype.

Is Ada strongly typed language?

Ada is a strongly typed language.

What are the types of Ada?

The principal scalar types predefined by Ada are Integer , Float , Boolean , and Character . These correspond to int , float , bool / boolean , and char , respectively.

What is natural in Ada?

The POSITIVE type includes all integers greater than or equal to 1, and the NATURAL type includes all integers greater than or equal to 0. Both of these are available with your Ada compiler, and both are subtypes of INTEGER, so all variables of these three types can be freely mixed with no type errors.


2 Answers

No, not natively.

What you describe might be best represented as a scoped enum, accompanied by a separate scoped enum with a subset of enumerations who share numerical representations with the "parent" scoped enum.

You could further define some conversions between the two, but without reflection it's not really possible to make it all elegant and intuitive, at least not without hardcoding and duplicating loads of stuff which rather defeats the purpose.

It would be best, when programming C++, to attempt entirely abandoning the mindset imbued by programming in other languages.

That being said, this is actually quite a nice feature idea, though I wouldn't hold my breath!

Workaround: just use an enum, and apply range checking where you need to.

like image 100
Lightness Races in Orbit Avatar answered Oct 13 '22 23:10

Lightness Races in Orbit


There are a few additional differences between C++ enumerations and Ada enumerations. The following Ada code demonstrates some of these differences.

with Ada.Text_IO; use Ada.Text_IO;

procedure Subtype_Example is
   type Days is (Monday, Tueday, Wednesday, Thursday, Friday, Saturday, Sunday);
   subtype Work_Days is Days range Monday..Friday;

begin
   Put_Line("Days of the week:");
   for D in Days'Range loop
      Put_Line(D'Image);
   end loop;
   New_Line;
   Put_Line("Days with classification:");
   for D in Days'Range loop
      Put(D'Image & " is a member of");
      if D in Work_Days then
         Put_Line(" Work_Days");
      else
         Put_Line(" a non-work day");
      end if;
   end loop;

end Subtype_Example;

The output of this program is:

Days of the week:
MONDAY
TUEDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

Days with classification:
MONDAY is a member of Work_Days
TUEDAY is a member of Work_Days
WEDNESDAY is a member of Work_Days
THURSDAY is a member of Work_Days
FRIDAY is a member of Work_Days
SATURDAY is a member of a non-work day
SUNDAY is a member of a non-work day

The subtype Work_Days has an is-a relationship with the type Days. Every member of Work_Days is also a member of Days. In this example the set of valid values for Work_Days is a subset of the set of valid values for Days.

Characters in Ada are defined as an enumeration. It is therefore simple to define subtypes of the type Character for special uses. The following example reads text from a file and counts the number of occurrences of upper case letters and lower case letters, ignoring all other characters in the file.

with Ada.Text_IO; use Ada.Text_IO;

procedure Count_Letters is
   subtype Upper_Case is Character range 'A'..'Z';
   subtype Lower_Case is Character range 'a'..'z';

   Uppers : array(Upper_Case) of Natural;
   Lowers : array(Lower_Case) of Natural;

   File_Name : String(1..1024);
   File_Id   : File_Type;
   Length    : Natural;
   Line      : String(1..100);
begin
   -- set the count arrays to zero
   Uppers := (Others => 0);
   Lowers := (Others => 0);

   Put("Enter the name of the file to read: ");
   Get_Line(Item => File_Name,
            Last => Length);

   -- Open the named file
   Open(File => File_Id,
        Mode => In_File,
        Name => File_Name(1..Length));

   -- Read the file one line at a time
   while not End_Of_File(File_Id) loop
      Get_Line(File => File_Id,
               Item => Line,
               Last => Length);
      -- Count the letters in the line
      for I in 1..Length loop
         if Line(I) in Upper_Case then
            Uppers(Line(I)) := Uppers(Line(I)) + 1;
         elsif Line(I) in Lower_Case then
            Lowers(Line(I)) := Lowers(Line(I)) + 1;
         end if;
      end loop;
   end loop;
   Close(File_Id);

   -- Print the counts of upper case letters
   for Letter in Uppers'Range loop
      Put_Line(Letter'Image & " =>" & Natural'Image(Uppers(Letter)));
   end loop;

   -- print the counts of lower case letters
   for Letter in Lowers'Range loop
      Put_Line(Letter'Image & " =>" & Natural'Image(Lowers(Letter)));
   end loop;
end Count_Letters;

Two subtypes of Character are defined. The subtype Upper_Case contains the range of Character values from 'A' through 'Z', while the subtype Lower_Case contains the range of Character values from 'a' through 'z'.

Two arrays are created for counting the letters read. The array Uppers is indexed by the set of Upper_Case values. Each element of the array is an instance of Natural, which is a pre-defined subtype of Integer containing only non-negative values. The array Lowers is indexed by the set of Lower_Case values. Each element of Lowers is also an instance of Natural.

The program prompts for a file name, opens that file, then reads the file one line at a time. The characters in each line are parsed. If the character is an Upper_Case character the array element in Uppers indexed by the parsed letter is incremented. If the character is a Lower_Case character the array element in Lowers indexed by the parsed letter is incremented.

The following output is the result of reading the source file for the count_letters program.

Enter the name of the file to read: count_letters.adb
'A' => 3
'B' => 0
'C' => 12
'D' => 0
'E' => 2
'F' => 13
'G' => 2
'H' => 0
'I' => 21
'J' => 0
'K' => 0
'L' => 36
'M' => 1
'N' => 9
'O' => 7
'P' => 4
'Q' => 0
'R' => 3
'S' => 2
'T' => 3
'U' => 9
'V' => 0
'W' => 0
'X' => 0
'Y' => 0
'Z' => 1
'a' => 51
'b' => 3
'c' => 8
'd' => 19
'e' => 146
'f' => 15
'g' => 16
'h' => 22
'i' => 50
'j' => 0
'k' => 0
'l' => 38
'm' => 13
'n' => 57
'o' => 48
'p' => 35
'q' => 0
'r' => 62
's' => 41
't' => 78
'u' => 19
'v' => 0
'w' => 12
'x' => 2
'y' => 6
'z' => 2
like image 22
Jim Rogers Avatar answered Oct 13 '22 23:10

Jim Rogers