Commit 5815f92a by Arnaud Charlet Committed by Pierre-Marie de Rodat

[Ada] Simplify Big_Integer and Big_Real interface

2019-12-18  Arnaud Charlet  <charlet@adacore.com>

gcc/ada/

	* libgnat/a-nbnbin.ads, libgnat/a-nbnbin.adb,
	libgnat/a-nbnbre.ads, libgnat/a-nbnbre.adb: Replace
	Optional_Big_* types by a simple check and exception raise in
	Get_Bignum.
	(Set_Bignum): Arg should be 'out' and not 'in out'.
	(Invalid_Big_Integer, No_Big_Real): Removed.
	(Is_Valid): Now convention Intrinsic.

From-SVN: r279515
parent 16b54914
2019-12-18 Arnaud Charlet <charlet@adacore.com>
* libgnat/a-nbnbin.ads, libgnat/a-nbnbin.adb,
libgnat/a-nbnbre.ads, libgnat/a-nbnbre.adb: Replace
Optional_Big_* types by a simple check and exception raise in
Get_Bignum.
(Set_Bignum): Arg should be 'out' and not 'in out'.
(Invalid_Big_Integer, No_Big_Real): Removed.
(Is_Valid): Now convention Intrinsic.
2019-12-18 Piotr Trojanek <trojanek@adacore.com> 2019-12-18 Piotr Trojanek <trojanek@adacore.com>
* doc/gnat_rm/implementation_defined_pragmas.rst, * doc/gnat_rm/implementation_defined_pragmas.rst,
......
...@@ -44,11 +44,14 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -44,11 +44,14 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
procedure Free is new Ada.Unchecked_Deallocation (Bignum_Data, Bignum); procedure Free is new Ada.Unchecked_Deallocation (Bignum_Data, Bignum);
function Get_Bignum (Arg : Optional_Big_Integer) return Bignum is function Get_Bignum (Arg : Big_Integer) return Bignum is
(To_Bignum (Arg.Value.C)); (if Arg.Value.C = System.Null_Address
-- Return the Bignum value stored in Arg then raise Constraint_Error with "invalid big integer"
else To_Bignum (Arg.Value.C));
procedure Set_Bignum (Arg : in out Optional_Big_Integer; Value : Bignum) -- Check for validity of Arg and return the Bignum value stored in Arg.
-- Raise Constraint_Error if Arg is uninitialized.
procedure Set_Bignum (Arg : out Big_Integer; Value : Bignum)
with Inline; with Inline;
-- Set the Bignum value stored in Arg to Value -- Set the Bignum value stored in Arg to Value
...@@ -56,7 +59,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -56,7 +59,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
-- Set_Bignum -- -- Set_Bignum --
---------------- ----------------
procedure Set_Bignum (Arg : in out Optional_Big_Integer; Value : Bignum) is procedure Set_Bignum (Arg : out Big_Integer; Value : Bignum) is
begin begin
Arg.Value.C := To_Address (Value); Arg.Value.C := To_Address (Value);
end Set_Bignum; end Set_Bignum;
...@@ -65,16 +68,9 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -65,16 +68,9 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
-- Is_Valid -- -- Is_Valid --
-------------- --------------
function Is_Valid (Arg : Optional_Big_Integer) return Boolean is function Is_Valid (Arg : Big_Integer) return Boolean is
(Arg.Value.C /= System.Null_Address); (Arg.Value.C /= System.Null_Address);
--------------------------
-- Invalid_Big_Integer --
--------------------------
function Invalid_Big_Integer return Optional_Big_Integer is
(Value => (Ada.Finalization.Controlled with C => System.Null_Address));
--------- ---------
-- "=" -- -- "=" --
--------- ---------
...@@ -125,7 +121,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -125,7 +121,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
-------------------- --------------------
function To_Big_Integer (Arg : Integer) return Big_Integer is function To_Big_Integer (Arg : Integer) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, To_Bignum (Long_Long_Integer (Arg))); Set_Bignum (Result, To_Bignum (Long_Long_Integer (Arg)));
return Result; return Result;
...@@ -151,7 +147,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -151,7 +147,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
-------------------- --------------------
function To_Big_Integer (Arg : Int) return Big_Integer is function To_Big_Integer (Arg : Int) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, To_Bignum (Long_Long_Integer (Arg))); Set_Bignum (Result, To_Bignum (Long_Long_Integer (Arg)));
return Result; return Result;
...@@ -179,7 +175,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -179,7 +175,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
-------------------- --------------------
function To_Big_Integer (Arg : Int) return Big_Integer is function To_Big_Integer (Arg : Int) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, To_Bignum (Unsigned_64 (Arg))); Set_Bignum (Result, To_Bignum (Unsigned_64 (Arg)));
return Result; return Result;
...@@ -283,7 +279,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -283,7 +279,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
----------------- -----------------
function From_String (Arg : String) return Big_Integer is function From_String (Arg : String) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
-- ??? only support Long_Long_Integer, good enough for now -- ??? only support Long_Long_Integer, good enough for now
Set_Bignum (Result, To_Bignum (Long_Long_Integer'Value (Arg))); Set_Bignum (Result, To_Bignum (Long_Long_Integer'Value (Arg)));
...@@ -306,7 +302,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -306,7 +302,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
--------- ---------
function "+" (L : Big_Integer) return Big_Integer is function "+" (L : Big_Integer) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, new Bignum_Data'(Get_Bignum (L).all)); Set_Bignum (Result, new Bignum_Data'(Get_Bignum (L).all));
return Result; return Result;
...@@ -317,7 +313,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -317,7 +313,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
--------- ---------
function "-" (L : Big_Integer) return Big_Integer is function "-" (L : Big_Integer) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, Big_Neg (Get_Bignum (L))); Set_Bignum (Result, Big_Neg (Get_Bignum (L)));
return Result; return Result;
...@@ -328,7 +324,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -328,7 +324,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
----------- -----------
function "abs" (L : Big_Integer) return Big_Integer is function "abs" (L : Big_Integer) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, Big_Abs (Get_Bignum (L))); Set_Bignum (Result, Big_Abs (Get_Bignum (L)));
return Result; return Result;
...@@ -339,7 +335,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -339,7 +335,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
--------- ---------
function "+" (L, R : Big_Integer) return Big_Integer is function "+" (L, R : Big_Integer) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, Big_Add (Get_Bignum (L), Get_Bignum (R))); Set_Bignum (Result, Big_Add (Get_Bignum (L), Get_Bignum (R)));
return Result; return Result;
...@@ -350,7 +346,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -350,7 +346,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
--------- ---------
function "-" (L, R : Big_Integer) return Big_Integer is function "-" (L, R : Big_Integer) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, Big_Sub (Get_Bignum (L), Get_Bignum (R))); Set_Bignum (Result, Big_Sub (Get_Bignum (L), Get_Bignum (R)));
return Result; return Result;
...@@ -361,7 +357,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -361,7 +357,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
--------- ---------
function "*" (L, R : Big_Integer) return Big_Integer is function "*" (L, R : Big_Integer) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, Big_Mul (Get_Bignum (L), Get_Bignum (R))); Set_Bignum (Result, Big_Mul (Get_Bignum (L), Get_Bignum (R)));
return Result; return Result;
...@@ -372,7 +368,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -372,7 +368,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
--------- ---------
function "/" (L, R : Big_Integer) return Big_Integer is function "/" (L, R : Big_Integer) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, Big_Div (Get_Bignum (L), Get_Bignum (R))); Set_Bignum (Result, Big_Div (Get_Bignum (L), Get_Bignum (R)));
return Result; return Result;
...@@ -383,7 +379,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -383,7 +379,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
----------- -----------
function "mod" (L, R : Big_Integer) return Big_Integer is function "mod" (L, R : Big_Integer) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, Big_Mod (Get_Bignum (L), Get_Bignum (R))); Set_Bignum (Result, Big_Mod (Get_Bignum (L), Get_Bignum (R)));
return Result; return Result;
...@@ -394,7 +390,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -394,7 +390,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
----------- -----------
function "rem" (L, R : Big_Integer) return Big_Integer is function "rem" (L, R : Big_Integer) return Big_Integer is
Result : Optional_Big_Integer; Result : Big_Integer;
begin begin
Set_Bignum (Result, Big_Rem (Get_Bignum (L), Get_Bignum (R))); Set_Bignum (Result, Big_Rem (Get_Bignum (L), Get_Bignum (R)));
return Result; return Result;
...@@ -405,12 +401,23 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is ...@@ -405,12 +401,23 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
---------- ----------
function "**" (L : Big_Integer; R : Natural) return Big_Integer is function "**" (L : Big_Integer; R : Natural) return Big_Integer is
Exp : Bignum := To_Bignum (Long_Long_Integer (R));
Result : Optional_Big_Integer;
begin begin
Set_Bignum (Result, Big_Exp (Get_Bignum (L), Exp)); -- Explicitly check for validity before allocating Exp so that
Free (Exp); -- the call to Get_Bignum below cannot raise an exception before
return Result; -- we get a chance to free Exp.
if not Is_Valid (L) then
raise Constraint_Error with "invalid big integer";
end if;
declare
Exp : Bignum := To_Bignum (Long_Long_Integer (R));
Result : Big_Integer;
begin
Set_Bignum (Result, Big_Exp (Get_Bignum (L), Exp));
Free (Exp);
return Result;
end;
end "**"; end "**";
--------- ---------
......
...@@ -25,19 +25,12 @@ package Ada.Numerics.Big_Numbers.Big_Integers ...@@ -25,19 +25,12 @@ package Ada.Numerics.Big_Numbers.Big_Integers
with Preelaborate with Preelaborate
-- Nonblocking -- Nonblocking
is is
type Optional_Big_Integer is private type Big_Integer is private;
with Default_Initial_Condition => not Is_Valid (Optional_Big_Integer); -- with Integer_Literal => From_String,
-- Integer_Literal => From_String,
-- Put_Image => Put_Image; -- Put_Image => Put_Image;
function Is_Valid (Arg : Optional_Big_Integer) return Boolean; function Is_Valid (Arg : Big_Integer) return Boolean
with Convention => Intrinsic;
subtype Big_Integer is Optional_Big_Integer
with Dynamic_Predicate => Is_Valid (Big_Integer),
Predicate_Failure => (raise Constraint_Error);
function Invalid_Big_Integer return Optional_Big_Integer
with Post => not Is_Valid (Invalid_Big_Integer'Result);
function "=" (L, R : Big_Integer) return Boolean; function "=" (L, R : Big_Integer) return Boolean;
...@@ -51,18 +44,6 @@ is ...@@ -51,18 +44,6 @@ is
function To_Big_Integer (Arg : Integer) return Big_Integer; function To_Big_Integer (Arg : Integer) return Big_Integer;
subtype Optional_Big_Positive is Optional_Big_Integer
with Dynamic_Predicate =>
(not Is_Valid (Optional_Big_Positive))
or else (Optional_Big_Positive > To_Big_Integer (0)),
Predicate_Failure => (raise Constraint_Error);
subtype Optional_Big_Natural is Optional_Big_Integer
with Dynamic_Predicate =>
(not Is_Valid (Optional_Big_Natural))
or else (Optional_Big_Natural >= To_Big_Integer (0)),
Predicate_Failure => (raise Constraint_Error);
subtype Big_Positive is Big_Integer subtype Big_Positive is Big_Integer
with Dynamic_Predicate => Big_Positive > To_Big_Integer (0), with Dynamic_Predicate => Big_Positive > To_Big_Integer (0),
Predicate_Failure => (raise Constraint_Error); Predicate_Failure => (raise Constraint_Error);
...@@ -157,7 +138,7 @@ private ...@@ -157,7 +138,7 @@ private
procedure Adjust (This : in out Controlled_Bignum); procedure Adjust (This : in out Controlled_Bignum);
procedure Finalize (This : in out Controlled_Bignum); procedure Finalize (This : in out Controlled_Bignum);
type Optional_Big_Integer is record type Big_Integer is record
Value : Controlled_Bignum; Value : Controlled_Bignum;
end record; end record;
......
...@@ -45,22 +45,15 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is ...@@ -45,22 +45,15 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
-- Is_Valid -- -- Is_Valid --
-------------- --------------
function Is_Valid (Arg : Optional_Big_Real) return Boolean is function Is_Valid (Arg : Big_Real) return Boolean is
(Is_Valid (Arg.Num) and then Is_Valid (Arg.Den)); (Is_Valid (Arg.Num) and then Is_Valid (Arg.Den));
-----------------
-- No_Big_Real --
-----------------
function No_Big_Real return Optional_Big_Real is
(Num => Invalid_Big_Integer, Den => Invalid_Big_Integer);
--------- ---------
-- "/" -- -- "/" --
--------- ---------
function "/" (Num, Den : Big_Integer) return Big_Real is function "/" (Num, Den : Big_Integer) return Big_Real is
Result : Optional_Big_Real; Result : Big_Real;
begin begin
if Den = To_Big_Integer (0) then if Den = To_Big_Integer (0) then
raise Constraint_Error with "divide by zero"; raise Constraint_Error with "divide by zero";
...@@ -323,7 +316,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is ...@@ -323,7 +316,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
function From_String (Arg : String) return Big_Real is function From_String (Arg : String) return Big_Real is
Ten : constant Big_Integer := To_Big_Integer (10); Ten : constant Big_Integer := To_Big_Integer (10);
Frac : Optional_Big_Integer; Frac : Big_Integer;
Exp : Integer := 0; Exp : Integer := 0;
Pow : Natural := 0; Pow : Natural := 0;
Index : Natural := 0; Index : Natural := 0;
...@@ -353,7 +346,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is ...@@ -353,7 +346,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
end if; end if;
declare declare
Result : Optional_Big_Real; Result : Big_Real;
begin begin
Result.Den := Ten ** Pow; Result.Den := Ten ** Pow;
Result.Num := From_String (Arg (Arg'First .. Index)) * Result.Den; Result.Num := From_String (Arg (Arg'First .. Index)) * Result.Den;
...@@ -414,7 +407,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is ...@@ -414,7 +407,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
--------- ---------
function "+" (L : Big_Real) return Big_Real is function "+" (L : Big_Real) return Big_Real is
Result : Optional_Big_Real; Result : Big_Real;
begin begin
Result.Num := L.Num; Result.Num := L.Num;
Result.Den := L.Den; Result.Den := L.Den;
...@@ -440,7 +433,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is ...@@ -440,7 +433,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
--------- ---------
function "+" (L, R : Big_Real) return Big_Real is function "+" (L, R : Big_Real) return Big_Real is
Result : Optional_Big_Real; Result : Big_Real;
begin begin
Result.Num := L.Num * R.Den + R.Num * L.Den; Result.Num := L.Num * R.Den + R.Num * L.Den;
Result.Den := L.Den * R.Den; Result.Den := L.Den * R.Den;
...@@ -453,7 +446,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is ...@@ -453,7 +446,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
--------- ---------
function "-" (L, R : Big_Real) return Big_Real is function "-" (L, R : Big_Real) return Big_Real is
Result : Optional_Big_Real; Result : Big_Real;
begin begin
Result.Num := L.Num * R.Den - R.Num * L.Den; Result.Num := L.Num * R.Den - R.Num * L.Den;
Result.Den := L.Den * R.Den; Result.Den := L.Den * R.Den;
...@@ -466,7 +459,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is ...@@ -466,7 +459,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
--------- ---------
function "*" (L, R : Big_Real) return Big_Real is function "*" (L, R : Big_Real) return Big_Real is
Result : Optional_Big_Real; Result : Big_Real;
begin begin
Result.Num := L.Num * R.Num; Result.Num := L.Num * R.Num;
Result.Den := L.Den * R.Den; Result.Den := L.Den * R.Den;
...@@ -479,7 +472,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is ...@@ -479,7 +472,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
--------- ---------
function "/" (L, R : Big_Real) return Big_Real is function "/" (L, R : Big_Real) return Big_Real is
Result : Optional_Big_Real; Result : Big_Real;
begin begin
Result.Num := L.Num * R.Den; Result.Num := L.Num * R.Den;
Result.Den := L.Den * R.Num; Result.Den := L.Den * R.Num;
...@@ -492,7 +485,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is ...@@ -492,7 +485,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
---------- ----------
function "**" (L : Big_Real; R : Integer) return Big_Real is function "**" (L : Big_Real; R : Integer) return Big_Real is
Result : Optional_Big_Real; Result : Big_Real;
begin begin
if R = 0 then if R = 0 then
Result.Num := To_Big_Integer (1); Result.Num := To_Big_Integer (1);
......
...@@ -23,19 +23,11 @@ package Ada.Numerics.Big_Numbers.Big_Reals ...@@ -23,19 +23,11 @@ package Ada.Numerics.Big_Numbers.Big_Reals
with Preelaborate with Preelaborate
-- Nonblocking, Global => in out synchronized Big_Reals -- Nonblocking, Global => in out synchronized Big_Reals
is is
type Optional_Big_Real is private with type Big_Real is private;
Default_Initial_Condition => not Is_Valid (Optional_Big_Real); -- with Real_Literal => From_String,
-- Real_Literal => From_String, -- Put_Image => Put_Image;
-- Put_Image => Put_Image;
function Is_Valid (Arg : Optional_Big_Real) return Boolean; function Is_Valid (Arg : Big_Real) return Boolean;
function No_Big_Real return Optional_Big_Real
with Post => not Is_Valid (No_Big_Real'Result);
subtype Big_Real is Optional_Big_Real
with Dynamic_Predicate => Is_Valid (Big_Real),
Predicate_Failure => (raise Constraint_Error);
function "/" (Num, Den : Big_Integers.Big_Integer) return Big_Real; function "/" (Num, Den : Big_Integers.Big_Integer) return Big_Real;
-- with Pre => (if Big_Integers."=" (Den, Big_Integers.To_Big_Integer (0)) -- with Pre => (if Big_Integers."=" (Den, Big_Integers.To_Big_Integer (0))
...@@ -139,8 +131,8 @@ is ...@@ -139,8 +131,8 @@ is
private private
type Optional_Big_Real is record type Big_Real is record
Num, Den : Big_Integers.Optional_Big_Integer; Num, Den : Big_Integers.Big_Integer;
end record; end record;
end Ada.Numerics.Big_Numbers.Big_Reals; end Ada.Numerics.Big_Numbers.Big_Reals;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment