{-# LANGUAGE TypeFamilies #-}

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

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

class Zig a where
  type Zigged a
  zig :: a -> Zigged a

instance Zig Int8 where
  type Zigged Int8 = Word8
  zig :: Int8 -> Zigged Int8
zig Int8
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (Int8
n forall a. Bits a => a -> Int -> a
`shiftL` Int
1) forall a. Bits a => a -> a -> a
`xor` (Int8
n forall a. Bits a => a -> Int -> a
`shiftR` (forall b. FiniteBits b => b -> Int
finiteBitSize Int8
n forall a. Num a => a -> a -> a
- Int
1))
  {-# INLINE zig #-}

instance Zig Int16 where
  type Zigged Int16 = Word16
  zig :: Int16 -> Zigged Int16
zig Int16
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (Int16
n forall a. Bits a => a -> Int -> a
`shiftL` Int
1) forall a. Bits a => a -> a -> a
`xor` (Int16
n forall a. Bits a => a -> Int -> a
`shiftR` (forall b. FiniteBits b => b -> Int
finiteBitSize Int16
n forall a. Num a => a -> a -> a
- Int
1))
  {-# INLINE zig #-}

instance Zig Int32 where
  type Zigged Int32 = Word32
  zig :: Int32 -> Zigged Int32
zig Int32
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (Int32
n forall a. Bits a => a -> Int -> a
`shiftL` Int
1) forall a. Bits a => a -> a -> a
`xor` (Int32
n forall a. Bits a => a -> Int -> a
`shiftR` (forall b. FiniteBits b => b -> Int
finiteBitSize Int32
n forall a. Num a => a -> a -> a
- Int
1))
  {-# INLINE zig #-}

instance Zig Int64 where
  type Zigged Int64 = Word64
  zig :: Int64 -> Zigged Int64
zig Int64
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (Int64
n forall a. Bits a => a -> Int -> a
`shiftL` Int
1) forall a. Bits a => a -> a -> a
`xor` (Int64
n forall a. Bits a => a -> Int -> a
`shiftR` (forall b. FiniteBits b => b -> Int
finiteBitSize Int64
n forall a. Num a => a -> a -> a
- Int
1))
  {-# INLINE zig #-}

instance Zig Int where
  type Zigged Int = Word
  zig :: Int -> Zigged Int
zig Int
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (Int
n forall a. Bits a => a -> Int -> a
`shiftL` Int
1) forall a. Bits a => a -> a -> a
`xor` (Int
n forall a. Bits a => a -> Int -> a
`shiftR` (forall b. FiniteBits b => b -> Int
finiteBitSize Int
n forall a. Num a => a -> a -> a
- Int
1))
  {-# INLINE zig #-}