1{-# LANGUAGE CPP #-}
2module Data.Bits.Compat (
3    popCount,
4    zeroBits,
5    finiteBitSize,
6    countLeadingZeros,
7    ) where
8
9import Data.Bits
10
11#if !MIN_VERSION_base(4,7,0)
12#define FiniteBits Bits
13#endif
14
15#if !MIN_VERSION_base(4,5,0)
16popCount :: Bits a => a -> Int
17popCount = go 0
18 where
19   go c 0 = c `seq` c
20   go c w = go (c+1) (w .&. (w - 1)) -- clear the least significant
21{-# INLINE popCount #-}
22#endif
23
24#if !MIN_VERSION_base(4,7,0)
25zeroBits :: Bits a => a
26zeroBits = clearBit (bit 0) 0
27{-# INLINE zeroBits #-}
28
29finiteBitSize :: Bits a => a -> Int
30finiteBitSize = bitSize
31{-# INLINE finiteBitSize #-}
32#endif
33
34#if !MIN_VERSION_base(4,8,0)
35countLeadingZeros :: FiniteBits b => b -> Int
36countLeadingZeros x = (w-1) - go (w-1)
37  where
38    go i | i < 0       = i -- no bit set
39         | testBit x i = i
40         | otherwise   = go (i-1)
41
42    w = finiteBitSize x
43{-# INLINE countLeadingZeros #-}
44#endif
45