{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ConstrainedClassMethods #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Haskus.Binary.Bits.Finite
( FiniteBits (..)
)
where
import Haskus.Utils.Types
import Haskus.Number.Word
import Haskus.Number.Int
import GHC.Exts
#include "MachDeps.h"
class FiniteBits a where
type BitSize a :: Nat
bitSize :: (Integral i, KnownNat (BitSize a)) => a -> i
bitSize _ = natValue @(BitSize a)
zeroBits :: a
oneBits :: a
oneBits = complement zeroBits
countLeadingZeros :: a -> Word
countTrailingZeros :: a -> Word
complement :: a -> a
instance FiniteBits Word where
type BitSize Word = WORD_SIZE_IN_BITS
zeroBits = 0
oneBits = maxBound
countLeadingZeros (W# x#) = W# (clz# x#)
countTrailingZeros (W# x#) = W# (ctz# x#)
complement (W# x#) = W# (x# `xor#` mb#)
where !(W# mb#) = maxBound
instance FiniteBits Word8 where
type BitSize Word8 = 8
zeroBits = 0
oneBits = maxBound
countLeadingZeros (W8# x#) = W# (clz8# x#)
countTrailingZeros (W8# x#) = W# (ctz8# x#)
complement (W8# x#) = W8# (x# `xor#` mb#)
where !(W8# mb#) = maxBound
instance FiniteBits Word16 where
type BitSize Word16 = 16
zeroBits = 0
oneBits = maxBound
countLeadingZeros (W16# x#) = W# (clz16# x#)
countTrailingZeros (W16# x#) = W# (ctz16# x#)
complement (W16# x#) = W16# (x# `xor#` mb#)
where !(W16# mb#) = maxBound
instance FiniteBits Word32 where
type BitSize Word32 = 32
zeroBits = 0
oneBits = maxBound
countLeadingZeros (W32# x#) = W# (clz32# x#)
countTrailingZeros (W32# x#) = W# (ctz32# x#)
complement (W32# x#) = W32# (x# `xor#` mb#)
where !(W32# mb#) = maxBound
instance FiniteBits Word64 where
type BitSize Word64 = 64
zeroBits = 0
oneBits = maxBound
countLeadingZeros (W64# x#) = W# (clz64# x#)
countTrailingZeros (W64# x#) = W# (ctz64# x#)
complement (W64# x#) = W64# (x# `xor#` mb#)
where !(W64# mb#) = maxBound
instance FiniteBits Int where
type BitSize Int = WORD_SIZE_IN_BITS
zeroBits = 0
oneBits = (-1)
countLeadingZeros (I# x#) = W# (clz# (int2Word# x#))
countTrailingZeros (I# x#) = W# (ctz# (int2Word# x#))
complement (I# x#) = I# (notI# x#)
instance FiniteBits Int8 where
type BitSize Int8 = 8
zeroBits = 0
oneBits = (-1)
countLeadingZeros (I8# x#) = W# (clz8# (int2Word# x#))
countTrailingZeros (I8# x#) = W# (ctz8# (int2Word# x#))
complement (I8# x#) = I8# (word2Int# (not# (int2Word# x#)))
instance FiniteBits Int16 where
type BitSize Int16 = 16
zeroBits = 0
oneBits = (-1)
countLeadingZeros (I16# x#) = W# (clz16# (int2Word# x#))
countTrailingZeros (I16# x#) = W# (ctz16# (int2Word# x#))
complement (I16# x#) = I16# (word2Int# (not# (int2Word# x#)))
instance FiniteBits Int32 where
type BitSize Int32 = 32
zeroBits = 0
oneBits = (-1)
countLeadingZeros (I32# x#) = W# (clz32# (int2Word# x#))
countTrailingZeros (I32# x#) = W# (ctz32# (int2Word# x#))
complement (I32# x#) = I32# (word2Int# (not# (int2Word# x#)))
instance FiniteBits Int64 where
type BitSize Int64 = 64
zeroBits = 0
oneBits = (-1)
countLeadingZeros (I64# x#) = W# (clz64# (int2Word# x#))
countTrailingZeros (I64# x#) = W# (ctz64# (int2Word# x#))
complement (I64# x#) = I64# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))