{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE CPP, NoImplicitPrelude, BangPatterns, MagicHash #-}
module Data.Bits (
Bits(
(.&.), (.|.), xor,
complement,
shift,
rotate,
zeroBits,
bit,
setBit,
clearBit,
complementBit,
testBit,
bitSizeMaybe,
bitSize,
isSigned,
shiftL, shiftR,
unsafeShiftL, unsafeShiftR,
rotateL, rotateR,
popCount
),
FiniteBits(
finiteBitSize,
countLeadingZeros,
countTrailingZeros
),
bitDefault,
testBitDefault,
popCountDefault,
toIntegralSized
) where
#include "MachDeps.h"
import Data.Maybe
import GHC.Enum
import GHC.Num
import GHC.Base
import GHC.Real
infixl 8 `shift`, `rotate`, `shiftL`, `shiftR`, `rotateL`, `rotateR`
infixl 7 .&.
infixl 6 `xor`
infixl 5 .|.
{-# DEPRECATED bitSize "Use 'bitSizeMaybe' or 'finiteBitSize' instead" #-}
class Eq a => Bits a where
{-# MINIMAL (.&.), (.|.), xor, complement,
(shift | (shiftL, shiftR)),
(rotate | (rotateL, rotateR)),
bitSize, bitSizeMaybe, isSigned, testBit, bit, popCount #-}
(.&.) :: a -> a -> a
(.|.) :: a -> a -> a
xor :: a -> a -> a
complement :: a -> a
shift :: a -> Int -> a
x :: a
x `shift` i :: Int
i | Int
iInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<0 = a
x a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftR` (-Int
i)
| Int
iInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>0 = a
x a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` Int
i
| Bool
otherwise = a
x
rotate :: a -> Int -> a
x :: a
x `rotate` i :: Int
i | Int
iInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<0 = a
x a -> Int -> a
forall a. Bits a => a -> Int -> a
`rotateR` (-Int
i)
| Int
iInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>0 = a
x a -> Int -> a
forall a. Bits a => a -> Int -> a
`rotateL` Int
i
| Bool
otherwise = a
x
zeroBits :: a
zeroBits = a -> Int -> a
forall a. Bits a => a -> Int -> a
clearBit (Int -> a
forall a. Bits a => Int -> a
bit 0) 0
bit :: Int -> a
setBit :: a -> Int -> a
clearBit :: a -> Int -> a
complementBit :: a -> Int -> a
testBit :: a -> Int -> Bool
bitSizeMaybe :: a -> Maybe Int
bitSize :: a -> Int
bitSize b :: a
b = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> Int
forall a. HasCallStack => [Char] -> a
error "bitSize is undefined") (a -> Maybe Int
forall a. Bits a => a -> Maybe Int
bitSizeMaybe a
b)
isSigned :: a -> Bool
{-# INLINE setBit #-}
{-# INLINE clearBit #-}
{-# INLINE complementBit #-}
x :: a
x `setBit` i :: Int
i = a
x a -> a -> a
forall a. Bits a => a -> a -> a
.|. Int -> a
forall a. Bits a => Int -> a
bit Int
i
x :: a
x `clearBit` i :: Int
i = a
x a -> a -> a
forall a. Bits a => a -> a -> a
.&. a -> a
forall a. Bits a => a -> a
complement (Int -> a
forall a. Bits a => Int -> a
bit Int
i)
x :: a
x `complementBit` i :: Int
i = a
x a -> a -> a
forall a. Bits a => a -> a -> a
`xor` Int -> a
forall a. Bits a => Int -> a
bit Int
i
shiftL :: a -> Int -> a
{-# INLINE shiftL #-}
x :: a
x `shiftL` i :: Int
i = a
x a -> Int -> a
forall a. Bits a => a -> Int -> a
`shift` Int
i
unsafeShiftL :: a -> Int -> a
{-# INLINE unsafeShiftL #-}
x :: a
x `unsafeShiftL` i :: Int
i = a
x a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` Int
i
shiftR :: a -> Int -> a
{-# INLINE shiftR #-}
x :: a
x `shiftR` i :: Int
i = a
x a -> Int -> a
forall a. Bits a => a -> Int -> a
`shift` (-Int
i)
unsafeShiftR :: a -> Int -> a
{-# INLINE unsafeShiftR #-}
x :: a
x `unsafeShiftR` i :: Int
i = a
x a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftR` Int
i
rotateL :: a -> Int -> a
{-# INLINE rotateL #-}
x :: a
x `rotateL` i :: Int
i = a
x a -> Int -> a
forall a. Bits a => a -> Int -> a
`rotate` Int
i
rotateR :: a -> Int -> a
{-# INLINE rotateR #-}
x :: a
x `rotateR` i :: Int
i = a
x a -> Int -> a
forall a. Bits a => a -> Int -> a
`rotate` (-Int
i)
popCount :: a -> Int
class Bits b => FiniteBits b where
finiteBitSize :: b -> Int
countLeadingZeros :: b -> Int
countLeadingZeros x :: b
x = (Int
wInt -> Int -> Int
forall a. Num a => a -> a -> a
-1) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int -> Int
go (Int
wInt -> Int -> Int
forall a. Num a => a -> a -> a
-1)
where
go :: Int -> Int
go i :: Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = Int
i
| b -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit b
x Int
i = Int
i
| Bool
otherwise = Int -> Int
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-1)
w :: Int
w = b -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize b
x
countTrailingZeros :: b -> Int
countTrailingZeros x :: b
x = Int -> Int
go 0
where
go :: Int -> Int
go i :: Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
w = Int
i
| b -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit b
x Int
i = Int
i
| Bool
otherwise = Int -> Int
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+1)
w :: Int
w = b -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize b
x
bitDefault :: (Bits a, Num a) => Int -> a
bitDefault :: Int -> a
bitDefault = \i :: Int
i -> 1 a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` Int
i
{-# INLINE bitDefault #-}
testBitDefault :: (Bits a, Num a) => a -> Int -> Bool
testBitDefault :: a -> Int -> Bool
testBitDefault = \x :: a
x i :: Int
i -> (a
x a -> a -> a
forall a. Bits a => a -> a -> a
.&. Int -> a
forall a. Bits a => Int -> a
bit Int
i) a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= 0
{-# INLINE testBitDefault #-}
popCountDefault :: (Bits a, Num a) => a -> Int
popCountDefault :: a -> Int
popCountDefault = Int -> a -> Int
forall t t. (Num t, Num t, Bits t) => t -> t -> t
go 0
where
go :: t -> t -> t
go !t
c 0 = t
c
go c :: t
c w :: t
w = t -> t -> t
go (t
ct -> t -> t
forall a. Num a => a -> a -> a
+1) (t
w t -> t -> t
forall a. Bits a => a -> a -> a
.&. (t
w t -> t -> t
forall a. Num a => a -> a -> a
- 1))
{-# INLINABLE popCountDefault #-}
instance Bits Bool where
.&. :: Bool -> Bool -> Bool
(.&.) = Bool -> Bool -> Bool
(&&)
.|. :: Bool -> Bool -> Bool
(.|.) = Bool -> Bool -> Bool
(||)
xor :: Bool -> Bool -> Bool
xor = Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
(/=)
complement :: Bool -> Bool
complement = Bool -> Bool
not
shift :: Bool -> Int -> Bool
shift x :: Bool
x 0 = Bool
x
shift _ _ = Bool
False
rotate :: Bool -> Int -> Bool
rotate x :: Bool
x _ = Bool
x
bit :: Int -> Bool
bit 0 = Bool
True
bit _ = Bool
False
testBit :: Bool -> Int -> Bool
testBit x :: Bool
x 0 = Bool
x
testBit _ _ = Bool
False
bitSizeMaybe :: Bool -> Maybe Int
bitSizeMaybe _ = Int -> Maybe Int
forall a. a -> Maybe a
Just 1
bitSize :: Bool -> Int
bitSize _ = 1
isSigned :: Bool -> Bool
isSigned _ = Bool
False
popCount :: Bool -> Int
popCount False = 0
popCount True = 1
instance FiniteBits Bool where
finiteBitSize :: Bool -> Int
finiteBitSize _ = 1
countTrailingZeros :: Bool -> Int
countTrailingZeros x :: Bool
x = if Bool
x then 0 else 1
countLeadingZeros :: Bool -> Int
countLeadingZeros x :: Bool
x = if Bool
x then 0 else 1
instance Bits Int where
{-# INLINE shift #-}
{-# INLINE bit #-}
{-# INLINE testBit #-}
zeroBits :: Int
zeroBits = 0
bit :: Int -> Int
bit = Int -> Int
forall a. (Bits a, Num a) => Int -> a
bitDefault
testBit :: Int -> Int -> Bool
testBit = Int -> Int -> Bool
forall a. (Bits a, Num a) => a -> Int -> Bool
testBitDefault
(I# x# :: Int#
x#) .&. :: Int -> Int -> Int
.&. (I# y# :: Int#
y#) = Int# -> Int
I# (Int#
x# Int# -> Int# -> Int#
`andI#` Int#
y#)
(I# x# :: Int#
x#) .|. :: Int -> Int -> Int
.|. (I# y# :: Int#
y#) = Int# -> Int
I# (Int#
x# Int# -> Int# -> Int#
`orI#` Int#
y#)
(I# x# :: Int#
x#) xor :: Int -> Int -> Int
`xor` (I# y# :: Int#
y#) = Int# -> Int
I# (Int#
x# Int# -> Int# -> Int#
`xorI#` Int#
y#)
complement :: Int -> Int
complement (I# x# :: Int#
x#) = Int# -> Int
I# (Int# -> Int#
notI# Int#
x#)
(I# x# :: Int#
x#) shift :: Int -> Int -> Int
`shift` (I# i# :: Int#
i#)
| Int# -> Bool
isTrue# (Int#
i# Int# -> Int# -> Int#
>=# 0#) = Int# -> Int
I# (Int#
x# Int# -> Int# -> Int#
`iShiftL#` Int#
i#)
| Bool
otherwise = Int# -> Int
I# (Int#
x# Int# -> Int# -> Int#
`iShiftRA#` Int# -> Int#
negateInt# Int#
i#)
(I# x# :: Int#
x#) shiftL :: Int -> Int -> Int
`shiftL` (I# i# :: Int#
i#)
| Int# -> Bool
isTrue# (Int#
i# Int# -> Int# -> Int#
>=# 0#) = Int# -> Int
I# (Int#
x# Int# -> Int# -> Int#
`iShiftL#` Int#
i#)
| Bool
otherwise = Int
forall a. a
overflowError
(I# x# :: Int#
x#) unsafeShiftL :: Int -> Int -> Int
`unsafeShiftL` (I# i# :: Int#
i#) = Int# -> Int
I# (Int#
x# Int# -> Int# -> Int#
`uncheckedIShiftL#` Int#
i#)
(I# x# :: Int#
x#) shiftR :: Int -> Int -> Int
`shiftR` (I# i# :: Int#
i#)
| Int# -> Bool
isTrue# (Int#
i# Int# -> Int# -> Int#
>=# 0#) = Int# -> Int
I# (Int#
x# Int# -> Int# -> Int#
`iShiftRA#` Int#
i#)
| Bool
otherwise = Int
forall a. a
overflowError
(I# x# :: Int#
x#) unsafeShiftR :: Int -> Int -> Int
`unsafeShiftR` (I# i# :: Int#
i#) = Int# -> Int
I# (Int#
x# Int# -> Int# -> Int#
`uncheckedIShiftRA#` Int#
i#)
{-# INLINE rotate #-}
(I# x# :: Int#
x#) rotate :: Int -> Int -> Int
`rotate` (I# i# :: Int#
i#) =
Int# -> Int
I# ((Int#
x# Int# -> Int# -> Int#
`uncheckedIShiftL#` Int#
i'#) Int# -> Int# -> Int#
`orI#` (Int#
x# Int# -> Int# -> Int#
`uncheckedIShiftRL#` (Int#
wsib Int# -> Int# -> Int#
-# Int#
i'#)))
where
!i'# :: Int#
i'# = Int#
i# Int# -> Int# -> Int#
`andI#` (Int#
wsib Int# -> Int# -> Int#
-# 1#)
!wsib :: Int#
wsib = WORD_SIZE_IN_BITS#
bitSizeMaybe :: Int -> Maybe Int
bitSizeMaybe i :: Int
i = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Int
i)
bitSize :: Int -> Int
bitSize i :: Int
i = Int -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Int
i
popCount :: Int -> Int
popCount (I# x# :: Int#
x#) = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
popCnt# (Int# -> Word#
int2Word# Int#
x#)))
isSigned :: Int -> Bool
isSigned _ = Bool
True
instance FiniteBits Int where
finiteBitSize :: Int -> Int
finiteBitSize _ = WORD_SIZE_IN_BITS
countLeadingZeros :: Int -> Int
countLeadingZeros (I# x# :: Int#
x#) = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
clz# (Int# -> Word#
int2Word# Int#
x#)))
countTrailingZeros :: Int -> Int
countTrailingZeros (I# x# :: Int#
x#) = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
ctz# (Int# -> Word#
int2Word# Int#
x#)))
instance Bits Word where
{-# INLINE shift #-}
{-# INLINE bit #-}
{-# INLINE testBit #-}
(W# x# :: Word#
x#) .&. :: Word -> Word -> Word
.&. (W# y# :: Word#
y#) = Word# -> Word
W# (Word#
x# Word# -> Word# -> Word#
`and#` Word#
y#)
(W# x# :: Word#
x#) .|. :: Word -> Word -> Word
.|. (W# y# :: Word#
y#) = Word# -> Word
W# (Word#
x# Word# -> Word# -> Word#
`or#` Word#
y#)
(W# x# :: Word#
x#) xor :: Word -> Word -> Word
`xor` (W# y# :: Word#
y#) = Word# -> Word
W# (Word#
x# Word# -> Word# -> Word#
`xor#` Word#
y#)
complement :: Word -> Word
complement (W# x# :: Word#
x#) = Word# -> Word
W# (Word#
x# Word# -> Word# -> Word#
`xor#` Word#
mb#)
where !(W# mb# :: Word#
mb#) = Word
forall a. Bounded a => a
maxBound
(W# x# :: Word#
x#) shift :: Word -> Int -> Word
`shift` (I# i# :: Int#
i#)
| Int# -> Bool
isTrue# (Int#
i# Int# -> Int# -> Int#
>=# 0#) = Word# -> Word
W# (Word#
x# Word# -> Int# -> Word#
`shiftL#` Int#
i#)
| Bool
otherwise = Word# -> Word
W# (Word#
x# Word# -> Int# -> Word#
`shiftRL#` Int# -> Int#
negateInt# Int#
i#)
(W# x# :: Word#
x#) shiftL :: Word -> Int -> Word
`shiftL` (I# i# :: Int#
i#)
| Int# -> Bool
isTrue# (Int#
i# Int# -> Int# -> Int#
>=# 0#) = Word# -> Word
W# (Word#
x# Word# -> Int# -> Word#
`shiftL#` Int#
i#)
| Bool
otherwise = Word
forall a. a
overflowError
(W# x# :: Word#
x#) unsafeShiftL :: Word -> Int -> Word
`unsafeShiftL` (I# i# :: Int#
i#) = Word# -> Word
W# (Word#
x# Word# -> Int# -> Word#
`uncheckedShiftL#` Int#
i#)
(W# x# :: Word#
x#) shiftR :: Word -> Int -> Word
`shiftR` (I# i# :: Int#
i#)
| Int# -> Bool
isTrue# (Int#
i# Int# -> Int# -> Int#
>=# 0#) = Word# -> Word
W# (Word#
x# Word# -> Int# -> Word#
`shiftRL#` Int#
i#)
| Bool
otherwise = Word
forall a. a
overflowError
(W# x# :: Word#
x#) unsafeShiftR :: Word -> Int -> Word
`unsafeShiftR` (I# i# :: Int#
i#) = Word# -> Word
W# (Word#
x# Word# -> Int# -> Word#
`uncheckedShiftRL#` Int#
i#)
(W# x# :: Word#
x#) rotate :: Word -> Int -> Word
`rotate` (I# i# :: Int#
i#)
| Int# -> Bool
isTrue# (Int#
i'# Int# -> Int# -> Int#
==# 0#) = Word# -> Word
W# Word#
x#
| Bool
otherwise = Word# -> Word
W# ((Word#
x# Word# -> Int# -> Word#
`uncheckedShiftL#` Int#
i'#) Word# -> Word# -> Word#
`or#` (Word#
x# Word# -> Int# -> Word#
`uncheckedShiftRL#` (Int#
wsib Int# -> Int# -> Int#
-# Int#
i'#)))
where
!i'# :: Int#
i'# = Int#
i# Int# -> Int# -> Int#
`andI#` (Int#
wsib Int# -> Int# -> Int#
-# 1#)
!wsib :: Int#
wsib = WORD_SIZE_IN_BITS#
bitSizeMaybe :: Word -> Maybe Int
bitSizeMaybe i :: Word
i = Int -> Maybe Int
forall a. a -> Maybe a
Just (Word -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Word
i)
bitSize :: Word -> Int
bitSize i :: Word
i = Word -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Word
i
isSigned :: Word -> Bool
isSigned _ = Bool
False
popCount :: Word -> Int
popCount (W# x# :: Word#
x#) = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
popCnt# Word#
x#))
bit :: Int -> Word
bit = Int -> Word
forall a. (Bits a, Num a) => Int -> a
bitDefault
testBit :: Word -> Int -> Bool
testBit = Word -> Int -> Bool
forall a. (Bits a, Num a) => a -> Int -> Bool
testBitDefault
instance FiniteBits Word where
finiteBitSize :: Word -> Int
finiteBitSize _ = WORD_SIZE_IN_BITS
countLeadingZeros :: Word -> Int
countLeadingZeros (W# x# :: Word#
x#) = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
clz# Word#
x#))
countTrailingZeros :: Word -> Int
countTrailingZeros (W# x# :: Word#
x#) = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
ctz# Word#
x#))
instance Bits Integer where
.&. :: Integer -> Integer -> Integer
(.&.) = Integer -> Integer -> Integer
andInteger
.|. :: Integer -> Integer -> Integer
(.|.) = Integer -> Integer -> Integer
orInteger
xor :: Integer -> Integer -> Integer
xor = Integer -> Integer -> Integer
xorInteger
complement :: Integer -> Integer
complement = Integer -> Integer
complementInteger
shift :: Integer -> Int -> Integer
shift x :: Integer
x i :: Int
i@(I# i# :: Int#
i#) | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 0 = Integer -> Int# -> Integer
shiftLInteger Integer
x Int#
i#
| Bool
otherwise = Integer -> Int# -> Integer
shiftRInteger Integer
x (Int# -> Int#
negateInt# Int#
i#)
testBit :: Integer -> Int -> Bool
testBit x :: Integer
x (I# i :: Int#
i) = Integer -> Int# -> Bool
testBitInteger Integer
x Int#
i
zeroBits :: Integer
zeroBits = 0
bit :: Int -> Integer
bit (I# i# :: Int#
i#) = Int# -> Integer
bitInteger Int#
i#
popCount :: Integer -> Int
popCount x :: Integer
x = Int# -> Int
I# (Integer -> Int#
popCountInteger Integer
x)
rotate :: Integer -> Int -> Integer
rotate x :: Integer
x i :: Int
i = Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shift Integer
x Int
i
bitSizeMaybe :: Integer -> Maybe Int
bitSizeMaybe _ = Maybe Int
forall a. Maybe a
Nothing
bitSize :: Integer -> Int
bitSize _ = [Char] -> Int
forall a. [Char] -> a
errorWithoutStackTrace "Data.Bits.bitSize(Integer)"
isSigned :: Integer -> Bool
isSigned _ = Bool
True
instance Bits Natural where
.&. :: Natural -> Natural -> Natural
(.&.) = Natural -> Natural -> Natural
andNatural
.|. :: Natural -> Natural -> Natural
(.|.) = Natural -> Natural -> Natural
orNatural
xor :: Natural -> Natural -> Natural
xor = Natural -> Natural -> Natural
xorNatural
complement :: Natural -> Natural
complement _ = [Char] -> Natural
forall a. [Char] -> a
errorWithoutStackTrace
"Bits.complement: Natural complement undefined"
shift :: Natural -> Int -> Natural
shift x :: Natural
x i :: Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 0 = Natural -> Int -> Natural
shiftLNatural Natural
x Int
i
| Bool
otherwise = Natural -> Int -> Natural
shiftRNatural Natural
x (Int -> Int
forall a. Num a => a -> a
negate Int
i)
testBit :: Natural -> Int -> Bool
testBit x :: Natural
x i :: Int
i = Natural -> Int -> Bool
testBitNatural Natural
x Int
i
zeroBits :: Natural
zeroBits = Word# -> Natural
wordToNaturalBase 0##
clearBit :: Natural -> Int -> Natural
clearBit x :: Natural
x i :: Int
i = Natural
x Natural -> Natural -> Natural
forall a. Bits a => a -> a -> a
`xor` (Int -> Natural
forall a. Bits a => Int -> a
bit Int
i Natural -> Natural -> Natural
forall a. Bits a => a -> a -> a
.&. Natural
x)
bit :: Int -> Natural
bit (I# i# :: Int#
i#) = Int# -> Natural
bitNatural Int#
i#
popCount :: Natural -> Int
popCount x :: Natural
x = Natural -> Int
popCountNatural Natural
x
rotate :: Natural -> Int -> Natural
rotate x :: Natural
x i :: Int
i = Natural -> Int -> Natural
forall a. Bits a => a -> Int -> a
shift Natural
x Int
i
bitSizeMaybe :: Natural -> Maybe Int
bitSizeMaybe _ = Maybe Int
forall a. Maybe a
Nothing
bitSize :: Natural -> Int
bitSize _ = [Char] -> Int
forall a. [Char] -> a
errorWithoutStackTrace "Data.Bits.bitSize(Natural)"
isSigned :: Natural -> Bool
isSigned _ = Bool
False
toIntegralSized :: (Integral a, Integral b, Bits a, Bits b) => a -> Maybe b
toIntegralSized :: a -> Maybe b
toIntegralSized x :: a
x
| Bool -> (a -> Bool) -> Maybe a -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
True (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
x) Maybe a
yMinBound
, Bool -> (a -> Bool) -> Maybe a -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
True (a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<=) Maybe a
yMaxBound = b -> Maybe b
forall a. a -> Maybe a
Just b
y
| Bool
otherwise = Maybe b
forall a. Maybe a
Nothing
where
y :: b
y = a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x
xWidth :: Maybe Int
xWidth = a -> Maybe Int
forall a. Bits a => a -> Maybe Int
bitSizeMaybe a
x
yWidth :: Maybe Int
yWidth = b -> Maybe Int
forall a. Bits a => a -> Maybe Int
bitSizeMaybe b
y
yMinBound :: Maybe a
yMinBound
| a -> b -> Bool
forall a b. (Bits a, Bits b) => a -> b -> Bool
isBitSubType a
x b
y = Maybe a
forall a. Maybe a
Nothing
| a -> Bool
forall a. Bits a => a -> Bool
isSigned a
x, Bool -> Bool
not (b -> Bool
forall a. Bits a => a -> Bool
isSigned b
y) = a -> Maybe a
forall a. a -> Maybe a
Just 0
| a -> Bool
forall a. Bits a => a -> Bool
isSigned a
x, b -> Bool
forall a. Bits a => a -> Bool
isSigned b
y
, Just yW :: Int
yW <- Maybe Int
yWidth = a -> Maybe a
forall a. a -> Maybe a
Just (a -> a
forall a. Num a => a -> a
negate (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Int -> a
forall a. Bits a => Int -> a
bit (Int
yWInt -> Int -> Int
forall a. Num a => a -> a -> a
-1))
| Bool
otherwise = Maybe a
forall a. Maybe a
Nothing
yMaxBound :: Maybe a
yMaxBound
| a -> b -> Bool
forall a b. (Bits a, Bits b) => a -> b -> Bool
isBitSubType a
x b
y = Maybe a
forall a. Maybe a
Nothing
| a -> Bool
forall a. Bits a => a -> Bool
isSigned a
x, Bool -> Bool
not (b -> Bool
forall a. Bits a => a -> Bool
isSigned b
y)
, Just xW :: Int
xW <- Maybe Int
xWidth, Just yW :: Int
yW <- Maybe Int
yWidth
, Int
xW Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
yWInt -> Int -> Int
forall a. Num a => a -> a -> a
+1 = Maybe a
forall a. Maybe a
Nothing
| Just yW :: Int
yW <- Maybe Int
yWidth = if b -> Bool
forall a. Bits a => a -> Bool
isSigned b
y
then a -> Maybe a
forall a. a -> Maybe a
Just (Int -> a
forall a. Bits a => Int -> a
bit (Int
yWInt -> Int -> Int
forall a. Num a => a -> a -> a
-1)a -> a -> a
forall a. Num a => a -> a -> a
-1)
else a -> Maybe a
forall a. a -> Maybe a
Just (Int -> a
forall a. Bits a => Int -> a
bit Int
yWa -> a -> a
forall a. Num a => a -> a -> a
-1)
| Bool
otherwise = Maybe a
forall a. Maybe a
Nothing
{-# INLINABLE toIntegralSized #-}
isBitSubType :: (Bits a, Bits b) => a -> b -> Bool
isBitSubType :: a -> b -> Bool
isBitSubType x :: a
x y :: b
y
| Maybe Int
xWidth Maybe Int -> Maybe Int -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe Int
yWidth, Bool
xSigned Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
ySigned = Bool
True
| Bool
ySigned, Maybe Int
forall a. Maybe a
Nothing Maybe Int -> Maybe Int -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe Int
yWidth = Bool
True
| Bool -> Bool
not Bool
xSigned, Bool -> Bool
not Bool
ySigned, Maybe Int
forall a. Maybe a
Nothing Maybe Int -> Maybe Int -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe Int
yWidth = Bool
True
| Bool
xSigned Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
ySigned, Just xW :: Int
xW <- Maybe Int
xWidth, Just yW :: Int
yW <- Maybe Int
yWidth = Int
xW Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
yW
| Bool -> Bool
not Bool
xSigned, Bool
ySigned, Just xW :: Int
xW <- Maybe Int
xWidth, Just yW :: Int
yW <- Maybe Int
yWidth = Int
xW Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
yW
| Bool
otherwise = Bool
False
where
xWidth :: Maybe Int
xWidth = a -> Maybe Int
forall a. Bits a => a -> Maybe Int
bitSizeMaybe a
x
xSigned :: Bool
xSigned = a -> Bool
forall a. Bits a => a -> Bool
isSigned a
x
yWidth :: Maybe Int
yWidth = b -> Maybe Int
forall a. Bits a => a -> Maybe Int
bitSizeMaybe b
y
ySigned :: Bool
ySigned = b -> Bool
forall a. Bits a => a -> Bool
isSigned b
y
{-# INLINE isBitSubType #-}