{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
module Grisette.Internal.Core.Data.Class.SymRotate
( SymRotate (..),
DefaultFiniteBitsSymRotate (..),
)
where
import Data.Bits (Bits (isSigned, rotate), FiniteBits (finiteBitSize))
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Word (Word16, Word32, Word64, Word8)
class (Bits a) => SymRotate a where
symRotate :: a -> a -> a
symRotateNegated :: a -> a -> a
instance SymRotate Int where
symRotate :: Int -> Int -> Int
symRotate = Int -> Int -> Int
forall a. Bits a => a -> Int -> a
rotate
symRotateNegated :: Int -> Int -> Int
symRotateNegated Int
a Int
s
| Int
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
forall a. Bounded a => a
minBound = Int -> Int -> Int
forall a. Bits a => a -> Int -> a
rotate Int
a (-Int
s)
| Bool
otherwise = Int -> Int -> Int
forall a. Bits a => a -> Int -> a
rotate Int
a (-(Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Int
s))
newtype DefaultFiniteBitsSymRotate a = DefaultFiniteBitsSymRotate
{ forall a. DefaultFiniteBitsSymRotate a -> a
unDefaultFiniteBitsSymRotate :: a
}
deriving newtype (DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> Bool
(DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> Bool)
-> (DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> Bool)
-> Eq (DefaultFiniteBitsSymRotate a)
forall a.
Eq a =>
DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a.
Eq a =>
DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> Bool
== :: DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> Bool
$c/= :: forall a.
Eq a =>
DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> Bool
/= :: DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> Bool
Eq, Eq (DefaultFiniteBitsSymRotate a)
DefaultFiniteBitsSymRotate a
Eq (DefaultFiniteBitsSymRotate a) =>
(DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> Int -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> Int -> DefaultFiniteBitsSymRotate a)
-> DefaultFiniteBitsSymRotate a
-> (Int -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> Int -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> Int -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> Int -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a -> Int -> Bool)
-> (DefaultFiniteBitsSymRotate a -> Maybe Int)
-> (DefaultFiniteBitsSymRotate a -> Int)
-> (DefaultFiniteBitsSymRotate a -> Bool)
-> (DefaultFiniteBitsSymRotate a
-> Int -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> Int -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> Int -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> Int -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> Int -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a
-> Int -> DefaultFiniteBitsSymRotate a)
-> (DefaultFiniteBitsSymRotate a -> Int)
-> Bits (DefaultFiniteBitsSymRotate a)
Int -> DefaultFiniteBitsSymRotate a
DefaultFiniteBitsSymRotate a -> Bool
DefaultFiniteBitsSymRotate a -> Int
DefaultFiniteBitsSymRotate a -> Maybe Int
DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
DefaultFiniteBitsSymRotate a -> Int -> Bool
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
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 a. Bits a => Eq (DefaultFiniteBitsSymRotate a)
forall a. Bits a => DefaultFiniteBitsSymRotate a
forall a. Bits a => Int -> DefaultFiniteBitsSymRotate a
forall a. Bits a => DefaultFiniteBitsSymRotate a -> Bool
forall a. Bits a => DefaultFiniteBitsSymRotate a -> Int
forall a. Bits a => DefaultFiniteBitsSymRotate a -> Maybe Int
forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
forall a. Bits a => DefaultFiniteBitsSymRotate a -> Int -> Bool
forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
forall a.
Bits a =>
DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
$c.&. :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
.&. :: DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
$c.|. :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
.|. :: DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
$cxor :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
xor :: DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
$ccomplement :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
complement :: DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
$cshift :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
shift :: DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
$crotate :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
rotate :: DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
$czeroBits :: forall a. Bits a => DefaultFiniteBitsSymRotate a
zeroBits :: DefaultFiniteBitsSymRotate a
$cbit :: forall a. Bits a => Int -> DefaultFiniteBitsSymRotate a
bit :: Int -> DefaultFiniteBitsSymRotate a
$csetBit :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
setBit :: DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
$cclearBit :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
clearBit :: DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
$ccomplementBit :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
complementBit :: DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
$ctestBit :: forall a. Bits a => DefaultFiniteBitsSymRotate a -> Int -> Bool
testBit :: DefaultFiniteBitsSymRotate a -> Int -> Bool
$cbitSizeMaybe :: forall a. Bits a => DefaultFiniteBitsSymRotate a -> Maybe Int
bitSizeMaybe :: DefaultFiniteBitsSymRotate a -> Maybe Int
$cbitSize :: forall a. Bits a => DefaultFiniteBitsSymRotate a -> Int
bitSize :: DefaultFiniteBitsSymRotate a -> Int
$cisSigned :: forall a. Bits a => DefaultFiniteBitsSymRotate a -> Bool
isSigned :: DefaultFiniteBitsSymRotate a -> Bool
$cshiftL :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
shiftL :: DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
$cunsafeShiftL :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
unsafeShiftL :: DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
$cshiftR :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
shiftR :: DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
$cunsafeShiftR :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
unsafeShiftR :: DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
$crotateL :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
rotateL :: DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
$crotateR :: forall a.
Bits a =>
DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
rotateR :: DefaultFiniteBitsSymRotate a -> Int -> DefaultFiniteBitsSymRotate a
$cpopCount :: forall a. Bits a => DefaultFiniteBitsSymRotate a -> Int
popCount :: DefaultFiniteBitsSymRotate a -> Int
Bits)
instance
(Integral a, FiniteBits a) =>
SymRotate (DefaultFiniteBitsSymRotate a)
where
symRotate :: DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
symRotate (DefaultFiniteBitsSymRotate a
a) (DefaultFiniteBitsSymRotate a
s)
| a -> Bool
forall a. Bits a => a -> Bool
isSigned a
a = a -> DefaultFiniteBitsSymRotate a
forall a. a -> DefaultFiniteBitsSymRotate a
DefaultFiniteBitsSymRotate (a -> DefaultFiniteBitsSymRotate a)
-> a -> DefaultFiniteBitsSymRotate a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
symRotateSigned a
a a
s
| Bool
otherwise = a -> DefaultFiniteBitsSymRotate a
forall a. a -> DefaultFiniteBitsSymRotate a
DefaultFiniteBitsSymRotate (a -> DefaultFiniteBitsSymRotate a)
-> a -> DefaultFiniteBitsSymRotate a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
symRotateUnsigned a
a a
s
where
symRotateUnsigned :: a -> a -> a
symRotateUnsigned :: a -> a -> a
symRotateUnsigned a
a a
s =
a -> Int -> a
forall a. Bits a => a -> Int -> a
rotate a
a (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
s a -> a -> a
forall a. Integral a => a -> a -> a
`mod` Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize a
a)))
symRotateSigned :: a -> a -> a
symRotateSigned :: a -> a -> a
symRotateSigned a
a a
s
| a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize a
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = a
a
| a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize a
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 = a -> Int -> a
forall a. Bits a => a -> Int -> a
rotate a
a (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
s)
| Bool
otherwise =
a -> Int -> a
forall a. Bits a => a -> Int -> a
rotate a
a (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
s a -> a -> a
forall a. Integral a => a -> a -> a
`mod` Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize a
a)))
symRotateNegated :: DefaultFiniteBitsSymRotate a
-> DefaultFiniteBitsSymRotate a -> DefaultFiniteBitsSymRotate a
symRotateNegated (DefaultFiniteBitsSymRotate a
a) (DefaultFiniteBitsSymRotate a
s)
| a -> Bool
forall a. Bits a => a -> Bool
isSigned a
a = a -> DefaultFiniteBitsSymRotate a
forall a. a -> DefaultFiniteBitsSymRotate a
DefaultFiniteBitsSymRotate (a -> DefaultFiniteBitsSymRotate a)
-> a -> DefaultFiniteBitsSymRotate a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
symRotateSigned a
a a
s
| Bool
otherwise = a -> DefaultFiniteBitsSymRotate a
forall a. a -> DefaultFiniteBitsSymRotate a
DefaultFiniteBitsSymRotate (a -> DefaultFiniteBitsSymRotate a)
-> a -> DefaultFiniteBitsSymRotate a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
symRotateUnsigned a
a a
s
where
bs :: a
bs = Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize a
a)
smodbs :: a
smodbs = a
s a -> a -> a
forall a. Integral a => a -> a -> a
`mod` a
bs
symRotateUnsigned :: a -> a -> a
symRotateUnsigned :: a -> a -> a
symRotateUnsigned a
a a
_ =
a -> Int -> a
forall a. Bits a => a -> Int -> a
rotate a
a (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
bs a -> a -> a
forall a. Num a => a -> a -> a
- a
smodbs))
symRotateSigned :: a -> a -> a
symRotateSigned :: a -> a -> a
symRotateSigned a
a a
s
| a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize a
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = a
a
| a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize a
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 = a -> Int -> a
forall a. Bits a => a -> Int -> a
rotate a
a (-a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
s)
| Bool
otherwise =
if a
smodbs a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0
then a -> Int -> a
forall a. Bits a => a -> Int -> a
rotate a
a (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
bs a -> a -> a
forall a. Num a => a -> a -> a
- a
smodbs))
else a -> Int -> a
forall a. Bits a => a -> Int -> a
rotate a
a (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (-a
smodbs))
deriving via (DefaultFiniteBitsSymRotate Int8) instance SymRotate Int8
deriving via (DefaultFiniteBitsSymRotate Int16) instance SymRotate Int16
deriving via (DefaultFiniteBitsSymRotate Int32) instance SymRotate Int32
deriving via (DefaultFiniteBitsSymRotate Int64) instance SymRotate Int64
deriving via (DefaultFiniteBitsSymRotate Word8) instance SymRotate Word8
deriving via (DefaultFiniteBitsSymRotate Word16) instance SymRotate Word16
deriving via (DefaultFiniteBitsSymRotate Word32) instance SymRotate Word32
deriving via (DefaultFiniteBitsSymRotate Word64) instance SymRotate Word64
deriving via (DefaultFiniteBitsSymRotate Word) instance SymRotate Word