{-# 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 = Int8 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int8 -> Word8) -> Int8 -> Word8
forall a b. (a -> b) -> a -> b
$ (Int8
n Int8 -> Int -> Int8
forall a. Bits a => a -> Int -> a
`shiftL` Int
1) Int8 -> Int8 -> Int8
forall a. Bits a => a -> a -> a
`xor` (Int8
n Int8 -> Int -> Int8
forall a. Bits a => a -> Int -> a
`shiftR` (Int8 -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Int8
n Int -> Int -> Int
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 = Int16 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int16 -> Word16) -> Int16 -> Word16
forall a b. (a -> b) -> a -> b
$ (Int16
n Int16 -> Int -> Int16
forall a. Bits a => a -> Int -> a
`shiftL` Int
1) Int16 -> Int16 -> Int16
forall a. Bits a => a -> a -> a
`xor` (Int16
n Int16 -> Int -> Int16
forall a. Bits a => a -> Int -> a
`shiftR` (Int16 -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Int16
n Int -> Int -> Int
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 = Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32 -> Word32) -> Int32 -> Word32
forall a b. (a -> b) -> a -> b
$ (Int32
n Int32 -> Int -> Int32
forall a. Bits a => a -> Int -> a
`shiftL` Int
1) Int32 -> Int32 -> Int32
forall a. Bits a => a -> a -> a
`xor` (Int32
n Int32 -> Int -> Int32
forall a. Bits a => a -> Int -> a
`shiftR` (Int32 -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Int32
n Int -> Int -> Int
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 = Int64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Word64) -> Int64 -> Word64
forall a b. (a -> b) -> a -> b
$ (Int64
n Int64 -> Int -> Int64
forall a. Bits a => a -> Int -> a
`shiftL` Int
1) Int64 -> Int64 -> Int64
forall a. Bits a => a -> a -> a
`xor` (Int64
n Int64 -> Int -> Int64
forall a. Bits a => a -> Int -> a
`shiftR` (Int64 -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Int64
n Int -> Int -> Int
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 = Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word) -> Int -> Word
forall a b. (a -> b) -> a -> b
$ (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
1) Int -> Int -> Int
forall a. Bits a => a -> a -> a
`xor` (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` (Int -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
  {-# INLINE zig #-}