{-# LANGUAGE UndecidableInstances #-}

{- TODO can I replace this with a closed newtype family?? idk if I even want to
    it's just this is clumsy to use sometimes
-}

module Binrep.Type.Int where

import Binrep
import Binrep.Type.Common ( Endianness(..) )
import Strongweak

import Data.Word
import Data.Int
import Data.Aeson
import FlatParse.Basic qualified as FP
import Mason.Builder qualified as Mason

import GHC.Generics ( Generic )
import Data.Data ( Typeable, Data )
import GHC.TypeNats

-- | Wrapper type grouping machine integers (sign, size) along with an explicit
--   endianness.
--
-- The internal representation is selected via a type family to correspond to
-- the relevant Haskell data type, so common overflow behaviour should match.
-- We derive lots of handy instances, so you may perform regular arithmetic on
-- pairs of these types. For example:
--
-- >>> 255 + 1 :: I 'U 'I1 e
-- 0
--
-- >>> 255 + 1 :: I 'U 'I2 e
-- 256
newtype I (sign :: ISign) (size :: ISize) (e :: Endianness)
  = I { forall (sign :: ISign) (size :: ISize) (e :: Endianness).
I sign size e -> IRep sign size
getI :: IRep sign size }
    deriving stock (forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (sign :: ISign) (size :: ISize) (e :: Endianness) x.
Rep (I sign size e) x -> I sign size e
forall (sign :: ISign) (size :: ISize) (e :: Endianness) x.
I sign size e -> Rep (I sign size e) x
$cto :: forall (sign :: ISign) (size :: ISize) (e :: Endianness) x.
Rep (I sign size e) x -> I sign size e
$cfrom :: forall (sign :: ISign) (size :: ISize) (e :: Endianness) x.
I sign size e -> Rep (I sign size e) x
Generic)

deriving instance (Data (IRep sign size), Typeable sign, Typeable size, Typeable e) => Data (I sign size e)
deriving via (IRep sign size) instance Show     (IRep sign size) => Show     (I sign size e)

-- Steal various numeric instances from the representation types.
deriving via (IRep sign size) instance Eq       (IRep sign size) => Eq       (I sign size e)
deriving via (IRep sign size) instance Ord      (IRep sign size) => Ord      (I sign size e)
deriving via (IRep sign size) instance Bounded  (IRep sign size) => Bounded  (I sign size e)
deriving via (IRep sign size) instance Num      (IRep sign size) => Num      (I sign size e)
deriving via (IRep sign size) instance Real     (IRep sign size) => Real     (I sign size e)
deriving via (IRep sign size) instance Enum     (IRep sign size) => Enum     (I sign size e)
deriving via (IRep sign size) instance Integral (IRep sign size) => Integral (I sign size e)

-- | Unsigned machine integers can be idealized as naturals.
instance (irep ~ IRep 'U size, Integral irep) => Weaken (I 'U size end) where
    type Weak (I 'U size end) = Natural
    weaken :: I 'U size end -> Weak (I 'U size end)
weaken = forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance (irep ~ IRep 'U size, Integral irep, Bounded irep, Show irep, Typeable size, Typeable end)
  => Strengthen (I 'U size end) where
      strengthen :: Weak (I 'U size end)
-> Validation (NonEmpty StrengthenFail) (I 'U size end)
strengthen = forall b n.
(Integral b, Bounded b, Show b, Typeable b, Integral n, Show n,
 Typeable n) =>
n -> Validation (NonEmpty StrengthenFail) b
strengthenBounded

-- | Signed machine integers can be idealized as integers.
instance (irep ~ IRep 'S size, Integral irep) => Weaken (I 'S size end) where
    type Weak (I 'S size end) = Integer
    weaken :: I 'S size end -> Weak (I 'S size end)
weaken = forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance (irep ~ IRep 'S size, Integral irep, Bounded irep, Show irep, Typeable size, Typeable end)
  => Strengthen (I 'S size end) where
      strengthen :: Weak (I 'S size end)
-> Validation (NonEmpty StrengthenFail) (I 'S size end)
strengthen = forall b n.
(Integral b, Bounded b, Show b, Typeable b, Integral n, Show n,
 Typeable n) =>
n -> Validation (NonEmpty StrengthenFail) b
strengthenBounded

-- | Machine integer sign.
data ISign
  = S -- ^   signed
  | U -- ^ unsigned
    deriving stock (forall x. Rep ISign x -> ISign
forall x. ISign -> Rep ISign x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ISign x -> ISign
$cfrom :: forall x. ISign -> Rep ISign x
Generic, Typeable ISign
ISign -> DataType
ISign -> Constr
(forall b. Data b => b -> b) -> ISign -> ISign
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ISign -> u
forall u. (forall d. Data d => d -> u) -> ISign -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> ISign -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> ISign -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ISign -> m ISign
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ISign -> m ISign
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ISign
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ISign -> c ISign
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ISign)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ISign)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ISign -> m ISign
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ISign -> m ISign
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ISign -> m ISign
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ISign -> m ISign
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ISign -> m ISign
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ISign -> m ISign
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ISign -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ISign -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> ISign -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ISign -> [u]
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> ISign -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> ISign -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> ISign -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> ISign -> r
gmapT :: (forall b. Data b => b -> b) -> ISign -> ISign
$cgmapT :: (forall b. Data b => b -> b) -> ISign -> ISign
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ISign)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ISign)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ISign)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ISign)
dataTypeOf :: ISign -> DataType
$cdataTypeOf :: ISign -> DataType
toConstr :: ISign -> Constr
$ctoConstr :: ISign -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ISign
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ISign
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ISign -> c ISign
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ISign -> c ISign
Data, Int -> ISign -> ShowS
[ISign] -> ShowS
ISign -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ISign] -> ShowS
$cshowList :: [ISign] -> ShowS
show :: ISign -> String
$cshow :: ISign -> String
showsPrec :: Int -> ISign -> ShowS
$cshowsPrec :: Int -> ISign -> ShowS
Show, ISign -> ISign -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ISign -> ISign -> Bool
$c/= :: ISign -> ISign -> Bool
== :: ISign -> ISign -> Bool
$c== :: ISign -> ISign -> Bool
Eq)

-- | Machine integer size in number of bytes.
data ISize = I1 | I2 | I4 | I8
    deriving stock (forall x. Rep ISize x -> ISize
forall x. ISize -> Rep ISize x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ISize x -> ISize
$cfrom :: forall x. ISize -> Rep ISize x
Generic, Typeable ISize
ISize -> DataType
ISize -> Constr
(forall b. Data b => b -> b) -> ISize -> ISize
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ISize -> u
forall u. (forall d. Data d => d -> u) -> ISize -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> ISize -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> ISize -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ISize -> m ISize
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ISize -> m ISize
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ISize
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ISize -> c ISize
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ISize)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ISize)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ISize -> m ISize
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ISize -> m ISize
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ISize -> m ISize
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ISize -> m ISize
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ISize -> m ISize
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ISize -> m ISize
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ISize -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ISize -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> ISize -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ISize -> [u]
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> ISize -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> ISize -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> ISize -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> ISize -> r
gmapT :: (forall b. Data b => b -> b) -> ISize -> ISize
$cgmapT :: (forall b. Data b => b -> b) -> ISize -> ISize
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ISize)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ISize)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ISize)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ISize)
dataTypeOf :: ISize -> DataType
$cdataTypeOf :: ISize -> DataType
toConstr :: ISize -> Constr
$ctoConstr :: ISize -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ISize
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ISize
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ISize -> c ISize
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ISize -> c ISize
Data, Int -> ISize -> ShowS
[ISize] -> ShowS
ISize -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ISize] -> ShowS
$cshowList :: [ISize] -> ShowS
show :: ISize -> String
$cshow :: ISize -> String
showsPrec :: Int -> ISize -> ShowS
$cshowsPrec :: Int -> ISize -> ShowS
Show, ISize -> ISize -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ISize -> ISize -> Bool
$c/= :: ISize -> ISize -> Bool
== :: ISize -> ISize -> Bool
$c== :: ISize -> ISize -> Bool
Eq)

-- | Grouping for matching a signedness and size to a Haskell integer data type.
type family IRep (sign :: ISign) (size :: ISize) where
    IRep 'U 'I1 = Word8
    IRep 'S 'I1 =  Int8
    IRep 'U 'I2 = Word16
    IRep 'S 'I2 =  Int16
    IRep 'U 'I4 = Word32
    IRep 'S 'I4 =  Int32
    IRep 'U 'I8 = Word64
    IRep 'S 'I8 =  Int64

-- Also steal Aeson instances. The parser applies bounding checks appropriately.
deriving via (IRep sign size) instance ToJSON   (IRep sign size) => ToJSON   (I sign size e)
deriving via (IRep sign size) instance FromJSON (IRep sign size) => FromJSON (I sign size e)

instance KnownNat (CBLen (I sign size end)) => BLen (I sign size end) where
    type CBLen (I sign size end) = CBLen (IRep sign size)

instance Put (I 'U 'I1 e) where put :: I 'U 'I1 e -> Builder
put = forall a. Put a => a -> Builder
put forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (sign :: ISign) (size :: ISize) (e :: Endianness).
I sign size e -> IRep sign size
getI
instance Get (I 'U 'I1 e) where get :: Getter (I 'U 'I1 e)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Get a => Getter a
get
instance Put (I 'S 'I1 e) where put :: I 'S 'I1 e -> Builder
put = forall a. Put a => a -> Builder
put forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (sign :: ISign) (size :: ISize) (e :: Endianness).
I sign size e -> IRep sign size
getI
instance Get (I 'S 'I1 e) where get :: Getter (I 'S 'I1 e)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Get a => Getter a
get

instance Put (I 'U 'I2 'BE) where put :: I 'U 'I2 'BE -> Builder
put (I IRep 'U 'I2
i) = Word16 -> Builder
Mason.word16BE IRep 'U 'I2
i
instance Get (I 'U 'I2 'BE) where get :: Getter (I 'U 'I2 'BE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Word16
FP.anyWord16be (Natural -> EBase
ERanOut Natural
2)
instance Put (I 'U 'I2 'LE) where put :: I 'U 'I2 'LE -> Builder
put (I IRep 'U 'I2
i) = Word16 -> Builder
Mason.word16LE IRep 'U 'I2
i
instance Get (I 'U 'I2 'LE) where get :: Getter (I 'U 'I2 'LE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Word16
FP.anyWord16le (Natural -> EBase
ERanOut Natural
2)
instance Put (I 'S 'I2 'BE) where put :: I 'S 'I2 'BE -> Builder
put (I IRep 'S 'I2
i) = Int16 -> Builder
Mason.int16BE IRep 'S 'I2
i
instance Get (I 'S 'I2 'BE) where get :: Getter (I 'S 'I2 'BE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Int16
FP.anyInt16be  (Natural -> EBase
ERanOut Natural
2)
instance Put (I 'S 'I2 'LE) where put :: I 'S 'I2 'LE -> Builder
put (I IRep 'S 'I2
i) = Int16 -> Builder
Mason.int16LE IRep 'S 'I2
i
instance Get (I 'S 'I2 'LE) where get :: Getter (I 'S 'I2 'LE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Int16
FP.anyInt16le  (Natural -> EBase
ERanOut Natural
2)

instance Put (I 'U 'I4 'BE) where put :: I 'U 'I4 'BE -> Builder
put (I IRep 'U 'I4
i) = Word32 -> Builder
Mason.word32BE IRep 'U 'I4
i
instance Get (I 'U 'I4 'BE) where get :: Getter (I 'U 'I4 'BE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Word32
FP.anyWord32be (Natural -> EBase
ERanOut Natural
4)
instance Put (I 'U 'I4 'LE) where put :: I 'U 'I4 'LE -> Builder
put (I IRep 'U 'I4
i) = Word32 -> Builder
Mason.word32LE IRep 'U 'I4
i
instance Get (I 'U 'I4 'LE) where get :: Getter (I 'U 'I4 'LE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Word32
FP.anyWord32le (Natural -> EBase
ERanOut Natural
4)
instance Put (I 'S 'I4 'BE) where put :: I 'S 'I4 'BE -> Builder
put (I IRep 'S 'I4
i) = Int32 -> Builder
Mason.int32BE IRep 'S 'I4
i
instance Get (I 'S 'I4 'BE) where get :: Getter (I 'S 'I4 'BE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Int32
FP.anyInt32be  (Natural -> EBase
ERanOut Natural
4)
instance Put (I 'S 'I4 'LE) where put :: I 'S 'I4 'LE -> Builder
put (I IRep 'S 'I4
i) = Int32 -> Builder
Mason.int32LE IRep 'S 'I4
i
instance Get (I 'S 'I4 'LE) where get :: Getter (I 'S 'I4 'LE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Int32
FP.anyInt32le  (Natural -> EBase
ERanOut Natural
4)

instance Put (I 'U 'I8 'BE) where put :: I 'U 'I8 'BE -> Builder
put (I IRep 'U 'I8
i) = Word64 -> Builder
Mason.word64BE IRep 'U 'I8
i
instance Get (I 'U 'I8 'BE) where get :: Getter (I 'U 'I8 'BE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Word64
FP.anyWord64be (Natural -> EBase
ERanOut Natural
8)
instance Put (I 'U 'I8 'LE) where put :: I 'U 'I8 'LE -> Builder
put (I IRep 'U 'I8
i) = Word64 -> Builder
Mason.word64LE IRep 'U 'I8
i
instance Get (I 'U 'I8 'LE) where get :: Getter (I 'U 'I8 'LE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Word64
FP.anyWord64le (Natural -> EBase
ERanOut Natural
8)
instance Put (I 'S 'I8 'BE) where put :: I 'S 'I8 'BE -> Builder
put (I IRep 'S 'I8
i) = Int64 -> Builder
Mason.int64BE IRep 'S 'I8
i
instance Get (I 'S 'I8 'BE) where get :: Getter (I 'S 'I8 'BE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Int64
FP.anyInt64be  (Natural -> EBase
ERanOut Natural
8)
instance Put (I 'S 'I8 'LE) where put :: I 'S 'I8 'LE -> Builder
put (I IRep 'S 'I8
i) = Int64 -> Builder
Mason.int64LE IRep 'S 'I8
i
instance Get (I 'S 'I8 'LE) where get :: Getter (I 'S 'I8 'LE)
get = forall (sign :: ISign) (size :: ISize) (e :: Endianness).
IRep sign size -> I sign size e
I forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Getter a -> EBase -> Getter a
cutEBase forall e. Parser e Int64
FP.anyInt64le  (Natural -> EBase
ERanOut Natural
8)

-- | Shortcut.
type family IMax (sign :: ISign) (size :: ISize) :: Natural where
    IMax sign size = MaxBound (IRep sign size)

-- | Restricted reflected version of @maxBound@.
type family MaxBound w :: Natural where
    MaxBound Word8  = 255
    MaxBound  Int8  = 127
    MaxBound Word16 = 65535
    MaxBound  Int16 = 32767
    MaxBound Word32 = 4294967295
    MaxBound  Int32 = 2147483647
    MaxBound Word64 = 18446744073709551615
    MaxBound  Int64 = 9223372036854775807