{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
--------------------------------------------------------------------
-- |
-- License   :  BSD3
-- Stability :  experimental
-- Portability: non-portable
--
--------------------------------------------------------------------
module Data.Bits.Coded
  (
    Coded(..)
    , Unary(..)
    , Elias(..)
    , Gamma
    , Delta
    , runEncode
    , runDecode
  ) where

import Data.Bits
import Data.Bits.Coding
import Data.Bits.Extras
import Data.Bytes.Get
import Data.Bytes.Put
import Data.Foldable

-- $setup
-- >>> import Data.Bytes.Put

-- | Unaligned codes
class Coded c where
  encode     :: MonadPut m => c -> Coding m ()
  encodeMany :: (MonadPut m, Foldable t) => t c -> Coding m ()
  encodeMany = (c -> Coding m ()) -> t c -> Coding m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ c -> Coding m ()
forall c (m :: * -> *). (Coded c, MonadPut m) => c -> Coding m ()
encode
  decode     :: MonadGet m => Coding m c

-- | Unary-coded integers
--
-- >>> runPutL . runEncode $ encode (Unary 1) >> flush
-- "\128"
-- >>> runPutL . runEncode $ encode (Unary 7) >> flush
-- "\254"
newtype Unary n = Unary {
  Unary n -> n
unUnary :: n
} deriving (Unary n -> Unary n -> Bool
(Unary n -> Unary n -> Bool)
-> (Unary n -> Unary n -> Bool) -> Eq (Unary n)
forall n. Eq n => Unary n -> Unary n -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Unary n -> Unary n -> Bool
$c/= :: forall n. Eq n => Unary n -> Unary n -> Bool
== :: Unary n -> Unary n -> Bool
$c== :: forall n. Eq n => Unary n -> Unary n -> Bool
Eq, Eq (Unary n)
Eq (Unary n)
-> (Unary n -> Unary n -> Ordering)
-> (Unary n -> Unary n -> Bool)
-> (Unary n -> Unary n -> Bool)
-> (Unary n -> Unary n -> Bool)
-> (Unary n -> Unary n -> Bool)
-> (Unary n -> Unary n -> Unary n)
-> (Unary n -> Unary n -> Unary n)
-> Ord (Unary n)
Unary n -> Unary n -> Bool
Unary n -> Unary n -> Ordering
Unary n -> Unary n -> Unary n
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall n. Ord n => Eq (Unary n)
forall n. Ord n => Unary n -> Unary n -> Bool
forall n. Ord n => Unary n -> Unary n -> Ordering
forall n. Ord n => Unary n -> Unary n -> Unary n
min :: Unary n -> Unary n -> Unary n
$cmin :: forall n. Ord n => Unary n -> Unary n -> Unary n
max :: Unary n -> Unary n -> Unary n
$cmax :: forall n. Ord n => Unary n -> Unary n -> Unary n
>= :: Unary n -> Unary n -> Bool
$c>= :: forall n. Ord n => Unary n -> Unary n -> Bool
> :: Unary n -> Unary n -> Bool
$c> :: forall n. Ord n => Unary n -> Unary n -> Bool
<= :: Unary n -> Unary n -> Bool
$c<= :: forall n. Ord n => Unary n -> Unary n -> Bool
< :: Unary n -> Unary n -> Bool
$c< :: forall n. Ord n => Unary n -> Unary n -> Bool
compare :: Unary n -> Unary n -> Ordering
$ccompare :: forall n. Ord n => Unary n -> Unary n -> Ordering
$cp1Ord :: forall n. Ord n => Eq (Unary n)
Ord, ReadPrec [Unary n]
ReadPrec (Unary n)
Int -> ReadS (Unary n)
ReadS [Unary n]
(Int -> ReadS (Unary n))
-> ReadS [Unary n]
-> ReadPrec (Unary n)
-> ReadPrec [Unary n]
-> Read (Unary n)
forall n. Read n => ReadPrec [Unary n]
forall n. Read n => ReadPrec (Unary n)
forall n. Read n => Int -> ReadS (Unary n)
forall n. Read n => ReadS [Unary n]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Unary n]
$creadListPrec :: forall n. Read n => ReadPrec [Unary n]
readPrec :: ReadPrec (Unary n)
$creadPrec :: forall n. Read n => ReadPrec (Unary n)
readList :: ReadS [Unary n]
$creadList :: forall n. Read n => ReadS [Unary n]
readsPrec :: Int -> ReadS (Unary n)
$creadsPrec :: forall n. Read n => Int -> ReadS (Unary n)
Read, Int -> Unary n -> ShowS
[Unary n] -> ShowS
Unary n -> String
(Int -> Unary n -> ShowS)
-> (Unary n -> String) -> ([Unary n] -> ShowS) -> Show (Unary n)
forall n. Show n => Int -> Unary n -> ShowS
forall n. Show n => [Unary n] -> ShowS
forall n. Show n => Unary n -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Unary n] -> ShowS
$cshowList :: forall n. Show n => [Unary n] -> ShowS
show :: Unary n -> String
$cshow :: forall n. Show n => Unary n -> String
showsPrec :: Int -> Unary n -> ShowS
$cshowsPrec :: forall n. Show n => Int -> Unary n -> ShowS
Show, Integer -> Unary n
Unary n -> Unary n
Unary n -> Unary n -> Unary n
(Unary n -> Unary n -> Unary n)
-> (Unary n -> Unary n -> Unary n)
-> (Unary n -> Unary n -> Unary n)
-> (Unary n -> Unary n)
-> (Unary n -> Unary n)
-> (Unary n -> Unary n)
-> (Integer -> Unary n)
-> Num (Unary n)
forall n. Num n => Integer -> Unary n
forall n. Num n => Unary n -> Unary n
forall n. Num n => Unary n -> Unary n -> Unary n
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Unary n
$cfromInteger :: forall n. Num n => Integer -> Unary n
signum :: Unary n -> Unary n
$csignum :: forall n. Num n => Unary n -> Unary n
abs :: Unary n -> Unary n
$cabs :: forall n. Num n => Unary n -> Unary n
negate :: Unary n -> Unary n
$cnegate :: forall n. Num n => Unary n -> Unary n
* :: Unary n -> Unary n -> Unary n
$c* :: forall n. Num n => Unary n -> Unary n -> Unary n
- :: Unary n -> Unary n -> Unary n
$c- :: forall n. Num n => Unary n -> Unary n -> Unary n
+ :: Unary n -> Unary n -> Unary n
$c+ :: forall n. Num n => Unary n -> Unary n -> Unary n
Num, Enum (Unary n)
Real (Unary n)
Real (Unary n)
-> Enum (Unary n)
-> (Unary n -> Unary n -> Unary n)
-> (Unary n -> Unary n -> Unary n)
-> (Unary n -> Unary n -> Unary n)
-> (Unary n -> Unary n -> Unary n)
-> (Unary n -> Unary n -> (Unary n, Unary n))
-> (Unary n -> Unary n -> (Unary n, Unary n))
-> (Unary n -> Integer)
-> Integral (Unary n)
Unary n -> Integer
Unary n -> Unary n -> (Unary n, Unary n)
Unary n -> Unary n -> Unary n
forall n. Integral n => Enum (Unary n)
forall n. Integral n => Real (Unary n)
forall n. Integral n => Unary n -> Integer
forall n. Integral n => Unary n -> Unary n -> (Unary n, Unary n)
forall n. Integral n => Unary n -> Unary n -> Unary n
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: Unary n -> Integer
$ctoInteger :: forall n. Integral n => Unary n -> Integer
divMod :: Unary n -> Unary n -> (Unary n, Unary n)
$cdivMod :: forall n. Integral n => Unary n -> Unary n -> (Unary n, Unary n)
quotRem :: Unary n -> Unary n -> (Unary n, Unary n)
$cquotRem :: forall n. Integral n => Unary n -> Unary n -> (Unary n, Unary n)
mod :: Unary n -> Unary n -> Unary n
$cmod :: forall n. Integral n => Unary n -> Unary n -> Unary n
div :: Unary n -> Unary n -> Unary n
$cdiv :: forall n. Integral n => Unary n -> Unary n -> Unary n
rem :: Unary n -> Unary n -> Unary n
$crem :: forall n. Integral n => Unary n -> Unary n -> Unary n
quot :: Unary n -> Unary n -> Unary n
$cquot :: forall n. Integral n => Unary n -> Unary n -> Unary n
$cp2Integral :: forall n. Integral n => Enum (Unary n)
$cp1Integral :: forall n. Integral n => Real (Unary n)
Integral, Num (Unary n)
Ord (Unary n)
Num (Unary n)
-> Ord (Unary n) -> (Unary n -> Rational) -> Real (Unary n)
Unary n -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
forall n. Real n => Num (Unary n)
forall n. Real n => Ord (Unary n)
forall n. Real n => Unary n -> Rational
toRational :: Unary n -> Rational
$ctoRational :: forall n. Real n => Unary n -> Rational
$cp2Real :: forall n. Real n => Ord (Unary n)
$cp1Real :: forall n. Real n => Num (Unary n)
Real, Int -> Unary n
Unary n -> Int
Unary n -> [Unary n]
Unary n -> Unary n
Unary n -> Unary n -> [Unary n]
Unary n -> Unary n -> Unary n -> [Unary n]
(Unary n -> Unary n)
-> (Unary n -> Unary n)
-> (Int -> Unary n)
-> (Unary n -> Int)
-> (Unary n -> [Unary n])
-> (Unary n -> Unary n -> [Unary n])
-> (Unary n -> Unary n -> [Unary n])
-> (Unary n -> Unary n -> Unary n -> [Unary n])
-> Enum (Unary n)
forall n. Enum n => Int -> Unary n
forall n. Enum n => Unary n -> Int
forall n. Enum n => Unary n -> [Unary n]
forall n. Enum n => Unary n -> Unary n
forall n. Enum n => Unary n -> Unary n -> [Unary n]
forall n. Enum n => Unary n -> Unary n -> Unary n -> [Unary n]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Unary n -> Unary n -> Unary n -> [Unary n]
$cenumFromThenTo :: forall n. Enum n => Unary n -> Unary n -> Unary n -> [Unary n]
enumFromTo :: Unary n -> Unary n -> [Unary n]
$cenumFromTo :: forall n. Enum n => Unary n -> Unary n -> [Unary n]
enumFromThen :: Unary n -> Unary n -> [Unary n]
$cenumFromThen :: forall n. Enum n => Unary n -> Unary n -> [Unary n]
enumFrom :: Unary n -> [Unary n]
$cenumFrom :: forall n. Enum n => Unary n -> [Unary n]
fromEnum :: Unary n -> Int
$cfromEnum :: forall n. Enum n => Unary n -> Int
toEnum :: Int -> Unary n
$ctoEnum :: forall n. Enum n => Int -> Unary n
pred :: Unary n -> Unary n
$cpred :: forall n. Enum n => Unary n -> Unary n
succ :: Unary n -> Unary n
$csucc :: forall n. Enum n => Unary n -> Unary n
Enum)

ones :: Integer
ones :: Integer
ones = Integer
forall b. Bits b => b
oneBits Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
1
instance Integral n => Coded (Unary n) where
  encode :: Unary n -> Coding m ()
encode (Unary n
n) = Int -> Integer -> Coding m ()
forall (m :: * -> *) b.
(MonadPut m, Bits b) =>
Int -> b -> Coding m ()
putBitsFrom (n -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral n
n) Integer
ones
  decode :: Coding m (Unary n)
decode = do Bool
b <- Coding m Bool
forall (m :: * -> *). MonadGet m => Coding m Bool
getBit
              if Bool
b then (Unary n -> Unary n) -> Coding m (Unary n) -> Coding m (Unary n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Unary n
1Unary n -> Unary n -> Unary n
forall a. Num a => a -> a -> a
+) Coding m (Unary n)
forall c (m :: * -> *). (Coded c, MonadGet m) => Coding m c
decode else Unary n -> Coding m (Unary n)
forall (m :: * -> *) a. Monad m => a -> m a
return Unary n
0

runEncode :: MonadPut m => Coding m () -> m ()
runEncode :: Coding m () -> m ()
runEncode (Coding forall r. (() -> Int -> Word8 -> m r) -> Int -> Word8 -> m r
c) = (() -> Int -> Word8 -> m ()) -> Int -> Word8 -> m ()
forall r. (() -> Int -> Word8 -> m r) -> Int -> Word8 -> m r
c () -> Int -> Word8 -> m ()
forall (m :: * -> *) p p p. Monad m => p -> p -> p -> m ()
k Int
0 Word8
0
  where k :: p -> p -> p -> m ()
k p
_ p
_ p
_ = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

runDecode :: MonadGet m => Coding m a -> m a
runDecode :: Coding m a -> m a
runDecode (Coding forall r. (a -> Int -> Word8 -> m r) -> Int -> Word8 -> m r
c) = (a -> Int -> Word8 -> m a) -> Int -> Word8 -> m a
forall r. (a -> Int -> Word8 -> m r) -> Int -> Word8 -> m r
c a -> Int -> Word8 -> m a
forall (m :: * -> *) a p p. Monad m => a -> p -> p -> m a
k Int
0 Word8
0
  where k :: a -> p -> p -> m a
k a
a p
_ p
_ = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a

-- | Representation for Elias 'Gamma' and 'Delta' codes.  A positive
-- integer @n@ is encoded by encoding the position of its most
-- significant bit, and then the binary representation of the rest of
-- the number.
newtype Elias c n = Elias {
  Elias c n -> n
unElias :: n
} deriving (Elias c n -> Elias c n -> Bool
(Elias c n -> Elias c n -> Bool)
-> (Elias c n -> Elias c n -> Bool) -> Eq (Elias c n)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall c n. Eq n => Elias c n -> Elias c n -> Bool
/= :: Elias c n -> Elias c n -> Bool
$c/= :: forall c n. Eq n => Elias c n -> Elias c n -> Bool
== :: Elias c n -> Elias c n -> Bool
$c== :: forall c n. Eq n => Elias c n -> Elias c n -> Bool
Eq, Eq (Elias c n)
Eq (Elias c n)
-> (Elias c n -> Elias c n -> Ordering)
-> (Elias c n -> Elias c n -> Bool)
-> (Elias c n -> Elias c n -> Bool)
-> (Elias c n -> Elias c n -> Bool)
-> (Elias c n -> Elias c n -> Bool)
-> (Elias c n -> Elias c n -> Elias c n)
-> (Elias c n -> Elias c n -> Elias c n)
-> Ord (Elias c n)
Elias c n -> Elias c n -> Bool
Elias c n -> Elias c n -> Ordering
Elias c n -> Elias c n -> Elias c n
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall c n. Ord n => Eq (Elias c n)
forall c n. Ord n => Elias c n -> Elias c n -> Bool
forall c n. Ord n => Elias c n -> Elias c n -> Ordering
forall c n. Ord n => Elias c n -> Elias c n -> Elias c n
min :: Elias c n -> Elias c n -> Elias c n
$cmin :: forall c n. Ord n => Elias c n -> Elias c n -> Elias c n
max :: Elias c n -> Elias c n -> Elias c n
$cmax :: forall c n. Ord n => Elias c n -> Elias c n -> Elias c n
>= :: Elias c n -> Elias c n -> Bool
$c>= :: forall c n. Ord n => Elias c n -> Elias c n -> Bool
> :: Elias c n -> Elias c n -> Bool
$c> :: forall c n. Ord n => Elias c n -> Elias c n -> Bool
<= :: Elias c n -> Elias c n -> Bool
$c<= :: forall c n. Ord n => Elias c n -> Elias c n -> Bool
< :: Elias c n -> Elias c n -> Bool
$c< :: forall c n. Ord n => Elias c n -> Elias c n -> Bool
compare :: Elias c n -> Elias c n -> Ordering
$ccompare :: forall c n. Ord n => Elias c n -> Elias c n -> Ordering
$cp1Ord :: forall c n. Ord n => Eq (Elias c n)
Ord, ReadPrec [Elias c n]
ReadPrec (Elias c n)
Int -> ReadS (Elias c n)
ReadS [Elias c n]
(Int -> ReadS (Elias c n))
-> ReadS [Elias c n]
-> ReadPrec (Elias c n)
-> ReadPrec [Elias c n]
-> Read (Elias c n)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall c n. Read n => ReadPrec [Elias c n]
forall c n. Read n => ReadPrec (Elias c n)
forall c n. Read n => Int -> ReadS (Elias c n)
forall c n. Read n => ReadS [Elias c n]
readListPrec :: ReadPrec [Elias c n]
$creadListPrec :: forall c n. Read n => ReadPrec [Elias c n]
readPrec :: ReadPrec (Elias c n)
$creadPrec :: forall c n. Read n => ReadPrec (Elias c n)
readList :: ReadS [Elias c n]
$creadList :: forall c n. Read n => ReadS [Elias c n]
readsPrec :: Int -> ReadS (Elias c n)
$creadsPrec :: forall c n. Read n => Int -> ReadS (Elias c n)
Read, Int -> Elias c n -> ShowS
[Elias c n] -> ShowS
Elias c n -> String
(Int -> Elias c n -> ShowS)
-> (Elias c n -> String)
-> ([Elias c n] -> ShowS)
-> Show (Elias c n)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall c n. Show n => Int -> Elias c n -> ShowS
forall c n. Show n => [Elias c n] -> ShowS
forall c n. Show n => Elias c n -> String
showList :: [Elias c n] -> ShowS
$cshowList :: forall c n. Show n => [Elias c n] -> ShowS
show :: Elias c n -> String
$cshow :: forall c n. Show n => Elias c n -> String
showsPrec :: Int -> Elias c n -> ShowS
$cshowsPrec :: forall c n. Show n => Int -> Elias c n -> ShowS
Show, Integer -> Elias c n
Elias c n -> Elias c n
Elias c n -> Elias c n -> Elias c n
(Elias c n -> Elias c n -> Elias c n)
-> (Elias c n -> Elias c n -> Elias c n)
-> (Elias c n -> Elias c n -> Elias c n)
-> (Elias c n -> Elias c n)
-> (Elias c n -> Elias c n)
-> (Elias c n -> Elias c n)
-> (Integer -> Elias c n)
-> Num (Elias c n)
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
forall c n. Num n => Integer -> Elias c n
forall c n. Num n => Elias c n -> Elias c n
forall c n. Num n => Elias c n -> Elias c n -> Elias c n
fromInteger :: Integer -> Elias c n
$cfromInteger :: forall c n. Num n => Integer -> Elias c n
signum :: Elias c n -> Elias c n
$csignum :: forall c n. Num n => Elias c n -> Elias c n
abs :: Elias c n -> Elias c n
$cabs :: forall c n. Num n => Elias c n -> Elias c n
negate :: Elias c n -> Elias c n
$cnegate :: forall c n. Num n => Elias c n -> Elias c n
* :: Elias c n -> Elias c n -> Elias c n
$c* :: forall c n. Num n => Elias c n -> Elias c n -> Elias c n
- :: Elias c n -> Elias c n -> Elias c n
$c- :: forall c n. Num n => Elias c n -> Elias c n -> Elias c n
+ :: Elias c n -> Elias c n -> Elias c n
$c+ :: forall c n. Num n => Elias c n -> Elias c n -> Elias c n
Num, Num (Elias c n)
Ord (Elias c n)
Num (Elias c n)
-> Ord (Elias c n) -> (Elias c n -> Rational) -> Real (Elias c n)
Elias c n -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
forall c n. Real n => Num (Elias c n)
forall c n. Real n => Ord (Elias c n)
forall c n. Real n => Elias c n -> Rational
toRational :: Elias c n -> Rational
$ctoRational :: forall c n. Real n => Elias c n -> Rational
$cp2Real :: forall c n. Real n => Ord (Elias c n)
$cp1Real :: forall c n. Real n => Num (Elias c n)
Real, Enum (Elias c n)
Real (Elias c n)
Real (Elias c n)
-> Enum (Elias c n)
-> (Elias c n -> Elias c n -> Elias c n)
-> (Elias c n -> Elias c n -> Elias c n)
-> (Elias c n -> Elias c n -> Elias c n)
-> (Elias c n -> Elias c n -> Elias c n)
-> (Elias c n -> Elias c n -> (Elias c n, Elias c n))
-> (Elias c n -> Elias c n -> (Elias c n, Elias c n))
-> (Elias c n -> Integer)
-> Integral (Elias c n)
Elias c n -> Integer
Elias c n -> Elias c n -> (Elias c n, Elias c n)
Elias c n -> Elias c n -> Elias c n
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
forall c n. Integral n => Enum (Elias c n)
forall c n. Integral n => Real (Elias c n)
forall c n. Integral n => Elias c n -> Integer
forall c n.
Integral n =>
Elias c n -> Elias c n -> (Elias c n, Elias c n)
forall c n. Integral n => Elias c n -> Elias c n -> Elias c n
toInteger :: Elias c n -> Integer
$ctoInteger :: forall c n. Integral n => Elias c n -> Integer
divMod :: Elias c n -> Elias c n -> (Elias c n, Elias c n)
$cdivMod :: forall c n.
Integral n =>
Elias c n -> Elias c n -> (Elias c n, Elias c n)
quotRem :: Elias c n -> Elias c n -> (Elias c n, Elias c n)
$cquotRem :: forall c n.
Integral n =>
Elias c n -> Elias c n -> (Elias c n, Elias c n)
mod :: Elias c n -> Elias c n -> Elias c n
$cmod :: forall c n. Integral n => Elias c n -> Elias c n -> Elias c n
div :: Elias c n -> Elias c n -> Elias c n
$cdiv :: forall c n. Integral n => Elias c n -> Elias c n -> Elias c n
rem :: Elias c n -> Elias c n -> Elias c n
$crem :: forall c n. Integral n => Elias c n -> Elias c n -> Elias c n
quot :: Elias c n -> Elias c n -> Elias c n
$cquot :: forall c n. Integral n => Elias c n -> Elias c n -> Elias c n
$cp2Integral :: forall c n. Integral n => Enum (Elias c n)
$cp1Integral :: forall c n. Integral n => Real (Elias c n)
Integral, Int -> Elias c n
Elias c n -> Int
Elias c n -> [Elias c n]
Elias c n -> Elias c n
Elias c n -> Elias c n -> [Elias c n]
Elias c n -> Elias c n -> Elias c n -> [Elias c n]
(Elias c n -> Elias c n)
-> (Elias c n -> Elias c n)
-> (Int -> Elias c n)
-> (Elias c n -> Int)
-> (Elias c n -> [Elias c n])
-> (Elias c n -> Elias c n -> [Elias c n])
-> (Elias c n -> Elias c n -> [Elias c n])
-> (Elias c n -> Elias c n -> Elias c n -> [Elias c n])
-> Enum (Elias c n)
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
forall c n. Enum n => Int -> Elias c n
forall c n. Enum n => Elias c n -> Int
forall c n. Enum n => Elias c n -> [Elias c n]
forall c n. Enum n => Elias c n -> Elias c n
forall c n. Enum n => Elias c n -> Elias c n -> [Elias c n]
forall c n.
Enum n =>
Elias c n -> Elias c n -> Elias c n -> [Elias c n]
enumFromThenTo :: Elias c n -> Elias c n -> Elias c n -> [Elias c n]
$cenumFromThenTo :: forall c n.
Enum n =>
Elias c n -> Elias c n -> Elias c n -> [Elias c n]
enumFromTo :: Elias c n -> Elias c n -> [Elias c n]
$cenumFromTo :: forall c n. Enum n => Elias c n -> Elias c n -> [Elias c n]
enumFromThen :: Elias c n -> Elias c n -> [Elias c n]
$cenumFromThen :: forall c n. Enum n => Elias c n -> Elias c n -> [Elias c n]
enumFrom :: Elias c n -> [Elias c n]
$cenumFrom :: forall c n. Enum n => Elias c n -> [Elias c n]
fromEnum :: Elias c n -> Int
$cfromEnum :: forall c n. Enum n => Elias c n -> Int
toEnum :: Int -> Elias c n
$ctoEnum :: forall c n. Enum n => Int -> Elias c n
pred :: Elias c n -> Elias c n
$cpred :: forall c n. Enum n => Elias c n -> Elias c n
succ :: Elias c n -> Elias c n
$csucc :: forall c n. Enum n => Elias c n -> Elias c n
Enum)

instance (Coded c, Integral c, Ranked n) => Coded (Elias c n) where
  encode :: Elias c n -> Coding m ()
encode (Elias n
n) = do c -> Coding m ()
forall c (m :: * -> *). (Coded c, MonadPut m) => c -> Coding m ()
encode (Int -> c
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
m :: c)
                        Int -> n -> Coding m ()
forall (m :: * -> *) b.
(MonadPut m, Bits b) =>
Int -> b -> Coding m ()
putBitsFrom (Int -> Int
forall a. Enum a => a -> a
pred Int
m) n
n
    where m :: Int
m = n -> Int
forall t. Ranked t => t -> Int
msb n
n
  decode :: Coding m (Elias c n)
decode = do c
m :: c <- Coding m c
forall c (m :: * -> *). (Coded c, MonadGet m) => Coding m c
decode
              n
n <- Int -> n -> Coding m n
forall (m :: * -> *) b.
(MonadGet m, Bits b) =>
Int -> b -> Coding m b
getBitsFrom (Int -> Int
forall a. Enum a => a -> a
pred (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ c -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral c
m) (Int -> n
forall a. Bits a => Int -> a
bit (Int -> n) -> Int -> n
forall a b. (a -> b) -> a -> b
$ c -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral c
m)
              Elias c n -> Coding m (Elias c n)
forall (m :: * -> *) a. Monad m => a -> m a
return (Elias c n -> Coding m (Elias c n))
-> Elias c n -> Coding m (Elias c n)
forall a b. (a -> b) -> a -> b
$ n -> Elias c n
forall c n. n -> Elias c n
Elias n
n

-- | Elias Gamma codes the position of the most significant in
-- 'Unary'.
type Gamma c = Elias (Unary c)
-- | Elias Delta codes the position of the most significant bit in
-- Elias 'Gamma'.
type Delta c n = Elias (Gamma c n) n