[Ada] Uintp: add a new UI_From_Integral generic constructor
authorEd Schonberg <schonberg@adacore.com>
Tue, 11 Dec 2018 11:11:06 +0000 (11:11 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Tue, 11 Dec 2018 11:11:06 +0000 (11:11 +0000)
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

gcc/ada/ChangeLog
gcc/ada/uintp.adb
gcc/ada/uintp.ads

index 76c6e761e00434ba8150ff619a82272d6277b9b7..c2fef9cbc852d5a7f1257e09f7426e3422e1087a 100644 (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
index 28fe22fdf915cc2a205d8ef4de51c11b3cc789ca..04f552e5d968a0b5bff8a596bdbb4a364adfb6af 100644 (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;
index 5e8321325bc3700fab534f524a5b2b95a43e4de3..d00d0e19f8fc153d412c580bbe28a5984a35a04f 100644 (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