{-# Language CPP #-}
module Basement.Numerical.Number
    ( IsIntegral(..)
    , IsNatural(..)
    ) where

import           Basement.Compat.Base
import           Basement.Compat.C.Types
import           Basement.Compat.Natural
import           Basement.Compat.NumLiteral
import           Data.Bits
import qualified Prelude

-- | Number literals, convertible through the generic Integer type.
--
-- all number are Enum'erable, meaning that you can move to
-- next element
class (Integral a, Eq a, Ord a) => IsIntegral a where
    {-# MINIMAL toInteger #-}
    toInteger :: a -> Integer

-- | Non Negative Number literals, convertible through the generic Natural type
class IsIntegral a => IsNatural a where
    {-# MINIMAL toNatural #-}
    toNatural :: a -> Natural

instance IsIntegral Integer where
    toInteger :: Integer -> Integer
toInteger Integer
i = Integer
i
instance IsIntegral Int where
    toInteger :: Int -> Integer
toInteger Int
i = Int -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger Int
i
instance IsIntegral Int8 where
    toInteger :: Int8 -> Integer
toInteger Int8
i = Int8 -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger Int8
i
instance IsIntegral Int16 where
    toInteger :: Int16 -> Integer
toInteger Int16
i = Int16 -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger Int16
i
instance IsIntegral Int32 where
    toInteger :: Int32 -> Integer
toInteger Int32
i = Int32 -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger Int32
i
instance IsIntegral Int64 where
    toInteger :: Int64 -> Integer
toInteger Int64
i = Int64 -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger Int64
i
instance IsIntegral Natural where
    toInteger :: Natural -> Integer
toInteger Natural
i = Natural -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger Natural
i
instance IsIntegral Word where
    toInteger :: Word -> Integer
toInteger Word
i = Word -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger Word
i
instance IsIntegral Word8 where
    toInteger :: Word8 -> Integer
toInteger Word8
i = Word8 -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger Word8
i
instance IsIntegral Word16 where
    toInteger :: Word16 -> Integer
toInteger Word16
i = Word16 -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger Word16
i
instance IsIntegral Word32 where
    toInteger :: Word32 -> Integer
toInteger Word32
i = Word32 -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger Word32
i
instance IsIntegral Word64 where
    toInteger :: Word64 -> Integer
toInteger Word64
i = Word64 -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger Word64
i

instance IsIntegral CChar where
    toInteger :: CChar -> Integer
toInteger CChar
i = CChar -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CChar
i
instance IsIntegral CSChar where
    toInteger :: CSChar -> Integer
toInteger CSChar
i = CSChar -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CSChar
i
instance IsIntegral CUChar where
    toInteger :: CUChar -> Integer
toInteger CUChar
i = CUChar -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CUChar
i
instance IsIntegral CShort where
    toInteger :: CShort -> Integer
toInteger CShort
i = CShort -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CShort
i
instance IsIntegral CUShort where
    toInteger :: CUShort -> Integer
toInteger CUShort
i = CUShort -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CUShort
i
instance IsIntegral CInt where
    toInteger :: CInt -> Integer
toInteger CInt
i = CInt -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CInt
i
instance IsIntegral CUInt where
    toInteger :: CUInt -> Integer
toInteger CUInt
i = CUInt -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CUInt
i
instance IsIntegral CLong where
    toInteger :: CLong -> Integer
toInteger CLong
i = CLong -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CLong
i
instance IsIntegral CULong where
    toInteger :: CULong -> Integer
toInteger CULong
i = CULong -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CULong
i
instance IsIntegral CPtrdiff where
    toInteger :: CPtrdiff -> Integer
toInteger CPtrdiff
i = CPtrdiff -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CPtrdiff
i
instance IsIntegral CSize where
    toInteger :: CSize -> Integer
toInteger CSize
i = CSize -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CSize
i
instance IsIntegral CWchar where
    toInteger :: CWchar -> Integer
toInteger CWchar
i = CWchar -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CWchar
i
instance IsIntegral CSigAtomic where
    toInteger :: CSigAtomic -> Integer
toInteger CSigAtomic
i = CSigAtomic -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CSigAtomic
i
instance IsIntegral CLLong where
    toInteger :: CLLong -> Integer
toInteger CLLong
i = CLLong -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CLLong
i
instance IsIntegral CULLong where
    toInteger :: CULLong -> Integer
toInteger CULLong
i = CULLong -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CULLong
i
#if MIN_VERSION_base(4,10,0)
instance IsIntegral CBool where
    toInteger :: CBool -> Integer
toInteger CBool
i = CBool -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CBool
i
#endif
instance IsIntegral CIntPtr where
    toInteger :: CIntPtr -> Integer
toInteger CIntPtr
i = CIntPtr -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CIntPtr
i
instance IsIntegral CUIntPtr where
    toInteger :: CUIntPtr -> Integer
toInteger CUIntPtr
i = CUIntPtr -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CUIntPtr
i
instance IsIntegral CIntMax where
    toInteger :: CIntMax -> Integer
toInteger CIntMax
i = CIntMax -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CIntMax
i
instance IsIntegral CUIntMax where
    toInteger :: CUIntMax -> Integer
toInteger CUIntMax
i = CUIntMax -> Integer
forall a. Integral a => a -> Integer
Prelude.toInteger CUIntMax
i

instance IsNatural Natural where
    toNatural :: Natural -> Natural
toNatural Natural
i = Natural
i
instance IsNatural Word where
    toNatural :: Word -> Natural
toNatural Word
i = Word -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral Word
i
instance IsNatural Word8 where
    toNatural :: Word8 -> Natural
toNatural Word8
i = Word8 -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral Word8
i
instance IsNatural Word16 where
    toNatural :: Word16 -> Natural
toNatural Word16
i = Word16 -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral Word16
i
instance IsNatural Word32 where
    toNatural :: Word32 -> Natural
toNatural Word32
i = Word32 -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral Word32
i
instance IsNatural Word64 where
    toNatural :: Word64 -> Natural
toNatural Word64
i = Word64 -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral Word64
i

instance IsNatural CUChar where
    toNatural :: CUChar -> Natural
toNatural CUChar
i = CUChar -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral CUChar
i
instance IsNatural CUShort where
    toNatural :: CUShort -> Natural
toNatural CUShort
i = CUShort -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral CUShort
i
instance IsNatural CUInt where
    toNatural :: CUInt -> Natural
toNatural CUInt
i = CUInt -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral CUInt
i
instance IsNatural CULong where
    toNatural :: CULong -> Natural
toNatural CULong
i = CULong -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral CULong
i
instance IsNatural CSize where
    toNatural :: CSize -> Natural
toNatural CSize
i = CSize -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral CSize
i
instance IsNatural CULLong where
    toNatural :: CULLong -> Natural
toNatural CULLong
i = CULLong -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral CULLong
i
instance IsNatural CUIntPtr where
    toNatural :: CUIntPtr -> Natural
toNatural CUIntPtr
i = CUIntPtr -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral CUIntPtr
i
instance IsNatural CUIntMax where
    toNatural :: CUIntMax -> Natural
toNatural CUIntMax
i = CUIntMax -> Natural
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral CUIntMax
i