hw-bits-0.0.0.1: src/HaskellWorks/Data/Bits/BitWise.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
-- |
-- Copyright: 2016 John Ky
-- License: MIT
--
-- Succinct operations.
module HaskellWorks.Data.Bits.BitWise
( -- * Bit map
BitWise(..)
, Shift(..)
, TestBit(..)
) where
import qualified Data.Bits as B
import qualified Data.Vector as DV
import qualified Data.Vector.Storable as DVS
import Data.Word
import HaskellWorks.Data.Bits.BitLength
import HaskellWorks.Data.Positioning
import HaskellWorks.Data.Vector.VectorLike as VL
import Prelude as P
-- We pervasively use precedence to avoid excessive parentheses, and we use
-- the same precedence conventions of the C programming language: arithmetic
-- operators come first, ordered in the standard way, followed by shifts,
-- followed by logical operators; ⊕ sits between | and &.
infixl 9 .?.
infixl 8 .<., .>.
infixl 7 .&. -- Bitwise AND. eg. ∧
infixl 6 .^. -- Bitwise XOR. eg. ⊕
infixl 5 .|. -- Bitwise OR. eg. ∨
class Shift a where
(.<.) :: a -> Count -> a
(.>.) :: a -> Count -> a
class TestBit a where
(.?.) :: a -> Position -> Bool
class BitWise a where
(.&.) :: a -> a -> a
(.|.) :: a -> a -> a
(.^.) :: a -> a -> a
comp :: a -> a
all0s :: a
all1s :: a
--------------------------------------------------------------------------------
-- Instances
instance TestBit Bool where
(.?.) w 0 = w
(.?.) _ _ = error "Invalid bit index"
{-# INLINABLE (.?.) #-}
instance TestBit [Bool] where
(.?.) v p = v !! fromIntegral p
{-# INLINABLE (.?.) #-}
instance TestBit Word8 where
(.?.) w n = B.testBit w (fromIntegral (getPosition n))
{-# INLINABLE (.?.) #-}
instance TestBit Word16 where
(.?.) w n = B.testBit w (fromIntegral (getPosition n))
{-# INLINABLE (.?.) #-}
instance TestBit Word32 where
(.?.) w n = B.testBit w (fromIntegral (getPosition n))
{-# INLINABLE (.?.) #-}
instance TestBit Word64 where
(.?.) w n = B.testBit w (fromIntegral (getPosition n))
{-# INLINABLE (.?.) #-}
instance TestBit (DV.Vector Word8) where
(.?.) v n = let (q, r) = n `quotRem` elemBitEnd v in (v !!! q) .?. r
{-# INLINABLE (.?.) #-}
instance TestBit (DV.Vector Word16) where
(.?.) v n = let (q, r) = n `quotRem` elemBitEnd v in (v !!! q) .?. r
{-# INLINABLE (.?.) #-}
instance TestBit (DV.Vector Word32) where
(.?.) v n = let (q, r) = n `quotRem` elemBitEnd v in (v !!! q) .?. r
{-# INLINABLE (.?.) #-}
instance TestBit (DV.Vector Word64) where
(.?.) v n = let (q, r) = n `quotRem` elemBitEnd v in (v !!! q) .?. r
{-# INLINABLE (.?.) #-}
instance TestBit (DVS.Vector Word8) where
(.?.) v n = let (q, r) = n `quotRem` elemBitEnd v in (v !!! q) .?. r
{-# INLINABLE (.?.) #-}
instance TestBit (DVS.Vector Word16) where
(.?.) v n = let (q, r) = n `quotRem` elemBitEnd v in (v !!! q) .?. r
{-# INLINABLE (.?.) #-}
instance TestBit (DVS.Vector Word32) where
(.?.) v n = let (q, r) = n `quotRem` elemBitEnd v in (v !!! q) .?. r
{-# INLINABLE (.?.) #-}
instance TestBit (DVS.Vector Word64) where
(.?.) v n = let (q, r) = n `quotRem` elemBitEnd v in (v !!! q) .?. r
{-# INLINABLE (.?.) #-}
instance BitWise Word8 where
(.&.) = (B..&.)
{-# INLINABLE (.&.) #-}
(.|.) = (B..|.)
{-# INLINABLE (.|.) #-}
(.^.) = B.xor
{-# INLINABLE (.^.) #-}
comp = B.complement
{-# INLINABLE comp #-}
all0s = 0
{-# INLINABLE all0s #-}
all1s = 0
{-# INLINABLE all1s #-}
instance BitWise Word16 where
(.&.) = (B..&.)
{-# INLINABLE (.&.) #-}
(.|.) = (B..|.)
{-# INLINABLE (.|.) #-}
(.^.) = B.xor
{-# INLINABLE (.^.) #-}
comp = B.complement
{-# INLINABLE comp #-}
all0s = 0
{-# INLINABLE all0s #-}
all1s = 0
{-# INLINABLE all1s #-}
instance BitWise Word32 where
(.&.) = (B..&.)
{-# INLINABLE (.&.) #-}
(.|.) = (B..|.)
{-# INLINABLE (.|.) #-}
(.^.) = B.xor
{-# INLINABLE (.^.) #-}
comp = B.complement
{-# INLINABLE comp #-}
all0s = 0
{-# INLINABLE all0s #-}
all1s = 0
{-# INLINABLE all1s #-}
instance BitWise Word64 where
(.&.) = (B..&.)
{-# INLINABLE (.&.) #-}
(.|.) = (B..|.)
{-# INLINABLE (.|.) #-}
(.^.) = B.xor
{-# INLINABLE (.^.) #-}
comp = B.complement
{-# INLINABLE comp #-}
all0s = 0
{-# INLINABLE all0s #-}
all1s = 0
{-# INLINABLE all1s #-}
instance Shift Word8 where
(.<.) w n = B.shiftL w (fromIntegral n)
{-# INLINABLE (.<.) #-}
(.>.) w n = B.shiftR w (fromIntegral n)
{-# INLINABLE (.>.) #-}
instance Shift Word16 where
(.<.) w n = B.shiftL w (fromIntegral n)
{-# INLINABLE (.<.) #-}
(.>.) w n = B.shiftR w (fromIntegral n)
{-# INLINABLE (.>.) #-}
instance Shift Word32 where
(.<.) w n = B.shiftL w (fromIntegral n)
{-# INLINABLE (.<.) #-}
(.>.) w n = B.shiftR w (fromIntegral n)
{-# INLINABLE (.>.) #-}
instance Shift Word64 where
(.<.) w n = B.shiftL w (fromIntegral n)
{-# INLINABLE (.<.) #-}
(.>.) w n = B.shiftR w (fromIntegral n)
{-# INLINABLE (.>.) #-}