I want to be able to include information about my type in the Predicate_Failure message. Here's what I have that works:
subtype Norm is Float range 0.0..1.0;
type Component is (Red, Green, Blue, Yellow, White);
type Proto_Color is array(Component'Range) of Norm;
function Is_Valid(This : Proto_Color) return Boolean is
Positive_Count : Natural := 0;
Sum : Norm := 0.0;
begin
for I in Component'Range loop
if This(I) > 0.001 then
Positive_Count := Positive_Count + 1;
Sum := Sum + This(I);
end if;
end loop;
if Positive_Count = 0 or Positive_Count > 2 then
return False;
end if;
if This(Red) > 0.001 and then This(Green) > 0.001 then
return False;
end if;
if This(Yellow) > 0.001 and then This(Blue) > 0.001 then
return False;
end if;
return Sum > 0.999 and then Sum < 1.001;
end Is_Valid;
Invalid_Color : exception;
type Color is new Proto_Color with Dynamic_Predicate => Is_Valid(Proto_Color(Color)),
Predicate_Failure => raise Invalid_Color;
Note that the Proto_Color type only exists so I can add that Dynamic_Predicate. I couldn't find a way to declare that Is_Valid function on a type that wasn't complete yet.
What I want to do, because all this tells me is that it failed, is have some more information about the type displayed along with the exception. But I can't get it to accept a function call on the Predicate_Failure:
function To_String(This : Proto_Color) return String is
begin
return "Red => " & Norm'Image(This(Red))
& ", Green => " & Norm'Image(This(Green))
& ", Blue => " & Norm'Image(This(Blue))
& ", Yellow => " & Norm'Image(This(Yellow))
& ", White => " & Norm'Image(This(White));
end To_String;
type Color is new Proto_Color with Dynamic_Predicate => Is_Valid(Proto_Color(Color)),
Predicate_Failure => raise Invalid_Color with To_String(Proto_Color'(Color));
The error I get with this is:
expected type "Proto_Color" defined at line [line number]
found type "Color" defined at line [line number]
Without the tick that makes it a qualified expression, it tells me:
the argument of conversion cannot be aggregate
use a qualified expression instead
Component
instead ofComponent'Range
.