{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE NoImplicitPrelude #-}

{-# OPTIONS_HADDOCK not-home #-}

#include "MachDeps.h"

-- | Compatibility module for pre ghc-bignum code.
module GHC.Integer (
    Integer,

    -- * Construct 'Integer's
    smallInteger, wordToInteger,
#if WORD_SIZE_IN_BITS < 64
    word64ToInteger, int64ToInteger,
#endif
    -- * Conversion to other integral types
    integerToWord, integerToInt,
#if WORD_SIZE_IN_BITS < 64
    integerToWord64, integerToInt64,
#endif

    -- * Helpers for 'RealFloat' type-class operations
    encodeFloatInteger, floatFromInteger,
    encodeDoubleInteger, decodeDoubleInteger, doubleFromInteger,

    -- * Arithmetic operations
    plusInteger, minusInteger, timesInteger, negateInteger,
    absInteger, signumInteger,

    divModInteger, divInteger, modInteger,
    quotRemInteger, quotInteger, remInteger,

    -- * Comparison predicates
    eqInteger,  neqInteger,  leInteger,  gtInteger,  ltInteger,  geInteger,
    compareInteger,

    -- ** 'Int#'-boolean valued versions of comparison predicates
    --
    -- | These operations return @0#@ and @1#@ instead of 'False' and
    -- 'True' respectively.  See
    -- <https://gitlab.haskell.org/ghc/ghc/wikis/prim-bool PrimBool wiki-page>
    -- for more details
    eqInteger#, neqInteger#, leInteger#, gtInteger#, ltInteger#, geInteger#,


    -- * Bit-operations
    andInteger, orInteger, xorInteger,

    complementInteger,
    shiftLInteger, shiftRInteger, testBitInteger,

    popCountInteger, bitInteger,

    -- * Hashing
    hashInteger,
    ) where

import GHC.Num.Integer (Integer)
import qualified GHC.Num.Integer as I
import GHC.Prim
import GHC.Types

smallInteger :: Int# -> Integer
smallInteger :: Int# -> Integer
smallInteger = Int# -> Integer
I.integerFromInt#

integerToInt :: Integer -> Int#
integerToInt :: Integer -> Int#
integerToInt = Integer -> Int#
I.integerToInt#

wordToInteger :: Word# -> Integer
wordToInteger :: Word# -> Integer
wordToInteger = Word# -> Integer
I.integerFromWord#

integerToWord :: Integer -> Word#
integerToWord :: Integer -> Word#
integerToWord = Integer -> Word#
I.integerToWord#

#if WORD_SIZE_IN_BITS < 64

word64ToInteger :: Word64# -> Integer
word64ToInteger = I.integerFromWord64#

integerToWord64 :: Integer -> Word64#
integerToWord64 = I.integerToWord64#

int64ToInteger :: Int64# -> Integer
int64ToInteger = I.integerFromInt64#

integerToInt64 :: Integer -> Int64#
integerToInt64 = I.integerToInt64#

#endif


encodeFloatInteger :: Integer -> Int# -> Float#
encodeFloatInteger :: Integer -> Int# -> Float#
encodeFloatInteger = Integer -> Int# -> Float#
I.integerEncodeFloat#

floatFromInteger :: Integer -> Float#
floatFromInteger :: Integer -> Float#
floatFromInteger = Integer -> Float#
I.integerToFloat#

encodeDoubleInteger :: Integer -> Int# -> Double#
encodeDoubleInteger :: Integer -> Int# -> Double#
encodeDoubleInteger = Integer -> Int# -> Double#
I.integerEncodeDouble#

doubleFromInteger :: Integer -> Double#
doubleFromInteger :: Integer -> Double#
doubleFromInteger = Integer -> Double#
I.integerToDouble#

decodeDoubleInteger :: Double# -> (# Integer, Int# #)
decodeDoubleInteger :: Double# -> (# Integer, Int# #)
decodeDoubleInteger = Double# -> (# Integer, Int# #)
I.integerDecodeDouble#


plusInteger :: Integer -> Integer -> Integer
plusInteger :: Integer -> Integer -> Integer
plusInteger = Integer -> Integer -> Integer
I.integerAdd

minusInteger :: Integer -> Integer -> Integer
minusInteger :: Integer -> Integer -> Integer
minusInteger = Integer -> Integer -> Integer
I.integerSub

timesInteger :: Integer -> Integer -> Integer
timesInteger :: Integer -> Integer -> Integer
timesInteger = Integer -> Integer -> Integer
I.integerMul

negateInteger :: Integer -> Integer
negateInteger :: Integer -> Integer
negateInteger = Integer -> Integer
I.integerNegate

absInteger :: Integer -> Integer
absInteger :: Integer -> Integer
absInteger = Integer -> Integer
I.integerAbs

signumInteger :: Integer -> Integer
signumInteger :: Integer -> Integer
signumInteger = Integer -> Integer
I.integerSignum

divModInteger :: Integer -> Integer -> (# Integer, Integer #)
divModInteger :: Integer -> Integer -> (# Integer, Integer #)
divModInteger = Integer -> Integer -> (# Integer, Integer #)
I.integerDivMod#

divInteger :: Integer -> Integer -> Integer
divInteger :: Integer -> Integer -> Integer
divInteger = Integer -> Integer -> Integer
I.integerDiv

modInteger :: Integer -> Integer -> Integer
modInteger :: Integer -> Integer -> Integer
modInteger = Integer -> Integer -> Integer
I.integerMod

quotRemInteger :: Integer -> Integer -> (# Integer, Integer #)
quotRemInteger :: Integer -> Integer -> (# Integer, Integer #)
quotRemInteger = Integer -> Integer -> (# Integer, Integer #)
I.integerQuotRem#

quotInteger :: Integer -> Integer -> Integer
quotInteger :: Integer -> Integer -> Integer
quotInteger = Integer -> Integer -> Integer
I.integerQuot

remInteger :: Integer -> Integer -> Integer
remInteger :: Integer -> Integer -> Integer
remInteger = Integer -> Integer -> Integer
I.integerRem


eqInteger :: Integer -> Integer -> Bool
eqInteger :: Integer -> Integer -> Bool
eqInteger = Integer -> Integer -> Bool
I.integerEq

neqInteger :: Integer -> Integer -> Bool
neqInteger :: Integer -> Integer -> Bool
neqInteger = Integer -> Integer -> Bool
I.integerNe

leInteger :: Integer -> Integer -> Bool
leInteger :: Integer -> Integer -> Bool
leInteger = Integer -> Integer -> Bool
I.integerLe

gtInteger :: Integer -> Integer -> Bool
gtInteger :: Integer -> Integer -> Bool
gtInteger = Integer -> Integer -> Bool
I.integerGt

ltInteger :: Integer -> Integer -> Bool
ltInteger :: Integer -> Integer -> Bool
ltInteger = Integer -> Integer -> Bool
I.integerLt

geInteger :: Integer -> Integer -> Bool
geInteger :: Integer -> Integer -> Bool
geInteger = Integer -> Integer -> Bool
I.integerGe

compareInteger :: Integer -> Integer -> Ordering
compareInteger :: Integer -> Integer -> Ordering
compareInteger = Integer -> Integer -> Ordering
I.integerCompare



eqInteger# :: Integer -> Integer -> Int#
eqInteger# :: Integer -> Integer -> Int#
eqInteger# = Integer -> Integer -> Int#
I.integerEq#

neqInteger# :: Integer -> Integer -> Int#
neqInteger# :: Integer -> Integer -> Int#
neqInteger# = Integer -> Integer -> Int#
I.integerNe#

leInteger# :: Integer -> Integer -> Int#
leInteger# :: Integer -> Integer -> Int#
leInteger# = Integer -> Integer -> Int#
I.integerLe#

gtInteger# :: Integer -> Integer -> Int#
gtInteger# :: Integer -> Integer -> Int#
gtInteger# = Integer -> Integer -> Int#
I.integerGt#

ltInteger# :: Integer -> Integer -> Int#
ltInteger# :: Integer -> Integer -> Int#
ltInteger# = Integer -> Integer -> Int#
I.integerLt#

geInteger# :: Integer -> Integer -> Int#
geInteger# :: Integer -> Integer -> Int#
geInteger# = Integer -> Integer -> Int#
I.integerGe#


andInteger :: Integer -> Integer -> Integer
andInteger :: Integer -> Integer -> Integer
andInteger = Integer -> Integer -> Integer
I.integerAnd

orInteger :: Integer -> Integer -> Integer
orInteger :: Integer -> Integer -> Integer
orInteger = Integer -> Integer -> Integer
I.integerOr

xorInteger :: Integer -> Integer -> Integer
xorInteger :: Integer -> Integer -> Integer
xorInteger = Integer -> Integer -> Integer
I.integerXor

complementInteger :: Integer -> Integer
complementInteger :: Integer -> Integer
complementInteger = Integer -> Integer
I.integerComplement

shiftLInteger :: Integer -> Int# -> Integer
shiftLInteger :: Integer -> Int# -> Integer
shiftLInteger Integer
n Int#
i = Integer -> Word# -> Integer
I.integerShiftL# Integer
n (Int# -> Word#
int2Word# Int#
i)

shiftRInteger :: Integer -> Int# -> Integer
shiftRInteger :: Integer -> Int# -> Integer
shiftRInteger Integer
n Int#
i = Integer -> Word# -> Integer
I.integerShiftR# Integer
n (Int# -> Word#
int2Word# Int#
i)

testBitInteger :: Integer -> Int# -> Bool
testBitInteger :: Integer -> Int# -> Bool
testBitInteger Integer
n Int#
i = Int# -> Bool
isTrue# (Integer -> Word# -> Int#
I.integerTestBit# Integer
n (Int# -> Word#
int2Word# Int#
i))

hashInteger :: Integer -> Int#
hashInteger :: Integer -> Int#
hashInteger = Integer -> Int#
I.integerToInt#

bitInteger :: Int# -> Integer
bitInteger :: Int# -> Integer
bitInteger Int#
i = Word# -> Integer
I.integerBit# (Int# -> Word#
int2Word# Int#
i)

popCountInteger :: Integer -> Int#
popCountInteger :: Integer -> Int#
popCountInteger = Integer -> Int#
I.integerPopCount#