Для такого рода фильтрации значений я бы использовал предикаты подтипа.
В вашем случае изменение вашего перечисления в соответствии с тем, что сказал Кит:
type Integers_Type is (ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN);
subtype Odd_Numbers_Type is Integers_Type
with Static_Predicate => Odd_Numbers_Type in ONE | THREE | FIVE | SEVEN | NINE;
Если вы хотите использовать числовые типы вместо перечисления, используйте следующее
type Integers_Type is range 1 .. 10;
subtype Odd_Numbers_Type is Integers_Type
with Dynamic_Predicate => Odd_Numbers_Type mod 2 /= 0;
Для получения дополнительной информации вы можете прочитать обоснование
РЕДАКТИРОВАТЬ :
Для типов Enumeration следующий код компилируется с использованием gnatmake -gnata -gnatVa test_enum.adb, но выдает предупреждение о строке воздействия 14 и завершается ошибкой при выполнении из-за утверждения, связанного со статическим предикатом.
with Ada.Text_IO; use Ada.Text_IO;
Procedure Test_Enum is
type Integers_Type is (ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN);
subtype Odd_Numbers_Type is Integers_Type
with Static_Predicate => Odd_Numbers_Type in ONE | THREE | FIVE | SEVEN | NINE;
Test_I : Integers_Type := TWO;
Test_O : Odd_Numbers_Type := ONE;
begin
Put_Line("Test_I=" & Integers_Type'Image (Test_I));
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
Test_O := Test_I;
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
end Test_Enum;
Для целочисленных типов с помощью команды компиляции gnatmake -gnata -gnatVa test_int.adb компилятор предупреждает, что проверка завершится ошибкой во время выполнения, что имеет место при срабатывании утверждения.
with Ada.Text_IO; use Ada.Text_IO;
Procedure Test_Int is
type Integers_Type is range 1 .. 10;
subtype Odd_Numbers_Type is Integers_Type
with Dynamic_Predicate => Odd_Numbers_Type mod 2 /= 0;
Test_I : Integers_Type := 2;
Test_O : Odd_Numbers_Type := 1;
begin
Put_Line("Test_I=" & Integers_Type'Image (Test_I));
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
Test_O := Test_I;
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
end Test_Int;
В обоих случаях удаление флага -gnata заставит программу работать, не заботясь о предикате, поскольку утверждения деактивируются.
person
Frédéric Praca
schedule
08.01.2020
Integers_Type
недействительна. Элементы перечисляемого типа должны быть идентификаторами (или символьными литералами), а не числами.type Integers_Type is range 1..10;
будет законным. - person Keith Thompson   schedule 08.01.2020