{-# LANGUAGE DataKinds                  #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables        #-}
{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE TypeOperators              #-}

-- |
-- Module      :  Data.Solidity.Prim.Int
-- Copyright   :  Aleksandr Krupenkin 2016-2021
-- License     :  Apache-2.0
--
-- Maintainer  :  mail@akru.me
-- Stability   :  experimental
-- Portability :  noportable
--
-- Ethereum Abi intN and uintN types.
--

module Data.Solidity.Prim.Int
    (
    -- * The @IntN@ type
      IntN

    -- * The @UIntN@ type
    , UIntN

    -- * @Word256@ serializers
    , getWord256
    , putWord256
    ) where

import qualified Basement.Numerical.Number as Basement (toInteger)
import           Basement.Types.Word256    (Word256 (Word256))
import qualified Basement.Types.Word256    as Basement (quot, rem)
import           Data.Bits                 (Bits (testBit), (.&.))
import           Data.Proxy                (Proxy (..))
import           Data.Serialize            (Get, Putter, Serialize (get, put))
import           GHC.Generics              (Generic)
import           GHC.TypeLits

import           Data.Solidity.Abi         (AbiGet (..), AbiPut (..),
                                            AbiType (..))

instance Real Word256 where
    toRational :: Word256 -> Rational
toRational = Integer -> Rational
forall a. Real a => a -> Rational
toRational (Integer -> Rational)
-> (Word256 -> Integer) -> Word256 -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word256 -> Integer
forall a. Integral a => a -> Integer
toInteger

instance Integral Word256 where
    toInteger :: Word256 -> Integer
toInteger = Word256 -> Integer
forall a. IsIntegral a => a -> Integer
Basement.toInteger
    quotRem :: Word256 -> Word256 -> (Word256, Word256)
quotRem Word256
a Word256
b = (Word256 -> Word256 -> Word256
Basement.quot Word256
a Word256
b, Word256 -> Word256 -> Word256
Basement.rem Word256
a Word256
b)

-- | Unsigned integer with fixed length in bits.
newtype UIntN (n :: Nat) = UIntN { UIntN n -> Word256
unUIntN :: Word256 }
    deriving (UIntN n -> UIntN n -> Bool
(UIntN n -> UIntN n -> Bool)
-> (UIntN n -> UIntN n -> Bool) -> Eq (UIntN n)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (n :: Nat). UIntN n -> UIntN n -> Bool
/= :: UIntN n -> UIntN n -> Bool
$c/= :: forall (n :: Nat). UIntN n -> UIntN n -> Bool
== :: UIntN n -> UIntN n -> Bool
$c== :: forall (n :: Nat). UIntN n -> UIntN n -> Bool
Eq, Eq (UIntN n)
Eq (UIntN n)
-> (UIntN n -> UIntN n -> Ordering)
-> (UIntN n -> UIntN n -> Bool)
-> (UIntN n -> UIntN n -> Bool)
-> (UIntN n -> UIntN n -> Bool)
-> (UIntN n -> UIntN n -> Bool)
-> (UIntN n -> UIntN n -> UIntN n)
-> (UIntN n -> UIntN n -> UIntN n)
-> Ord (UIntN n)
UIntN n -> UIntN n -> Bool
UIntN n -> UIntN n -> Ordering
UIntN n -> UIntN n -> UIntN n
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall (n :: Nat). Eq (UIntN n)
forall (n :: Nat). UIntN n -> UIntN n -> Bool
forall (n :: Nat). UIntN n -> UIntN n -> Ordering
forall (n :: Nat). UIntN n -> UIntN n -> UIntN n
min :: UIntN n -> UIntN n -> UIntN n
$cmin :: forall (n :: Nat). UIntN n -> UIntN n -> UIntN n
max :: UIntN n -> UIntN n -> UIntN n
$cmax :: forall (n :: Nat). UIntN n -> UIntN n -> UIntN n
>= :: UIntN n -> UIntN n -> Bool
$c>= :: forall (n :: Nat). UIntN n -> UIntN n -> Bool
> :: UIntN n -> UIntN n -> Bool
$c> :: forall (n :: Nat). UIntN n -> UIntN n -> Bool
<= :: UIntN n -> UIntN n -> Bool
$c<= :: forall (n :: Nat). UIntN n -> UIntN n -> Bool
< :: UIntN n -> UIntN n -> Bool
$c< :: forall (n :: Nat). UIntN n -> UIntN n -> Bool
compare :: UIntN n -> UIntN n -> Ordering
$ccompare :: forall (n :: Nat). UIntN n -> UIntN n -> Ordering
$cp1Ord :: forall (n :: Nat). Eq (UIntN n)
Ord, Int -> UIntN n
UIntN n -> Int
UIntN n -> [UIntN n]
UIntN n -> UIntN n
UIntN n -> UIntN n -> [UIntN n]
UIntN n -> UIntN n -> UIntN n -> [UIntN n]
(UIntN n -> UIntN n)
-> (UIntN n -> UIntN n)
-> (Int -> UIntN n)
-> (UIntN n -> Int)
-> (UIntN n -> [UIntN n])
-> (UIntN n -> UIntN n -> [UIntN n])
-> (UIntN n -> UIntN n -> [UIntN n])
-> (UIntN n -> UIntN n -> UIntN n -> [UIntN n])
-> Enum (UIntN n)
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
forall (n :: Nat). Int -> UIntN n
forall (n :: Nat). UIntN n -> Int
forall (n :: Nat). UIntN n -> [UIntN n]
forall (n :: Nat). UIntN n -> UIntN n
forall (n :: Nat). UIntN n -> UIntN n -> [UIntN n]
forall (n :: Nat). UIntN n -> UIntN n -> UIntN n -> [UIntN n]
enumFromThenTo :: UIntN n -> UIntN n -> UIntN n -> [UIntN n]
$cenumFromThenTo :: forall (n :: Nat). UIntN n -> UIntN n -> UIntN n -> [UIntN n]
enumFromTo :: UIntN n -> UIntN n -> [UIntN n]
$cenumFromTo :: forall (n :: Nat). UIntN n -> UIntN n -> [UIntN n]
enumFromThen :: UIntN n -> UIntN n -> [UIntN n]
$cenumFromThen :: forall (n :: Nat). UIntN n -> UIntN n -> [UIntN n]
enumFrom :: UIntN n -> [UIntN n]
$cenumFrom :: forall (n :: Nat). UIntN n -> [UIntN n]
fromEnum :: UIntN n -> Int
$cfromEnum :: forall (n :: Nat). UIntN n -> Int
toEnum :: Int -> UIntN n
$ctoEnum :: forall (n :: Nat). Int -> UIntN n
pred :: UIntN n -> UIntN n
$cpred :: forall (n :: Nat). UIntN n -> UIntN n
succ :: UIntN n -> UIntN n
$csucc :: forall (n :: Nat). UIntN n -> UIntN n
Enum, Eq (UIntN n)
UIntN n
Eq (UIntN n)
-> (UIntN n -> UIntN n -> UIntN n)
-> (UIntN n -> UIntN n -> UIntN n)
-> (UIntN n -> UIntN n -> UIntN n)
-> (UIntN n -> UIntN n)
-> (UIntN n -> Int -> UIntN n)
-> (UIntN n -> Int -> UIntN n)
-> UIntN n
-> (Int -> UIntN n)
-> (UIntN n -> Int -> UIntN n)
-> (UIntN n -> Int -> UIntN n)
-> (UIntN n -> Int -> UIntN n)
-> (UIntN n -> Int -> Bool)
-> (UIntN n -> Maybe Int)
-> (UIntN n -> Int)
-> (UIntN n -> Bool)
-> (UIntN n -> Int -> UIntN n)
-> (UIntN n -> Int -> UIntN n)
-> (UIntN n -> Int -> UIntN n)
-> (UIntN n -> Int -> UIntN n)
-> (UIntN n -> Int -> UIntN n)
-> (UIntN n -> Int -> UIntN n)
-> (UIntN n -> Int)
-> Bits (UIntN n)
Int -> UIntN n
UIntN n -> Bool
UIntN n -> Int
UIntN n -> Maybe Int
UIntN n -> UIntN n
UIntN n -> Int -> Bool
UIntN n -> Int -> UIntN n
UIntN n -> UIntN n -> UIntN n
forall a.
Eq a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
forall (n :: Nat). Eq (UIntN n)
forall (n :: Nat). UIntN n
forall (n :: Nat). Int -> UIntN n
forall (n :: Nat). UIntN n -> Bool
forall (n :: Nat). UIntN n -> Int
forall (n :: Nat). UIntN n -> Maybe Int
forall (n :: Nat). UIntN n -> UIntN n
forall (n :: Nat). UIntN n -> Int -> Bool
forall (n :: Nat). UIntN n -> Int -> UIntN n
forall (n :: Nat). UIntN n -> UIntN n -> UIntN n
popCount :: UIntN n -> Int
$cpopCount :: forall (n :: Nat). UIntN n -> Int
rotateR :: UIntN n -> Int -> UIntN n
$crotateR :: forall (n :: Nat). UIntN n -> Int -> UIntN n
rotateL :: UIntN n -> Int -> UIntN n
$crotateL :: forall (n :: Nat). UIntN n -> Int -> UIntN n
unsafeShiftR :: UIntN n -> Int -> UIntN n
$cunsafeShiftR :: forall (n :: Nat). UIntN n -> Int -> UIntN n
shiftR :: UIntN n -> Int -> UIntN n
$cshiftR :: forall (n :: Nat). UIntN n -> Int -> UIntN n
unsafeShiftL :: UIntN n -> Int -> UIntN n
$cunsafeShiftL :: forall (n :: Nat). UIntN n -> Int -> UIntN n
shiftL :: UIntN n -> Int -> UIntN n
$cshiftL :: forall (n :: Nat). UIntN n -> Int -> UIntN n
isSigned :: UIntN n -> Bool
$cisSigned :: forall (n :: Nat). UIntN n -> Bool
bitSize :: UIntN n -> Int
$cbitSize :: forall (n :: Nat). UIntN n -> Int
bitSizeMaybe :: UIntN n -> Maybe Int
$cbitSizeMaybe :: forall (n :: Nat). UIntN n -> Maybe Int
testBit :: UIntN n -> Int -> Bool
$ctestBit :: forall (n :: Nat). UIntN n -> Int -> Bool
complementBit :: UIntN n -> Int -> UIntN n
$ccomplementBit :: forall (n :: Nat). UIntN n -> Int -> UIntN n
clearBit :: UIntN n -> Int -> UIntN n
$cclearBit :: forall (n :: Nat). UIntN n -> Int -> UIntN n
setBit :: UIntN n -> Int -> UIntN n
$csetBit :: forall (n :: Nat). UIntN n -> Int -> UIntN n
bit :: Int -> UIntN n
$cbit :: forall (n :: Nat). Int -> UIntN n
zeroBits :: UIntN n
$czeroBits :: forall (n :: Nat). UIntN n
rotate :: UIntN n -> Int -> UIntN n
$crotate :: forall (n :: Nat). UIntN n -> Int -> UIntN n
shift :: UIntN n -> Int -> UIntN n
$cshift :: forall (n :: Nat). UIntN n -> Int -> UIntN n
complement :: UIntN n -> UIntN n
$ccomplement :: forall (n :: Nat). UIntN n -> UIntN n
xor :: UIntN n -> UIntN n -> UIntN n
$cxor :: forall (n :: Nat). UIntN n -> UIntN n -> UIntN n
.|. :: UIntN n -> UIntN n -> UIntN n
$c.|. :: forall (n :: Nat). UIntN n -> UIntN n -> UIntN n
.&. :: UIntN n -> UIntN n -> UIntN n
$c.&. :: forall (n :: Nat). UIntN n -> UIntN n -> UIntN n
$cp1Bits :: forall (n :: Nat). Eq (UIntN n)
Bits, (forall x. UIntN n -> Rep (UIntN n) x)
-> (forall x. Rep (UIntN n) x -> UIntN n) -> Generic (UIntN n)
forall x. Rep (UIntN n) x -> UIntN n
forall x. UIntN n -> Rep (UIntN n) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (n :: Nat) x. Rep (UIntN n) x -> UIntN n
forall (n :: Nat) x. UIntN n -> Rep (UIntN n) x
$cto :: forall (n :: Nat) x. Rep (UIntN n) x -> UIntN n
$cfrom :: forall (n :: Nat) x. UIntN n -> Rep (UIntN n) x
Generic)

instance (KnownNat n, n <= 256) => Num (UIntN n) where
    UIntN n
a + :: UIntN n -> UIntN n -> UIntN n
+ UIntN n
b  = Integer -> UIntN n
forall a. Num a => Integer -> a
fromInteger (UIntN n -> Integer
forall a. Integral a => a -> Integer
toInteger UIntN n
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ UIntN n -> Integer
forall a. Integral a => a -> Integer
toInteger UIntN n
b)
    UIntN n
a - :: UIntN n -> UIntN n -> UIntN n
- UIntN n
b  = Integer -> UIntN n
forall a. Num a => Integer -> a
fromInteger (UIntN n -> Integer
forall a. Integral a => a -> Integer
toInteger UIntN n
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- UIntN n -> Integer
forall a. Integral a => a -> Integer
toInteger UIntN n
b)
    UIntN n
a * :: UIntN n -> UIntN n -> UIntN n
* UIntN n
b  = Integer -> UIntN n
forall a. Num a => Integer -> a
fromInteger (UIntN n -> Integer
forall a. Integral a => a -> Integer
toInteger UIntN n
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* UIntN n -> Integer
forall a. Integral a => a -> Integer
toInteger UIntN n
b)
    abs :: UIntN n -> UIntN n
abs    = Integer -> UIntN n
forall a. Num a => Integer -> a
fromInteger (Integer -> UIntN n) -> (UIntN n -> Integer) -> UIntN n -> UIntN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Integer
forall a. Num a => a -> a
abs (Integer -> Integer) -> (UIntN n -> Integer) -> UIntN n -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UIntN n -> Integer
forall a. Integral a => a -> Integer
toInteger
    negate :: UIntN n -> UIntN n
negate = Integer -> UIntN n
forall a. Num a => Integer -> a
fromInteger (Integer -> UIntN n) -> (UIntN n -> Integer) -> UIntN n -> UIntN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Integer
forall a. Num a => a -> a
negate (Integer -> Integer) -> (UIntN n -> Integer) -> UIntN n -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UIntN n -> Integer
forall a. Integral a => a -> Integer
toInteger
    signum :: UIntN n -> UIntN n
signum = Integer -> UIntN n
forall a. Num a => Integer -> a
fromInteger (Integer -> UIntN n) -> (UIntN n -> Integer) -> UIntN n -> UIntN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Integer
forall a. Num a => a -> a
signum (Integer -> Integer) -> (UIntN n -> Integer) -> UIntN n -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UIntN n -> Integer
forall a. Integral a => a -> Integer
toInteger
    fromInteger :: Integer -> UIntN n
fromInteger Integer
x
      | Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0 = UIntN n -> UIntN n
mask (UIntN n -> UIntN n) -> UIntN n -> UIntN n
forall a b. (a -> b) -> a -> b
$ Word256 -> UIntN n
forall (n :: Nat). Word256 -> UIntN n
UIntN (Integer -> Word256
forall a. Num a => Integer -> a
fromInteger Integer
x)
      | Bool
otherwise = UIntN n -> UIntN n
mask (UIntN n -> UIntN n) -> UIntN n -> UIntN n
forall a b. (a -> b) -> a -> b
$ Word256 -> UIntN n
forall (n :: Nat). Word256 -> UIntN n
UIntN (Integer -> Word256
forall a. Num a => Integer -> a
fromInteger (Integer -> Word256) -> Integer -> Word256
forall a b. (a -> b) -> a -> b
$ Integer
2 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
256 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
x)
      where
        mask :: UIntN n -> UIntN n
mask = (UIntN n
forall a. Bounded a => a
maxBound UIntN n -> UIntN n -> UIntN n
forall a. Bits a => a -> a -> a
.&.) :: UIntN n -> UIntN n

instance (KnownNat n, n <= 256) => Show (UIntN n) where
    show :: UIntN n -> String
show = Word256 -> String
forall a. Show a => a -> String
show (Word256 -> String) -> (UIntN n -> Word256) -> UIntN n -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UIntN n -> Word256
forall (n :: Nat). UIntN n -> Word256
unUIntN

instance (KnownNat n, n <= 256) => Bounded (UIntN n) where
    minBound :: UIntN n
minBound = Word256 -> UIntN n
forall (n :: Nat). Word256 -> UIntN n
UIntN Word256
0
    maxBound :: UIntN n
maxBound = Word256 -> UIntN n
forall (n :: Nat). Word256 -> UIntN n
UIntN (Word256 -> UIntN n) -> Word256 -> UIntN n
forall a b. (a -> b) -> a -> b
$ Word256
2 Word256 -> Integer -> Word256
forall a b. (Num a, Integral b) => a -> b -> a
^ Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy :: Proxy n) Word256 -> Word256 -> Word256
forall a. Num a => a -> a -> a
- Word256
1

instance (KnownNat n, n <= 256) => Real (UIntN n) where
    toRational :: UIntN n -> Rational
toRational = Integer -> Rational
forall a. Real a => a -> Rational
toRational (Integer -> Rational)
-> (UIntN n -> Integer) -> UIntN n -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UIntN n -> Integer
forall a. Integral a => a -> Integer
toInteger

instance (KnownNat n, n <= 256) => Integral (UIntN n) where
    toInteger :: UIntN n -> Integer
toInteger = Word256 -> Integer
forall a. Integral a => a -> Integer
toInteger (Word256 -> Integer) -> (UIntN n -> Word256) -> UIntN n -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UIntN n -> Word256
forall (n :: Nat). UIntN n -> Word256
unUIntN
    quotRem :: UIntN n -> UIntN n -> (UIntN n, UIntN n)
quotRem (UIntN Word256
a) (UIntN Word256
b) = (Word256 -> UIntN n
forall (n :: Nat). Word256 -> UIntN n
UIntN (Word256 -> UIntN n) -> Word256 -> UIntN n
forall a b. (a -> b) -> a -> b
$ Word256 -> Word256 -> Word256
forall a. Integral a => a -> a -> a
quot Word256
a Word256
b, Word256 -> UIntN n
forall (n :: Nat). Word256 -> UIntN n
UIntN (Word256 -> UIntN n) -> Word256 -> UIntN n
forall a b. (a -> b) -> a -> b
$ Word256 -> Word256 -> Word256
forall a. Integral a => a -> a -> a
rem Word256
a Word256
b)

instance (n <= 256) => AbiType (UIntN n) where
    isDynamic :: Proxy (UIntN n) -> Bool
isDynamic Proxy (UIntN n)
_ = Bool
False

instance (n <= 256) => AbiGet (UIntN n) where
    abiGet :: Get (UIntN n)
abiGet = Word256 -> UIntN n
forall (n :: Nat). Word256 -> UIntN n
UIntN (Word256 -> UIntN n) -> Get Word256 -> Get (UIntN n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word256
getWord256

instance (n <= 256) => AbiPut (UIntN n) where
    abiPut :: Putter (UIntN n)
abiPut = Putter Word256
putWord256 Putter Word256 -> (UIntN n -> Word256) -> Putter (UIntN n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UIntN n -> Word256
forall (n :: Nat). UIntN n -> Word256
unUIntN

-- | Signed integer with fixed length in bits.
newtype IntN (n :: Nat) = IntN { IntN n -> Word256
unIntN :: Word256 }
    deriving (IntN n -> IntN n -> Bool
(IntN n -> IntN n -> Bool)
-> (IntN n -> IntN n -> Bool) -> Eq (IntN n)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (n :: Nat). IntN n -> IntN n -> Bool
/= :: IntN n -> IntN n -> Bool
$c/= :: forall (n :: Nat). IntN n -> IntN n -> Bool
== :: IntN n -> IntN n -> Bool
$c== :: forall (n :: Nat). IntN n -> IntN n -> Bool
Eq, Eq (IntN n)
Eq (IntN n)
-> (IntN n -> IntN n -> Ordering)
-> (IntN n -> IntN n -> Bool)
-> (IntN n -> IntN n -> Bool)
-> (IntN n -> IntN n -> Bool)
-> (IntN n -> IntN n -> Bool)
-> (IntN n -> IntN n -> IntN n)
-> (IntN n -> IntN n -> IntN n)
-> Ord (IntN n)
IntN n -> IntN n -> Bool
IntN n -> IntN n -> Ordering
IntN n -> IntN n -> IntN n
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall (n :: Nat). Eq (IntN n)
forall (n :: Nat). IntN n -> IntN n -> Bool
forall (n :: Nat). IntN n -> IntN n -> Ordering
forall (n :: Nat). IntN n -> IntN n -> IntN n
min :: IntN n -> IntN n -> IntN n
$cmin :: forall (n :: Nat). IntN n -> IntN n -> IntN n
max :: IntN n -> IntN n -> IntN n
$cmax :: forall (n :: Nat). IntN n -> IntN n -> IntN n
>= :: IntN n -> IntN n -> Bool
$c>= :: forall (n :: Nat). IntN n -> IntN n -> Bool
> :: IntN n -> IntN n -> Bool
$c> :: forall (n :: Nat). IntN n -> IntN n -> Bool
<= :: IntN n -> IntN n -> Bool
$c<= :: forall (n :: Nat). IntN n -> IntN n -> Bool
< :: IntN n -> IntN n -> Bool
$c< :: forall (n :: Nat). IntN n -> IntN n -> Bool
compare :: IntN n -> IntN n -> Ordering
$ccompare :: forall (n :: Nat). IntN n -> IntN n -> Ordering
$cp1Ord :: forall (n :: Nat). Eq (IntN n)
Ord, Int -> IntN n
IntN n -> Int
IntN n -> [IntN n]
IntN n -> IntN n
IntN n -> IntN n -> [IntN n]
IntN n -> IntN n -> IntN n -> [IntN n]
(IntN n -> IntN n)
-> (IntN n -> IntN n)
-> (Int -> IntN n)
-> (IntN n -> Int)
-> (IntN n -> [IntN n])
-> (IntN n -> IntN n -> [IntN n])
-> (IntN n -> IntN n -> [IntN n])
-> (IntN n -> IntN n -> IntN n -> [IntN n])
-> Enum (IntN n)
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
forall (n :: Nat). Int -> IntN n
forall (n :: Nat). IntN n -> Int
forall (n :: Nat). IntN n -> [IntN n]
forall (n :: Nat). IntN n -> IntN n
forall (n :: Nat). IntN n -> IntN n -> [IntN n]
forall (n :: Nat). IntN n -> IntN n -> IntN n -> [IntN n]
enumFromThenTo :: IntN n -> IntN n -> IntN n -> [IntN n]
$cenumFromThenTo :: forall (n :: Nat). IntN n -> IntN n -> IntN n -> [IntN n]
enumFromTo :: IntN n -> IntN n -> [IntN n]
$cenumFromTo :: forall (n :: Nat). IntN n -> IntN n -> [IntN n]
enumFromThen :: IntN n -> IntN n -> [IntN n]
$cenumFromThen :: forall (n :: Nat). IntN n -> IntN n -> [IntN n]
enumFrom :: IntN n -> [IntN n]
$cenumFrom :: forall (n :: Nat). IntN n -> [IntN n]
fromEnum :: IntN n -> Int
$cfromEnum :: forall (n :: Nat). IntN n -> Int
toEnum :: Int -> IntN n
$ctoEnum :: forall (n :: Nat). Int -> IntN n
pred :: IntN n -> IntN n
$cpred :: forall (n :: Nat). IntN n -> IntN n
succ :: IntN n -> IntN n
$csucc :: forall (n :: Nat). IntN n -> IntN n
Enum, Eq (IntN n)
IntN n
Eq (IntN n)
-> (IntN n -> IntN n -> IntN n)
-> (IntN n -> IntN n -> IntN n)
-> (IntN n -> IntN n -> IntN n)
-> (IntN n -> IntN n)
-> (IntN n -> Int -> IntN n)
-> (IntN n -> Int -> IntN n)
-> IntN n
-> (Int -> IntN n)
-> (IntN n -> Int -> IntN n)
-> (IntN n -> Int -> IntN n)
-> (IntN n -> Int -> IntN n)
-> (IntN n -> Int -> Bool)
-> (IntN n -> Maybe Int)
-> (IntN n -> Int)
-> (IntN n -> Bool)
-> (IntN n -> Int -> IntN n)
-> (IntN n -> Int -> IntN n)
-> (IntN n -> Int -> IntN n)
-> (IntN n -> Int -> IntN n)
-> (IntN n -> Int -> IntN n)
-> (IntN n -> Int -> IntN n)
-> (IntN n -> Int)
-> Bits (IntN n)
Int -> IntN n
IntN n -> Bool
IntN n -> Int
IntN n -> Maybe Int
IntN n -> IntN n
IntN n -> Int -> Bool
IntN n -> Int -> IntN n
IntN n -> IntN n -> IntN n
forall a.
Eq a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
forall (n :: Nat). Eq (IntN n)
forall (n :: Nat). IntN n
forall (n :: Nat). Int -> IntN n
forall (n :: Nat). IntN n -> Bool
forall (n :: Nat). IntN n -> Int
forall (n :: Nat). IntN n -> Maybe Int
forall (n :: Nat). IntN n -> IntN n
forall (n :: Nat). IntN n -> Int -> Bool
forall (n :: Nat). IntN n -> Int -> IntN n
forall (n :: Nat). IntN n -> IntN n -> IntN n
popCount :: IntN n -> Int
$cpopCount :: forall (n :: Nat). IntN n -> Int
rotateR :: IntN n -> Int -> IntN n
$crotateR :: forall (n :: Nat). IntN n -> Int -> IntN n
rotateL :: IntN n -> Int -> IntN n
$crotateL :: forall (n :: Nat). IntN n -> Int -> IntN n
unsafeShiftR :: IntN n -> Int -> IntN n
$cunsafeShiftR :: forall (n :: Nat). IntN n -> Int -> IntN n
shiftR :: IntN n -> Int -> IntN n
$cshiftR :: forall (n :: Nat). IntN n -> Int -> IntN n
unsafeShiftL :: IntN n -> Int -> IntN n
$cunsafeShiftL :: forall (n :: Nat). IntN n -> Int -> IntN n
shiftL :: IntN n -> Int -> IntN n
$cshiftL :: forall (n :: Nat). IntN n -> Int -> IntN n
isSigned :: IntN n -> Bool
$cisSigned :: forall (n :: Nat). IntN n -> Bool
bitSize :: IntN n -> Int
$cbitSize :: forall (n :: Nat). IntN n -> Int
bitSizeMaybe :: IntN n -> Maybe Int
$cbitSizeMaybe :: forall (n :: Nat). IntN n -> Maybe Int
testBit :: IntN n -> Int -> Bool
$ctestBit :: forall (n :: Nat). IntN n -> Int -> Bool
complementBit :: IntN n -> Int -> IntN n
$ccomplementBit :: forall (n :: Nat). IntN n -> Int -> IntN n
clearBit :: IntN n -> Int -> IntN n
$cclearBit :: forall (n :: Nat). IntN n -> Int -> IntN n
setBit :: IntN n -> Int -> IntN n
$csetBit :: forall (n :: Nat). IntN n -> Int -> IntN n
bit :: Int -> IntN n
$cbit :: forall (n :: Nat). Int -> IntN n
zeroBits :: IntN n
$czeroBits :: forall (n :: Nat). IntN n
rotate :: IntN n -> Int -> IntN n
$crotate :: forall (n :: Nat). IntN n -> Int -> IntN n
shift :: IntN n -> Int -> IntN n
$cshift :: forall (n :: Nat). IntN n -> Int -> IntN n
complement :: IntN n -> IntN n
$ccomplement :: forall (n :: Nat). IntN n -> IntN n
xor :: IntN n -> IntN n -> IntN n
$cxor :: forall (n :: Nat). IntN n -> IntN n -> IntN n
.|. :: IntN n -> IntN n -> IntN n
$c.|. :: forall (n :: Nat). IntN n -> IntN n -> IntN n
.&. :: IntN n -> IntN n -> IntN n
$c.&. :: forall (n :: Nat). IntN n -> IntN n -> IntN n
$cp1Bits :: forall (n :: Nat). Eq (IntN n)
Bits, (forall x. IntN n -> Rep (IntN n) x)
-> (forall x. Rep (IntN n) x -> IntN n) -> Generic (IntN n)
forall x. Rep (IntN n) x -> IntN n
forall x. IntN n -> Rep (IntN n) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (n :: Nat) x. Rep (IntN n) x -> IntN n
forall (n :: Nat) x. IntN n -> Rep (IntN n) x
$cto :: forall (n :: Nat) x. Rep (IntN n) x -> IntN n
$cfrom :: forall (n :: Nat) x. IntN n -> Rep (IntN n) x
Generic)

instance (KnownNat n, n <= 256) => Show (IntN n) where
    show :: IntN n -> String
show = Integer -> String
forall a. Show a => a -> String
show (Integer -> String) -> (IntN n -> Integer) -> IntN n -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntN n -> Integer
forall a. Integral a => a -> Integer
toInteger

instance (KnownNat n, n <= 256) => Bounded (IntN n) where
    minBound :: IntN n
minBound = Word256 -> IntN n
forall (n :: Nat). Word256 -> IntN n
IntN (Word256 -> IntN n) -> Word256 -> IntN n
forall a b. (a -> b) -> a -> b
$ Word256 -> Word256
forall a. Num a => a -> a
negate (Word256 -> Word256) -> Word256 -> Word256
forall a b. (a -> b) -> a -> b
$ Word256
2 Word256 -> Integer -> Word256
forall a b. (Num a, Integral b) => a -> b -> a
^ (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy :: Proxy (n :: Nat)) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1)
    maxBound :: IntN n
maxBound = Word256 -> IntN n
forall (n :: Nat). Word256 -> IntN n
IntN (Word256 -> IntN n) -> Word256 -> IntN n
forall a b. (a -> b) -> a -> b
$ Word256
2 Word256 -> Integer -> Word256
forall a b. (Num a, Integral b) => a -> b -> a
^ (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy :: Proxy (n :: Nat)) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1) Word256 -> Word256 -> Word256
forall a. Num a => a -> a -> a
- Word256
1

instance (KnownNat n, n <= 256) => Num (IntN n) where
    IntN n
a + :: IntN n -> IntN n -> IntN n
+ IntN n
b  = Integer -> IntN n
forall a. Num a => Integer -> a
fromInteger (IntN n -> Integer
forall a. Integral a => a -> Integer
toInteger IntN n
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ IntN n -> Integer
forall a. Integral a => a -> Integer
toInteger IntN n
b)
    IntN n
a - :: IntN n -> IntN n -> IntN n
- IntN n
b  = Integer -> IntN n
forall a. Num a => Integer -> a
fromInteger (IntN n -> Integer
forall a. Integral a => a -> Integer
toInteger IntN n
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- IntN n -> Integer
forall a. Integral a => a -> Integer
toInteger IntN n
b)
    IntN n
a * :: IntN n -> IntN n -> IntN n
* IntN n
b  = Integer -> IntN n
forall a. Num a => Integer -> a
fromInteger (IntN n -> Integer
forall a. Integral a => a -> Integer
toInteger IntN n
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* IntN n -> Integer
forall a. Integral a => a -> Integer
toInteger IntN n
b)
    abs :: IntN n -> IntN n
abs    = Integer -> IntN n
forall a. Num a => Integer -> a
fromInteger (Integer -> IntN n) -> (IntN n -> Integer) -> IntN n -> IntN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Integer
forall a. Num a => a -> a
abs (Integer -> Integer) -> (IntN n -> Integer) -> IntN n -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntN n -> Integer
forall a. Integral a => a -> Integer
toInteger
    negate :: IntN n -> IntN n
negate = Integer -> IntN n
forall a. Num a => Integer -> a
fromInteger (Integer -> IntN n) -> (IntN n -> Integer) -> IntN n -> IntN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Integer
forall a. Num a => a -> a
negate (Integer -> Integer) -> (IntN n -> Integer) -> IntN n -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntN n -> Integer
forall a. Integral a => a -> Integer
toInteger
    signum :: IntN n -> IntN n
signum = Integer -> IntN n
forall a. Num a => Integer -> a
fromInteger (Integer -> IntN n) -> (IntN n -> Integer) -> IntN n -> IntN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Integer
forall a. Num a => a -> a
signum (Integer -> Integer) -> (IntN n -> Integer) -> IntN n -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntN n -> Integer
forall a. Integral a => a -> Integer
toInteger
    fromInteger :: Integer -> IntN n
fromInteger Integer
x
      | Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0 = Word256 -> IntN n
forall (n :: Nat). Word256 -> IntN n
IntN (Integer -> Word256
forall a. Num a => Integer -> a
fromInteger Integer
x)
      | Bool
otherwise = Word256 -> IntN n
forall (n :: Nat). Word256 -> IntN n
IntN (Integer -> Word256
forall a. Num a => Integer -> a
fromInteger (Integer -> Word256) -> Integer -> Word256
forall a b. (a -> b) -> a -> b
$ Integer
2 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
256 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
x)

instance (KnownNat n, n <= 256) => Real (IntN n) where
    toRational :: IntN n -> Rational
toRational = Integer -> Rational
forall a. Real a => a -> Rational
toRational (Integer -> Rational) -> (IntN n -> Integer) -> IntN n -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntN n -> Integer
forall a. Integral a => a -> Integer
toInteger

instance (KnownNat n, n <= 256) => Integral (IntN n) where
    quotRem :: IntN n -> IntN n -> (IntN n, IntN n)
quotRem (IntN Word256
a) (IntN Word256
b) = (Word256 -> IntN n
forall (n :: Nat). Word256 -> IntN n
IntN (Word256 -> IntN n) -> Word256 -> IntN n
forall a b. (a -> b) -> a -> b
$ Word256 -> Word256 -> Word256
forall a. Integral a => a -> a -> a
quot Word256
a Word256
b, Word256 -> IntN n
forall (n :: Nat). Word256 -> IntN n
IntN (Word256 -> IntN n) -> Word256 -> IntN n
forall a b. (a -> b) -> a -> b
$ Word256 -> Word256 -> Word256
forall a. Integral a => a -> a -> a
rem Word256
a Word256
b)
    toInteger :: IntN n -> Integer
toInteger IntN n
x
      | IntN n -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit IntN n
x Int
255 = Word256 -> Integer
forall a. Integral a => a -> Integer
toInteger (IntN n -> Word256
forall (n :: Nat). IntN n -> Word256
unIntN IntN n
x) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
2 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
256
      | Bool
otherwise = Word256 -> Integer
forall a. Integral a => a -> Integer
toInteger (Word256 -> Integer) -> Word256 -> Integer
forall a b. (a -> b) -> a -> b
$ IntN n -> Word256
forall (n :: Nat). IntN n -> Word256
unIntN IntN n
x

instance (n <= 256) => AbiType (IntN n) where
    isDynamic :: Proxy (IntN n) -> Bool
isDynamic Proxy (IntN n)
_ = Bool
False

instance (n <= 256) => AbiGet (IntN n) where
    abiGet :: Get (IntN n)
abiGet = Word256 -> IntN n
forall (n :: Nat). Word256 -> IntN n
IntN (Word256 -> IntN n) -> Get Word256 -> Get (IntN n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word256
getWord256

instance (n <= 256) => AbiPut (IntN n) where
    abiPut :: Putter (IntN n)
abiPut = Putter Word256
putWord256 Putter Word256 -> (IntN n -> Word256) -> Putter (IntN n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntN n -> Word256
forall (n :: Nat). IntN n -> Word256
unIntN

-- | Serialize 256 bit unsigned integer.
putWord256 :: Putter Word256
putWord256 :: Putter Word256
putWord256 (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) =
    Putter Word64
forall t. Serialize t => Putter t
put Word64
a3 PutM () -> PutM () -> PutM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Putter Word64
forall t. Serialize t => Putter t
put Word64
a2 PutM () -> PutM () -> PutM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Putter Word64
forall t. Serialize t => Putter t
put Word64
a1 PutM () -> PutM () -> PutM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Putter Word64
forall t. Serialize t => Putter t
put Word64
a0

-- | Deserialize 256 bit unsigned integer.
getWord256 :: Get Word256
getWord256 :: Get Word256
getWord256 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64 -> Word64 -> Word64 -> Word64 -> Word256)
-> Get Word64 -> Get (Word64 -> Word64 -> Word64 -> Word256)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word64
forall t. Serialize t => Get t
get Get (Word64 -> Word64 -> Word64 -> Word256)
-> Get Word64 -> Get (Word64 -> Word64 -> Word256)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word64
forall t. Serialize t => Get t
get Get (Word64 -> Word64 -> Word256)
-> Get Word64 -> Get (Word64 -> Word256)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word64
forall t. Serialize t => Get t
get Get (Word64 -> Word256) -> Get Word64 -> Get Word256
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word64
forall t. Serialize t => Get t
get