{-# LANGUAGE TypeFamilies #-}

module Data.Avro.Internal.Zag
  ( Zag(..)
  ) where

import Data.Bits
import Data.Int
import Data.Word

class Zag a where
  type Zagged a
  zag :: a -> Zagged a

instance Zag Word8 where
  type Zagged Word8 = Int8
  zag :: Word8 -> Zagged Word8
zag Word8
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (Word8
n forall a. Bits a => a -> Int -> a
`shiftR` Int
1) forall a. Bits a => a -> a -> a
`xor` forall a. Num a => a -> a
negate (Word8
n forall a. Bits a => a -> a -> a
.&. Word8
0x1)
  {-# INLINE zag #-}

instance Zag Word16 where
  type Zagged Word16 = Int16
  zag :: Word16 -> Zagged Word16
zag Word16
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (Word16
n forall a. Bits a => a -> Int -> a
`shiftR` Int
1) forall a. Bits a => a -> a -> a
`xor` forall a. Num a => a -> a
negate (Word16
n forall a. Bits a => a -> a -> a
.&. Word16
0x1)
  {-# INLINE zag #-}

instance Zag Word32 where
  type Zagged Word32 = Int32
  zag :: Word32 -> Zagged Word32
zag Word32
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (Word32
n forall a. Bits a => a -> Int -> a
`shiftR` Int
1) forall a. Bits a => a -> a -> a
`xor` forall a. Num a => a -> a
negate (Word32
n forall a. Bits a => a -> a -> a
.&. Word32
0x1)
  {-# INLINE zag #-}

instance Zag Word64 where
  type Zagged Word64 = Int64
  zag :: Word64 -> Zagged Word64
zag Word64
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (Word64
n forall a. Bits a => a -> Int -> a
`shiftR` Int
1) forall a. Bits a => a -> a -> a
`xor` forall a. Num a => a -> a
negate (Word64
n forall a. Bits a => a -> a -> a
.&. Word64
0x1)
  {-# INLINE zag #-}

instance Zag Word where
  type Zagged Word = Int
  zag :: Word -> Zagged Word
zag Word
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (Word
n forall a. Bits a => a -> Int -> a
`shiftR` Int
1) forall a. Bits a => a -> a -> a
`xor` forall a. Num a => a -> a
negate (Word
n forall a. Bits a => a -> a -> a
.&. Word
0x1)
  {-# INLINE zag #-}