{-# LANGUAGE FunctionalDependencies #-}

module Grisette.Internal.Core.Data.Class.SignConversion
  ( SignConversion (..),
  )
where

import Data.Int (Int16, Int32, Int64, Int8)
import Data.Word (Word16, Word32, Word64, Word8)

-- | Convert values between signed and unsigned.
class SignConversion ubv sbv | ubv -> sbv, sbv -> ubv where
  -- | Convert unsigned value to the corresponding signed value.
  toSigned :: ubv -> sbv

  -- | Convert signed value to the corresponding unsigned value.
  toUnsigned :: sbv -> ubv

instance SignConversion Word8 Int8 where
  toSigned :: Word8 -> Int8
toSigned = Word8 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  toUnsigned :: Int8 -> Word8
toUnsigned = Int8 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral

instance SignConversion Word16 Int16 where
  toSigned :: Word16 -> Int16
toSigned = Word16 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  toUnsigned :: Int16 -> Word16
toUnsigned = Int16 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral

instance SignConversion Word32 Int32 where
  toSigned :: Word32 -> Int32
toSigned = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  toUnsigned :: Int32 -> Word32
toUnsigned = Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral

instance SignConversion Word64 Int64 where
  toSigned :: Word64 -> Int64
toSigned = Word64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  toUnsigned :: Int64 -> Word64
toUnsigned = Int64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral

instance SignConversion Word Int where
  toSigned :: Word -> Int
toSigned = Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  toUnsigned :: Int -> Word
toUnsigned = Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral