bv-little-1.0.0: test/Data/BitVector/Visual.hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Data.BitVector.Visual
( VisualBitVector()
, VisualBitVectorSmall()
, HasBitVector(..)
)where
import Control.DeepSeq
import Data.Bits
import Data.BitVector.LittleEndian
import Data.Data
import Data.Functor.Compose
import Data.Functor.Identity
import Data.Hashable
import Data.List.NonEmpty (NonEmpty(..))
import Data.Monoid ()
import Data.MonoTraversable
import Data.Semigroup
import GHC.Generics
import GHC.Natural
import Test.QuickCheck hiding (generate)
import Test.SmallCheck.Series
newtype VisualBitVector = VBV BitVector
deriving (Data, Eq, Ord, Generic, NFData, Typeable)
newtype VisualBitVectorSmall = VBVS BitVector
deriving (Data, Eq, Ord, Generic, NFData, Typeable)
class HasBitVector a where
getBitVector :: a -> BitVector
instance HasBitVector BitVector where
getBitVector = id
instance HasBitVector VisualBitVector where
getBitVector (VBV bv) = bv
instance HasBitVector VisualBitVectorSmall where
getBitVector (VBVS bv) = bv
instance CoArbitrary VisualBitVector where
coarbitrary = coarbitraryEnum
instance CoArbitrary VisualBitVectorSmall where
coarbitrary = coarbitraryEnum
{-
instance Monad m => CoSerial m VisualBitVector where
coseries x = genericCoseries x
-}
instance Bounded VisualBitVector where
minBound = VBV $ fromNumber 0 0
maxBound = VBV $ fromNumber 8 (bit 8 - 1 :: Natural)
instance Bounded VisualBitVectorSmall where
minBound = VBVS $ fromNumber 0 0
maxBound = VBVS $ fromNumber 3 (bit 3 - 1 :: Natural)
instance Enum VisualBitVector where
toEnum n = go $ n `mod` (bit 9 - 1)
where
go i = VBV $ fromNumber (toEnum dim) num
where
(num, off, dim) = getEnumContext i
fromEnum (VBV bv) =
case dim of
0 -> 0
n -> num + 2^dim - 1
where
num = toUnsignedNumber bv
dim = dimension bv
instance Enum VisualBitVectorSmall where
toEnum n = go $ n `mod` (bit 4 - 1)
where
go i = VBVS $ fromNumber (toEnum dim) num
where
(num, off, dim) = getEnumContext i
fromEnum (VBVS bv) =
case dim of
0 -> 0
n -> num + 2^dim - 1
where
num = toUnsignedNumber bv
dim = dimension bv
instance Monad m => Serial m VisualBitVector where
series = generate $ const allVBVs
where
allVBVs = toEnum <$> [0 .. fromEnum (maxBound :: VisualBitVector)]
instance Monad m => Serial m VisualBitVectorSmall where
series = generate $ const allVBVs
where
allVBVs = toEnum <$> [0 .. fromEnum (maxBound :: VisualBitVectorSmall)]
instance Show VisualBitVector where
show (VBV bv) = mconcat
[ "["
, show $ dimension bv
, "]"
, "<"
, foldMap (\b -> if b then "1" else "0") $ toBits bv
, ">"
]
instance Show VisualBitVectorSmall where
show (VBVS bv) = mconcat
[ "["
, show $ dimension bv
, "]"
, "<"
, foldMap (\b -> if b then "1" else "0") $ toBits bv
, ">"
]
getEnumContext i = (num, off, dim)
where
num = i - off
off = bit dim - 1
dim = logBase2 $ i + 1
logBase2 x = finiteBitSize x - 1 - countLeadingZeros x