{-# LANGUAGE CPP #-}
module Net.Bits (module Net.Bits, module Data.Bits, module Data.Word) where

import Data.Bits
import Data.Word
import qualified Numeric


#if __GLASGOW_HASKELL__ < 708
-- GHC 7.8 introduced a new `finiteBitSize` in Data.Bits, deprecating `bitSize`.
-- We emulate it in older versions.
finiteBitSize :: Bits a => a -> Int
finiteBitSize = bitSize
#endif


-- Manipulating bit arrays
-- Warning: this actually uses lazyness :-)

-- 0: least significant (right most in math notation)
p
array .!. :: p -> Int -> b
.!. Int
index         = let x :: b
x = p -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (p
array p -> Int -> p
forall a. Bits a => a -> Int -> a
`shiftR` (b -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize b
x Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
index))
                          in b
x

a
b1 nextTo :: a -> a -> a
`nextTo` a
b2          = (a -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
b1 a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize a
b2) a -> a -> a
forall a. Bits a => a -> a -> a
.|. a -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
b2



-- catBits xs              = foldr nextTo 0 xs

catBits :: [a] -> t
catBits [a]
bs              = [a] -> t -> t
forall {t} {a}. (Bits t, Integral a, Num t) => [a] -> t -> t
cat [a]
bs t
0
  where cat :: [a] -> t -> t
cat [] t
a        = t
a
        cat (a
b:[a]
bs) t
a    = [a] -> t -> t
cat [a]
bs ((t
a t -> Int -> t
forall a. Bits a => a -> Int -> a
`shiftL` Int
size) t -> t -> t
forall a. Bits a => a -> a -> a
.|. a -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
b)
        size :: Int
size            = a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize ([a] -> a
forall a. HasCallStack => [a] -> a
head [a]
bs)


showHex :: a -> String
showHex a
x               = a -> ShowS
forall a. Integral a => a -> ShowS
Numeric.showHex a
x []
showBin :: a -> String
showBin a
x               = ShowS
forall a. [a] -> [a]
reverse [ if a
x a -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
n then Char
'1' else Char
'0' | Int
n <- [Int
0..a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize a
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1] ]

showHex' :: Int -> a -> String
showHex' Int
n = ShowS
forall a. [a] -> [a]
reverse ShowS -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
take Int
n ShowS -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> ShowS
forall a. [a] -> [a] -> [a]
++Char -> String
forall a. a -> [a]
repeat Char
'0') ShowS -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
forall a. [a] -> [a]
reverse ShowS -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall {a}. Integral a => a -> String
showHex