{-# LANGUAGE FlexibleInstances #-} -- | -- Copyright: 2016 John Ky -- License: MIT -- -- Succinct operations. module HaskellWorks.Data.Bits.PopCount.PopCount1 ( PopCount1(..) ) where import qualified Data.Bits as DB import qualified Data.Vector as DV import qualified Data.Vector.Storable as DVS import Data.Word import HaskellWorks.Data.Bits.BitWise import HaskellWorks.Data.Bits.Types.Broadword import HaskellWorks.Data.Bits.Types.Builtin import HaskellWorks.Data.Positioning import Prelude as P type FastWord a = Builtin a fastWord :: a -> FastWord a fastWord = Builtin {-# INLINE fastWord #-} -- | The number of one bits in the value. class PopCount1 v where popCount1 :: v -> Count instance PopCount1 Bool where popCount1 True = 1 popCount1 False = 0 {-# INLINE popCount1 #-} instance PopCount1 (Broadword Word8) where popCount1 (Broadword x0) = Count (fromIntegral x3) where x1 = x0 - ((x0 .&. 0xaa) .>. 1) x2 = (x1 .&. 0x33) + ((x1 .>. 2) .&. 0x33) x3 = (x2 + (x2 .>. 4)) .&. 0x0f {-# INLINE popCount1 #-} instance PopCount1 (Broadword Word16) where popCount1 (Broadword x0) = Count (fromIntegral ((x3 * 0x0101) .>. 8)) where x1 = x0 - ((x0 .&. 0xaaaa) .>. 1) x2 = (x1 .&. 0x3333) + ((x1 .>. 2) .&. 0x3333) x3 = (x2 + (x2 .>. 4)) .&. 0x0f0f {-# INLINE popCount1 #-} instance PopCount1 (Broadword Word32) where popCount1 (Broadword x0) = Count (fromIntegral ((x3 * 0x01010101) .>. 24)) where x1 = x0 - ((x0 .&. 0xaaaaaaaa) .>. 1) x2 = (x1 .&. 0x33333333) + ((x1 .>. 2) .&. 0x33333333) x3 = (x2 + (x2 .>. 4)) .&. 0x0f0f0f0f {-# INLINE popCount1 #-} instance PopCount1 (Broadword Word64) where popCount1 (Broadword x0) = Count ((x3 * 0x0101010101010101) .>. 56) where x1 = x0 - ((x0 .&. 0xaaaaaaaaaaaaaaaa) .>. 1) x2 = (x1 .&. 0x3333333333333333) + ((x1 .>. 2) .&. 0x3333333333333333) x3 = (x2 + (x2 .>. 4)) .&. 0x0f0f0f0f0f0f0f0f {-# INLINE popCount1 #-} instance PopCount1 (Builtin Word8) where popCount1 (Builtin x0) = fromIntegral (DB.popCount x0) {-# INLINE popCount1 #-} instance PopCount1 (Builtin Word16) where popCount1 (Builtin x0) = fromIntegral (DB.popCount x0) {-# INLINE popCount1 #-} instance PopCount1 (Builtin Word32) where popCount1 (Builtin x0) = fromIntegral (DB.popCount x0) {-# INLINE popCount1 #-} instance PopCount1 (Builtin Word64) where popCount1 (Builtin x0) = fromIntegral (DB.popCount x0) {-# INLINE popCount1 #-} instance PopCount1 Word8 where popCount1 = fromIntegral . popCount1 . fastWord {-# INLINE popCount1 #-} instance PopCount1 Word16 where popCount1 = fromIntegral . popCount1 . fastWord {-# INLINE popCount1 #-} instance PopCount1 Word32 where popCount1 = fromIntegral . popCount1 . fastWord {-# INLINE popCount1 #-} instance PopCount1 Word64 where popCount1 = fromIntegral . popCount1 . fastWord {-# INLINE popCount1 #-} instance PopCount1 a => PopCount1 [a] where popCount1 = P.sum . fmap popCount1 {-# INLINE popCount1 #-} instance PopCount1 a => PopCount1 (DV.Vector a) where popCount1 = DV.foldl (\c -> (c +) . popCount1) 0 {-# INLINE popCount1 #-} instance (PopCount1 a, DVS.Storable a) => PopCount1 (DVS.Vector a) where popCount1 = DVS.foldl (\c -> (c +) . popCount1) 0 {-# INLINE popCount1 #-}