Ticket #5431: 0001-Add-Data.Bits.popCount.patch

File 0001-Add-Data.Bits.popCount.patch, 6.6 KB (added by tibbe, 4 years ago)
  • Data/Bits.hs

    From d65e7b1a11573d1c001ce8ab0ced55856e2e8c78 Mon Sep 17 00:00:00 2001
    From: Johan Tibell <[email protected]>
    Date: Tue, 23 Aug 2011 14:58:13 +0200
    Subject: [PATCH 1/1] Add Data.Bits.popCount
    
    ---
     Data/Bits.hs       |   16 +++++++++++++++-
     Foreign/C/Types.hs |    3 ++-
     GHC/Int.hs         |    6 ++++++
     GHC/Word.hs        |    6 ++++++
     include/CTypes.h   |    3 ++-
     5 files changed, 31 insertions(+), 3 deletions(-)
    
    diff --git a/Data/Bits.hs b/Data/Bits.hs
    index a400c2f..10ad6e1 100644
    a b module Data.Bits ( 
    3333    bitSize,           -- :: a -> Int
    3434    isSigned,          -- :: a -> Bool
    3535    shiftL, shiftR,    -- :: a -> Int -> a
    36     rotateL, rotateR   -- :: a -> Int -> a
     36    rotateL, rotateR,  -- :: a -> Int -> a
     37    popCount           -- :: a -> Int
    3738  )
    3839
    3940  -- instance Bits Int
    class Num a => Bits a where 
    207208    {-# INLINE rotateR #-}
    208209    x `rotateR` i = x `rotate` (-i)
    209210
     211    {-| Return the number of set bits in the argument, known as the
     212        population count or the Hamming weight. -}
     213    popCount          :: a -> Int
     214    popCount = go 0
     215      where
     216        go !c 0 = c
     217        go c w = go (c+1) (w .&. w - 1)  -- clear the least significant bit set
     218    {- This implementation is intentionally naive.  Instances are
     219       expected to override it with something optimized for their
     220       size. -}
     221
    210222instance Bits Int where
    211223    {-# INLINE shift #-}
    212224
    instance Bits Int where 
    235247        !wsib = WORD_SIZE_IN_BITS#   {- work around preprocessor problem (??) -}
    236248    bitSize  _             = WORD_SIZE_IN_BITS
    237249
     250    popCount (I# x#) = I# (word2Int# (popCnt# (int2Word# x#)))
     251
    238252#else /* !__GLASGOW_HASKELL__ */
    239253
    240254#ifdef __HUGS__
  • Foreign/C/Types.hs

    diff --git a/Foreign/C/Types.hs b/Foreign/C/Types.hs
    index 9bb7642..ed4c5e1 100644
    a b instance Bits T where { \ 
    320320  complementBit (T x) n = T (complementBit x n) ; \
    321321  testBit       (T x) n = testBit x n ; \
    322322  bitSize       (T x)   = bitSize x ; \
    323   isSigned      (T x)   = isSigned x }
     323  isSigned      (T x)   = isSigned x ; \
     324  popCount      (T x)   = popCount x }
    324325
    325326INSTANCE_BITS(CChar)
    326327INSTANCE_BITS(CSChar)
  • GHC/Int.hs

    diff --git a/GHC/Int.hs b/GHC/Int.hs
    index b029ec8..65d42b4 100644
    a b instance Bits Int8 where 
    149149        !i'# = word2Int# (int2Word# i# `and#` int2Word# 7#)
    150150    bitSize  _                = 8
    151151    isSigned _                = True
     152    popCount (I8# x#)         = I# (word2Int# (popCnt8# (int2Word# x#)))
    152153
    153154{-# RULES
    154155"fromIntegral/Int8->Int8" fromIntegral = id :: Int8 -> Int8
    instance Bits Int16 where 
    293294        !i'# = word2Int# (int2Word# i# `and#` int2Word# 15#)
    294295    bitSize  _                 = 16
    295296    isSigned _                 = True
     297    popCount (I16# x#)         = I# (word2Int# (popCnt16# (int2Word# x#)))
    296298
    297299
    298300{-# RULES
    instance Bits Int32 where 
    443445        !i'# = word2Int# (int2Word# i# `and#` int2Word# 31#)
    444446    bitSize  _                 = 32
    445447    isSigned _                 = True
     448    popCount (I32# x#)         = I# (word2Int# (popCnt32# (int2Word# x#)))
    446449
    447450{-# RULES
    448451"fromIntegral/Word8->Int32"  fromIntegral = \(W8# x#) -> I32# (word2Int# x#)
    instance Bits Int64 where 
    626629        !i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
    627630    bitSize  _                 = 64
    628631    isSigned _                 = True
     632    popCount (I64# x#)         =
     633        I64# (word64ToInt64# (popCnt64# (int64ToWord64# x#)))
    629634
    630635-- give the 64-bit shift operations the same treatment as the 32-bit
    631636-- ones (see GHC.Base), namely we wrap them in tests to catch the
    instance Bits Int64 where 
    751756        !i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
    752757    bitSize  _                 = 64
    753758    isSigned _                 = True
     759    popCount (I64# x#)         = I# (word2Int# (popCnt64# (int2Word# x#)))
    754760
    755761{-# RULES
    756762"fromIntegral/a->Int64" fromIntegral = \x -> case fromIntegral x of I# x# -> I64# x#
  • GHC/Word.hs

    diff --git a/GHC/Word.hs b/GHC/Word.hs
    index 99ac8a7..2714898 100644
    a b instance Bits Word where 
    180180        !wsib = WORD_SIZE_IN_BITS#  {- work around preprocessor problem (??) -}
    181181    bitSize  _               = WORD_SIZE_IN_BITS
    182182    isSigned _               = False
     183    popCount (W# x#)         = I# (word2Int# (popCnt# x#))
    183184
    184185{-# RULES
    185186"fromIntegral/Int->Word"  fromIntegral = \(I# x#) -> W# (int2Word# x#)
    instance Bits Word8 where 
    286287        !i'# = word2Int# (int2Word# i# `and#` int2Word# 7#)
    287288    bitSize  _                = 8
    288289    isSigned _                = False
     290    popCount (W8# x#)         = I# (word2Int# (popCnt8# x#))
    289291
    290292{-# RULES
    291293"fromIntegral/Word8->Word8"   fromIntegral = id :: Word8 -> Word8
    instance Bits Word16 where 
    419421        !i'# = word2Int# (int2Word# i# `and#` int2Word# 15#)
    420422    bitSize  _                = 16
    421423    isSigned _                = False
     424    popCount (W16# x#)        = I# (word2Int# (popCnt16# x#))
    422425
    423426{-# RULES
    424427"fromIntegral/Word8->Word16"   fromIntegral = \(W8# x#) -> W16# x#
    instance Bits Word32 where 
    593596        !i'# = word2Int# (int2Word# i# `and#` int2Word# 31#)
    594597    bitSize  _                = 32
    595598    isSigned _                = False
     599    popCount (W32# x#)        = I# (word2Int# (popCnt32# x#))
    596600
    597601{-# RULES
    598602"fromIntegral/Word8->Word32"   fromIntegral = \(W8# x#) -> W32# x#
    instance Bits Word64 where 
    719723        !i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
    720724    bitSize  _                = 64
    721725    isSigned _                = False
     726    popCount (W64# x#)        = I# (word2Int# (popCnt64# x#))
    722727
    723728-- give the 64-bit shift operations the same treatment as the 32-bit
    724729-- ones (see GHC.Base), namely we wrap them in tests to catch the
    instance Bits Word64 where 
    825830        !i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
    826831    bitSize  _                = 64
    827832    isSigned _                = False
     833    popCount (W64# x#)        = I# (word2Int# (popCnt64# x#))
    828834
    829835{-# RULES
    830836"fromIntegral/a->Word64" fromIntegral = \x -> case fromIntegral x of W# x# -> W64# x#
  • include/CTypes.h

    diff --git a/include/CTypes.h b/include/CTypes.h
    index 3ca9f1c..345a434 100644
    a b instance Bits T where { \ 
    108108  complementBit (T x) n = T (complementBit x n) ; \
    109109  testBit       (T x) n = testBit x n ; \
    110110  bitSize       (T x)   = bitSize x ; \
    111   isSigned      (T x)   = isSigned x }
     111  isSigned      (T x)   = isSigned x ; \
     112  popCount      (T x)   = popCount x }
    112113
    113114#define INSTANCE_FRACTIONAL(T) \
    114115instance Fractional T where { \