--------------------------------
-- Ivan Levashew aka OCTAGRAM --
--         Barnaul, 2009-2010 --
--------------------------------

-- Turbo_Private.Bits, 64bit version

with System, Interfaces, System.Storage_Elements;

package Turbo_Private.Bits is
   pragma Preelaborate;
   pragma Assert (System.Address'Size = 64, "Platform isn't 64bit, BITS must be readjusted");

   type Integer_Addr  is new Interfaces.Integer_64;
   type Unsigned_Addr is new Interfaces.Unsigned_64;

   function "+" (Item : Integer_Addr) return System.Storage_Elements.Storage_Offset;
   function "+" (Item : System.Storage_Elements.Storage_Offset) return Integer_Addr;

   -- 64bit systems can address very large memory space. No need to use
   -- Integer_128 (given that it's not available)

   -- !!! Caution: offsets only
   subtype Integer_Mem is Interfaces.Integer_64;
   subtype Natural_Mem is Integer_Mem range 0 .. Integer_Mem'Last;
   subtype Positive_Mem is Integer_Mem range 1 .. Integer_Mem'Last;

   function "+" (Item : Unsigned_Addr) return System.Address;
   function "+" (Item : System.Address) return Unsigned_Addr;

   function "+" (Item : Unsigned_Addr) return System.Storage_Elements.Integer_Address;
   function "+" (Item : System.Storage_Elements.Integer_Address) return Unsigned_Addr;

   function "+" (Item : System.Address) return System.Storage_Elements.Integer_Address
      renames System.Storage_Elements.To_Integer;
   function "+" (Item : System.Storage_Elements.Integer_Address) return System.Address
      renames System.Storage_Elements.To_Address;

   function "+" (Left : System.Address; Right : Integer_Addr)
     return System.Address;
   function "+" (Left : Integer_Addr; Right : System.Address)
     return System.Address;
   function "-" (Left : System.Address; Right : Integer_Addr)
     return System.Address;
   function "-" (Left, Right : System.Address)
     return Integer_Addr;
   function "mod" (Left : System.Address; Right : Integer_Addr)
     return Integer_Addr;

   pragma Inline ("+", "-", "mod");

end Turbo_Private.Bits;
