2013-04-27 2 views
0

Допустим, у меня естьКак изменить диапазон диапазона?

function x return boolean is 
      type range0 is range 1..1; 
     begin 
     canse x is 
      when 4=> range0:=firstArray'range; 
      when 5=> range0:=secondArray'range; 
      when 6=> range0:=1..100; 
     end case; 
    end x; 

В основном я хотел бы изменить диапазон range0 на ходу? Как я могу выполнить это без использования блока declare?

+1

Почему очевидный ответ (объявлять блок) исключен? Могло ли преобразование блока объявления в локальную процедуру обмануть? –

ответ

2

В принципе, я хотел бы изменить диапазон range0 на ходу? Как я могу выполнить это без использования блока declare?

Хм ... В Аде 2012 Вы можете использовать If- строчные и выражения, чтобы вы могли иметь что-то вроде этого:

Type Array_Type is Array(Positive Range <>) of Integer; 
Array_1 : Array_Type(1..128); 
Array_2 : Array_Type(33..63); 

-- your variant-selector 
Use_1 : constant Boolean:= True; 

-- Your variant-range here: 
Subtype Variant_Range is Positive Range 
    (if Use_1 then Array_1'First else Array_2'First) 
    ..(if Use_1 then Array_1'Last else Array_2'Last); 

Array_3 : Array_Type(Variant_Range); 

Все, что сказал, это, вероятно, не самый лучший способ пойдите об этом, и использование объявления-блока, скорее всего, будет более легко поддерживаться.

+0

Отлично. :) Я не знал, что у вас могут быть такие выражения в Ada 2012. Спасибо Shark! – 2013-04-28 15:12:48

+0

Возможно, вы захотите также взглянуть на новые выраженные выражения Quantified: http://www.ada-auth.org/standards/12rat/html/Rat12-3-4.html и http://www.adacore.com/ добавления/технические обои/Ada2012_Rationale_Chp2_expressions.pdf – Shark8

0

Еще не объявляют-блок ответа от Ады 2012:

Minimum : Integer := Integer'First; --' SO highlight correction 
Maximum : Integer := Integer'Last; --' *same* 

Function In_Range(X : Integer) return Boolean is 
    (X in range Minimum..Maximum); 

Subtype Variant_Range is Integer Range Integer 
with Dynamic_Predicate => In_Range(Variant_Range); 

ВНИМАНИЕ: Хотя это должна работа, я не проверял.

2

Вы могли бы технически удовлетворить заявленные требования, преобразуя очевидным образом (объявлять блок) в локальную процедуру:

function x return boolean is 

    procedure use_dynamic_range(first,last : in integer) is 
     type range0 is new integer range first .. last; 
    begin 
     null; 
    end use_dynamic_range; 

begin 
    case z is 
     when 4=> use_dynamic_range(firstArray'first, firstArray'last); 
     when 5=> use_dynamic_range(secondArray'first, secondArray'last); 
     when 6=> use_dynamic_range(1,100); 
    end case; 
end x; 

Потому что это локальная процедура она выполняется в том же объеме, эквивалентном блок объявляют, поэтому он может получить доступ ко всему видимому внутри X, поэтому вам не нужно передавать ему огромный список параметров.

1

А что-то вроде:

function x return Boolean is 
    type Range_Info_Type is 
     record 
      First : Integer; 
      Last : Integer; 
     end record; 
    function Get_Range_Info_Type return Range_Info_Type is 
    begin 
     case z is 
      when 4=> return Range_Info_Type'(First => firstArray'First, 
              Last => FirstArray'Last); 
      when 5=> return Range_Info_Type'(First => secondArray'First, 
              Last => secondArray'Last); 
      when 6=> return Range_Info_Type'(First => 1, 
              Last => 100); 
      when others => return Range_Info_Type'(First => 1, 
                Last => 1); 
     end case; 
    end; 
    MyTypeInfo : constant Range_Info_Type := Get_Range_Info_Type; 

    -- Now declare the actual type I want to use. 
    type range0 is new Integer range MyTypeInfo.First .. MyTypeInfo.Last; 

begin 
    return true; 
end x; 

DECLARE блок может быть проще понять, это следует сделать трюк.

Обратите внимание, что вы не можете писать type range0 is range <expr>..<expr> в вашем случае, поскольку expr должен быть статическим выражением (см RM 3.5.4)

Смежные вопросы