module Data.Word64 where
import Data.Bits
import Data.Word
import Unsafe.Coerce
class Word64Encode a where
encode64 :: a -> Word64
decode64 :: Word64 -> a
encodeNonNegative64 :: a -> Word64
encodeNonNegative64 = a -> Word64
forall a. Word64Encode a => a -> Word64
encode64
decodeNonNegative64 :: Word64 -> a
decodeNonNegative64 = Word64 -> a
forall a. Word64Encode a => Word64 -> a
decode64
instance Word64Encode Int where
encode64 :: Int -> Word64
encode64 Int
x = Int -> Word64
forall a b. a -> b
unsafeCoerce (Int -> Word64) -> Int -> Word64
forall a b. (a -> b) -> a -> b
$ Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0x3fffffffffffffff
decode64 :: Word64 -> Int
decode64 Word64
x = Word64 -> Int
forall a b. a -> b
unsafeCoerce Word64
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
0x3fffffffffffffff
encodeNonNegative64 :: Int -> Word64
encodeNonNegative64 = Int -> Word64
forall a b. a -> b
unsafeCoerce
decodeNonNegative64 :: Word64 -> Int
decodeNonNegative64 = Word64 -> Int
forall a b. a -> b
unsafeCoerce
instance Word64Encode (Int, Int) where
encode64 :: (Int, Int) -> Word64
encode64 (Int
x, Int
y) =
Int -> Word64
forall a b. a -> b
unsafeCoerce (Int -> Word64) -> Int -> Word64
forall a b. (a -> b) -> a -> b
$
Int -> Int -> Int
forall a. Bits a => a -> Int -> a
unsafeShiftL (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0x3fffffff) Int
31 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0x3fffffff)
decode64 :: Word64 -> (Int, Int)
decode64 Word64
xy = (Word64, Word64) -> (Int, Int)
forall a b. a -> b
unsafeCoerce (Word64
x, Word64
y)
where
!x :: Word64
x = Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
xy Int
31 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
0x3fffffff
!y :: Word64
y = (Word64
xy Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x7fffffff) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
0x3fffffff
encodeNonNegative64 :: (Int, Int) -> Word64
encodeNonNegative64 (Int
x, Int
y) = Int -> Word64
forall a b. a -> b
unsafeCoerce (Int -> Word64) -> Int -> Word64
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. Bits a => a -> Int -> a
unsafeShiftL Int
x Int
31 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
y
decodeNonNegative64 :: Word64 -> (Int, Int)
decodeNonNegative64 Word64
xy = (Word64, Word64) -> (Int, Int)
forall a b. a -> b
unsafeCoerce (Word64
x, Word64
y)
where
!x :: Word64
x = Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
xy Int
31
!y :: Word64
y = Word64
xy Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x7fffffff
instance Word64Encode (Int, Int, Int) where
encode64 :: (Int, Int, Int) -> Word64
encode64 (Int
x, Int
y, Int
z) =
Int -> Word64
forall a b. a -> b
unsafeCoerce (Int -> Word64) -> Int -> Word64
forall a b. (a -> b) -> a -> b
$
Int -> Int -> Int
forall a. Bits a => a -> Int -> a
unsafeShiftL (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
unsafeShiftL (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0xfffff) Int
21 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0xfffff)) Int
21 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
z Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0xfffff)
decode64 :: Word64 -> (Int, Int, Int)
decode64 Word64
xyz = (Word64, Word64, Word64) -> (Int, Int, Int)
forall a b. a -> b
unsafeCoerce (Word64
x, Word64
y, Word64
z)
where
!x :: Word64
x = Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
xyz Int
42 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
0xfffff
!y :: Word64
y = (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
xyz Int
21 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x1fffff) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
0xfffff
!z :: Word64
z = Word64
xyz Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x1fffff Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
0xfffff
encodeNonNegative64 :: (Int, Int, Int) -> Word64
encodeNonNegative64 (Int
x, Int
y, Int
z) =
Int -> Word64
forall a b. a -> b
unsafeCoerce (Int -> Word64) -> Int -> Word64
forall a b. (a -> b) -> a -> b
$
Int -> Int -> Int
forall a. Bits a => a -> Int -> a
unsafeShiftL (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
unsafeShiftL Int
x Int
21 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
y) Int
21 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
z
decodeNonNegative64 :: Word64 -> (Int, Int, Int)
decodeNonNegative64 Word64
xyz = (Word64, Word64, Word64) -> (Int, Int, Int)
forall a b. a -> b
unsafeCoerce (Word64
x, Word64
y, Word64
z)
where
!x :: Word64
x = Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
xyz Int
42
!y :: Word64
y = Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
xyz Int
21 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x1fffff
!z :: Word64
z = Word64
xyz Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x1fffff