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

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

    From d65e7b1a11573d1c001ce8ab0ced55856e2e8c78 Mon Sep 17 00:00:00 2001
    From: Johan Tibell <johan.tibell@gmail.com>
    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 { \