Reputation:
if I have a record type like this:
type ABC is record
A : Integer;
B : Integer;
end record;
How could I create a subtype of ABC with two Integer types whose range are specified?
Upvotes: 0
Views: 1274
Reputation: 4198
In Ada 2012
we now have Dynamic_Predicate
with which we can impose subtyping restrictions, as follows:
type ABC is record
A : Integer;
B : Integer;
end record;
subtype XYZ is ABC
with dynamic_predicate =>
((XYZ.A in Positive) and
(XYZ.B not in Positive)) or else raise Constraint_Error;
Upvotes: 3
Reputation: 4198
Given:
type ABC is record
A : Integer;
B : Integer;
end record;
You could use:
type XYZ is record
A : Positive; -- A is subtype of ABC.A
B : Natural; -- B is subtype of ABC.B
end record;
function convert(Input: ABC) return XYZ is
begin
return Result : XYZ:= ( A => Input.A, B => Input.B );
-- Put your exception handling here.
end convert;
Upvotes: 0
Reputation: 1804
You could use a generic too, like this:
generic
type Number is range <>;
package Int_Record is
type ABC is record
A, B : Number;
end record;
end Int_Record;
If you want different ranges for A and B, you'd have to use two generic parameters.
Usage would be like this:
procedure Foo is
subtype My_Int is Integer range 1 .. 3;
package My_Int_Record is new Int_Record (Number => My_Int);
X : My_Int_Record.ABC;
begin
X.A := 2; -- okay
X.B := 4; -- error!
end Foo;
Upvotes: 0
Reputation: 8522
While not answering your question per se (as NWS says, you can't do that), if instead of A and B being integers, they were to be arrays, you can do the following:
package Record_Subtypes is
type Int_Data is array (Integer range <>) of Integer;
type ABC (X_Min, X_Max, Y_Min, Y_Max : Integer) is record
A : Int_Data (X_Min .. X_Max);
B : Int_Data (Y_Min .. Y_Max);
end record;
subtype ABC_4_4 is ABC(X_Min => 1, X_Max => 4,
Y_Min => 1, Y_Max => 4);
subtype ABC_1_7_3_12 is ABC (X_Min => 1, X_Max => 7,
Y_Min => 3, Y_Max => 12);
end Record_Subtypes;
The A and B record fields then utilize the index subtype as provided by the record discriminants.
This is a nice trick I've used from time to time, useful when reading in variable length strings from an interface (such as a socket) where the number of bytes to read is supplied via fixed-sized header; or in the case of a variant record with an enumeration discriminant, I can subtype the record to a specific variant.
Upvotes: 3