[Ada] Uintp: add a new UI_From_Integral generic constructor

2018-12-11  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

	* uintp.ads, uintp.adb (UI_From_Integral): New generic function,
	to simplify construction of Universal_Integer representations
	from any Integer type. If type is small enough the code is
	equivalent to a call to UI_To_Int with appropriate conversions;
	otherwise the routine uses the existing mechanism of building a
	vector of suitable integer values and calling Vector_To_Uint.
	The routine must not be applied to a biased type.

From-SVN: r267000
This commit is contained in:
Ed Schonberg 2018-12-11 11:11:06 +00:00 committed by Pierre-Marie de Rodat
parent 5e36662885
commit 62ebfa5272
3 changed files with 63 additions and 0 deletions

View File

@ -1,3 +1,13 @@
2018-12-11 Ed Schonberg <schonberg@adacore.com>
* uintp.ads, uintp.adb (UI_From_Integral): New generic function,
to simplify construction of Universal_Integer representations
from any Integer type. If type is small enough the code is
equivalent to a call to UI_To_Int with appropriate conversions;
otherwise the routine uses the existing mechanism of building a
vector of suitable integer values and calling Vector_To_Uint.
The routine must not be applied to a biased type.
2018-12-11 Ed Schonberg <schonberg@adacore.com>
* sem_ch3.adb (Build_Itype_Reference): Handle properly an itype

View File

@ -2324,4 +2324,50 @@ package body Uintp is
return Uint_0;
end Vector_To_Uint;
----------------------
-- UI_From_Integral --
----------------------
function UI_From_Integral (Input : In_T) return Uint is
U : Uint;
begin
-- If in range of our normal conversion function, use it so we can
-- use direct access and our cache.
if In_T'Size <= Int'Size
or else Input in In_T (Int'First) .. In_T (Int'Last)
then
return UI_From_Int (Int (Input));
else
-- pragma Warnings (Off);
-- For values of larger magnitude, compute digits into a vector
-- and call Vector_To_Uint.
declare
Max_For_In_T : constant Int := 3 * In_T'Size / Int'Size;
Our_Base : constant In_T := In_T (Base);
Temp_Integer : In_T := Input;
-- Base is defined so that 3 Uint digits is sufficient to hold the
-- largest possible Int value.
V : UI_Vector (1 .. Max_For_In_T);
begin
for J in reverse V'Range loop
V (J) := Int (abs (Temp_Integer rem Our_Base));
Temp_Integer := Temp_Integer / Our_Base;
end loop;
U := Vector_To_Uint (V, Input < 0);
Uints_Min := Uints.Last;
Udigits_Min := Udigits.Last;
return U;
end;
-- pragma Warnings (On);
end if;
end UI_From_Integral;
end Uintp;

View File

@ -248,6 +248,13 @@ package Uintp is
function UI_From_Int (Input : Int) return Uint;
-- Converts Int value to universal integer form
generic
type In_T is range <>;
function UI_From_Integral (Input : In_T) return Uint;
-- Likewise, but converts from any integer type.
-- Must not be applied to biased types (instantiation will provide
-- a warning if actual is a biased type).
function UI_From_CC (Input : Char_Code) return Uint;
-- Converts Char_Code value to universal integer form