Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Remove Num superclass of Bits Add and export bitDefault, testBitDefau…

…lt and popCountDefault from Data.Bits.
  • Loading branch information...
commit f99cee0118c6bbcd0283ea795a3bb6ff6090b5b5 1 parent 7c1dff5
@basvandijk basvandijk authored igfoo committed
Showing with 90 additions and 14 deletions.
  1. +43 −13 Data/Bits.hs
  2. +20 −1 GHC/Int.hs
  3. +24 −0 GHC/Word.hs
  4. +3 −0  NHC/SizedTypes.hs
View
56 Data/Bits.hs
@@ -36,8 +36,11 @@ module Data.Bits (
unsafeShiftL, unsafeShiftR, -- :: a -> Int -> a
rotateL, rotateR, -- :: a -> Int -> a
popCount -- :: a -> Int
- )
+ ),
+ bitDefault,
+ testBitDefault,
+ popCountDefault
-- instance Bits Int
-- instance Bits Integer
) where
@@ -74,7 +77,7 @@ Minimal complete definition: '.&.', '.|.', 'xor', 'complement',
('shift' or ('shiftL' and 'shiftR')), ('rotate' or ('rotateL' and 'rotateR')),
'bitSize' and 'isSigned'.
-}
-class (Eq a, Num a) => Bits a where
+class Eq a => Bits a where
-- | Bitwise \"and\"
(.&.) :: a -> a -> a
@@ -155,16 +158,12 @@ class (Eq a, Num a) => Bits a where
value of the argument is ignored -}
isSigned :: a -> Bool
- {-# INLINE bit #-}
{-# INLINE setBit #-}
{-# INLINE clearBit #-}
{-# INLINE complementBit #-}
- {-# INLINE testBit #-}
- bit i = 1 `shiftL` i
x `setBit` i = x .|. bit i
x `clearBit` i = x .&. complement (bit i)
x `complementBit` i = x `xor` bit i
- x `testBit` i = (x .&. bit i) /= 0
{-| Shift the argument left by the specified number of bits
(which must be non-negative).
@@ -235,18 +234,41 @@ class (Eq a, Num a) => Bits a where
{-| Return the number of set bits in the argument. This number is
known as the population count or the Hamming weight. -}
popCount :: a -> Int
- popCount = go 0
- where
- go !c 0 = c
- go c w = go (c+1) (w .&. w - 1) -- clear the least significant bit set
- {- This implementation is intentionally naive. Instances are
- expected to override it with something optimized for their
- size. -}
+
+-- | Default implementation for 'bit'.
+--
+-- Note that: @bitDefault i = 1 `shiftL` i@
+bitDefault :: (Bits a, Num a) => Int -> a
+bitDefault i = 1 `shiftL` i
+{-# INLINE bitDefault #-}
+
+-- | Default implementation for 'testBit'.
+--
+-- Note that: @testBitDefault x i = (x .&. bit i) /= 0@
+testBitDefault :: (Bits a, Num a) => a -> Int -> Bool
+testBitDefault x i = (x .&. bit i) /= 0
+{-# INLINE testBitDefault #-}
+
+-- | Default implementation for 'popCount'.
+--
+-- This implementation is intentionally naive. Instances are expected to provide
+-- an optimized implementation for their size.
+popCountDefault :: (Bits a, Num a) => a -> Int
+popCountDefault = go 0
+ where
+ go !c 0 = c
+ go c w = go (c+1) (w .&. w - 1) -- clear the least significant
instance Bits Int where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
#ifdef __GLASGOW_HASKELL__
+ bit = bitDefault
+
+ testBit = testBitDefault
+
(I# x#) .&. (I# y#) = I# (word2Int# (int2Word# x# `and#` int2Word# y#))
(I# x#) .|. (I# y#) = I# (word2Int# (int2Word# x# `or#` int2Word# y#))
@@ -277,6 +299,8 @@ instance Bits Int where
#else /* !__GLASGOW_HASKELL__ */
+ popCount = popCountDefault
+
#ifdef __HUGS__
(.&.) = primAndInt
(.|.) = primOrInt
@@ -293,6 +317,8 @@ instance Bits Int where
complement = nhc_primIntCompl
shiftL = nhc_primIntLsh
shiftR = nhc_primIntRsh
+ bit = bitDefault
+ testBit = testBitDefault
bitSize _ = 32
#endif /* __NHC__ */
@@ -345,6 +371,10 @@ instance Bits Integer where
| otherwise = x `div` 2^(-i)
#endif
+ bit = bitDefault
+ testBit = testBitDefault
+ popCount = popCountDefault
+
rotate x i = shift x i -- since an Integer never wraps around
bitSize _ = error "Data.Bits.bitSize(Integer)"
View
21 GHC/Int.hs
@@ -129,6 +129,8 @@ instance Read Int8 where
instance Bits Int8 where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
(I8# x#) .&. (I8# y#) = I8# (word2Int# (int2Word# x# `and#` int2Word# y#))
(I8# x#) .|. (I8# y#) = I8# (word2Int# (int2Word# x# `or#` int2Word# y#))
@@ -153,6 +155,8 @@ instance Bits Int8 where
bitSize _ = 8
isSigned _ = True
popCount (I8# x#) = I# (word2Int# (popCnt8# (int2Word# x#)))
+ bit = bitDefault
+ testBit = testBitDefault
{-# RULES
"fromIntegral/Int8->Int8" fromIntegral = id :: Int8 -> Int8
@@ -276,6 +280,8 @@ instance Read Int16 where
instance Bits Int16 where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
(I16# x#) .&. (I16# y#) = I16# (word2Int# (int2Word# x# `and#` int2Word# y#))
(I16# x#) .|. (I16# y#) = I16# (word2Int# (int2Word# x# `or#` int2Word# y#))
@@ -300,7 +306,8 @@ instance Bits Int16 where
bitSize _ = 16
isSigned _ = True
popCount (I16# x#) = I# (word2Int# (popCnt16# (int2Word# x#)))
-
+ bit = bitDefault
+ testBit = testBitDefault
{-# RULES
"fromIntegral/Word8->Int16" fromIntegral = \(W8# x#) -> I16# (word2Int# x#)
@@ -429,6 +436,8 @@ instance Read Int32 where
instance Bits Int32 where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
(I32# x#) .&. (I32# y#) = I32# (word2Int# (int2Word# x# `and#` int2Word# y#))
(I32# x#) .|. (I32# y#) = I32# (word2Int# (int2Word# x# `or#` int2Word# y#))
@@ -454,6 +463,8 @@ instance Bits Int32 where
bitSize _ = 32
isSigned _ = True
popCount (I32# x#) = I# (word2Int# (popCnt32# (int2Word# x#)))
+ bit = bitDefault
+ testBit = testBitDefault
{-# RULES
"fromIntegral/Word8->Int32" fromIntegral = \(W8# x#) -> I32# (word2Int# x#)
@@ -616,6 +627,8 @@ instance Read Int64 where
instance Bits Int64 where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
(I64# x#) .&. (I64# y#) = I64# (word64ToInt64# (int64ToWord64# x# `and64#` int64ToWord64# y#))
(I64# x#) .|. (I64# y#) = I64# (word64ToInt64# (int64ToWord64# x# `or64#` int64ToWord64# y#))
@@ -641,6 +654,8 @@ instance Bits Int64 where
isSigned _ = True
popCount (I64# x#) =
I# (word2Int# (popCnt64# (int64ToWord64# x#)))
+ bit = bitDefault
+ testBit = testBitDefault
-- give the 64-bit shift operations the same treatment as the 32-bit
-- ones (see GHC.Base), namely we wrap them in tests to catch the
@@ -745,6 +760,8 @@ instance Read Int64 where
instance Bits Int64 where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
(I64# x#) .&. (I64# y#) = I64# (word2Int# (int2Word# x# `and#` int2Word# y#))
(I64# x#) .|. (I64# y#) = I64# (word2Int# (int2Word# x# `or#` int2Word# y#))
@@ -769,6 +786,8 @@ instance Bits Int64 where
bitSize _ = 64
isSigned _ = True
popCount (I64# x#) = I# (word2Int# (popCnt64# (int2Word# x#)))
+ bit = bitDefault
+ testBit = testBitDefault
{-# RULES
"fromIntegral/a->Int64" fromIntegral = \x -> case fromIntegral x of I# x# -> I64# x#
View
24 GHC/Word.hs
@@ -137,6 +137,8 @@ instance Read Word where
instance Bits Word where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
(W# x#) .&. (W# y#) = W# (x# `and#` y#)
(W# x#) .|. (W# y#) = W# (x# `or#` y#)
@@ -159,6 +161,8 @@ instance Bits Word where
bitSize _ = WORD_SIZE_IN_BITS
isSigned _ = False
popCount (W# x#) = I# (word2Int# (popCnt# x#))
+ bit = bitDefault
+ testBit = testBitDefault
{-# RULES
"fromIntegral/Int->Word" fromIntegral = \(I# x#) -> W# (int2Word# x#)
@@ -246,6 +250,8 @@ instance Read Word8 where
instance Bits Word8 where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
(W8# x#) .&. (W8# y#) = W8# (x# `and#` y#)
(W8# x#) .|. (W8# y#) = W8# (x# `or#` y#)
@@ -269,6 +275,8 @@ instance Bits Word8 where
bitSize _ = 8
isSigned _ = False
popCount (W8# x#) = I# (word2Int# (popCnt8# x#))
+ bit = bitDefault
+ testBit = testBitDefault
{-# RULES
"fromIntegral/Word8->Word8" fromIntegral = id :: Word8 -> Word8
@@ -383,6 +391,8 @@ instance Read Word16 where
instance Bits Word16 where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
(W16# x#) .&. (W16# y#) = W16# (x# `and#` y#)
(W16# x#) .|. (W16# y#) = W16# (x# `or#` y#)
@@ -406,6 +416,8 @@ instance Bits Word16 where
bitSize _ = 16
isSigned _ = False
popCount (W16# x#) = I# (word2Int# (popCnt16# x#))
+ bit = bitDefault
+ testBit = testBitDefault
{-# RULES
"fromIntegral/Word8->Word16" fromIntegral = \(W8# x#) -> W16# x#
@@ -561,6 +573,8 @@ instance Integral Word32 where
instance Bits Word32 where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
(W32# x#) .&. (W32# y#) = W32# (x# `and#` y#)
(W32# x#) .|. (W32# y#) = W32# (x# `or#` y#)
@@ -584,6 +598,8 @@ instance Bits Word32 where
bitSize _ = 32
isSigned _ = False
popCount (W32# x#) = I# (word2Int# (popCnt32# x#))
+ bit = bitDefault
+ testBit = testBitDefault
{-# RULES
"fromIntegral/Word8->Word32" fromIntegral = \(W8# x#) -> W32# x#
@@ -692,6 +708,8 @@ instance Integral Word64 where
instance Bits Word64 where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
(W64# x#) .&. (W64# y#) = W64# (x# `and64#` y#)
(W64# x#) .|. (W64# y#) = W64# (x# `or64#` y#)
@@ -713,6 +731,8 @@ instance Bits Word64 where
bitSize _ = 64
isSigned _ = False
popCount (W64# x#) = I# (word2Int# (popCnt64# x#))
+ bit = bitDefault
+ testBit = testBitDefault
-- give the 64-bit shift operations the same treatment as the 32-bit
-- ones (see GHC.Base), namely we wrap them in tests to catch the
@@ -800,6 +820,8 @@ instance Integral Word64 where
instance Bits Word64 where
{-# INLINE shift #-}
+ {-# INLINE bit #-}
+ {-# INLINE testBit #-}
(W64# x#) .&. (W64# y#) = W64# (x# `and#` y#)
(W64# x#) .|. (W64# y#) = W64# (x# `or#` y#)
@@ -822,6 +844,8 @@ instance Bits Word64 where
bitSize _ = 64
isSigned _ = False
popCount (W64# x#) = I# (word2Int# (popCnt64# x#))
+ bit = bitDefault
+ testBit = testBitDefault
{-# RULES
"fromIntegral/a->Word64" fromIntegral = \x -> case fromIntegral x of W# x# -> W64# x#
View
3  NHC/SizedTypes.hs
@@ -34,6 +34,9 @@ module NHC.SizedTypes
; shiftR = nhc_prim/**/T/**/Rsh \
; bitSize _ = BS \
; isSigned _ = S \
+ ; bit = bitDefault \
+ ; testBit = testBitDefault \
+ ; popCount = popCountDefault \
}
SIZED_TYPE(Int8,8,True)
Please sign in to comment.
Something went wrong with that request. Please try again.