{-# LANGUAGE BinaryLiterals #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeApplications #-}

module RON.Util.Word (
    -- * Word2
    Word2,
    b00, b01, b10, b11,
    pattern B00, pattern B01, pattern B10, pattern B11,
    leastSignificant2,
    -- * Word4
    Word4,
    b0000, b0001, b0010, b0011, b0100, b0101, b0110, b0111,
    b1000, b1001, b1010, b1011, b1100, b1101, b1110, b1111,
    pattern B0000,
    leastSignificant4,
    -- * Word6
    Word6 (..),
    leastSignificant6,
    ls6,
    -- * Word8
    Word8,
    -- * Word12
    Word12,
    leastSignificant12,
    ls12,
    -- * Word16
    Word16,
    -- * Word24
    Word24,
    leastSignificant24,
    ls24,
    -- * Word32
    Word32,
    -- * Word60
    Word60,
    leastSignificant60,
    ls60,
    toWord60,
    -- * Word64
    Word64,
    -- * SafeCast
    SafeCast (..),
) where

import           RON.Prelude

import           Data.Bits ((.&.))
import           Data.Fixed (Fixed, HasResolution)
import           Data.Hashable (hashUsing, hashWithSalt)
import           GHC.Num (abs, fromInteger, signum)

newtype Word2 = W2 Word8
    deriving (Word2 -> Word2 -> Bool
(Word2 -> Word2 -> Bool) -> (Word2 -> Word2 -> Bool) -> Eq Word2
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Word2 -> Word2 -> Bool
$c/= :: Word2 -> Word2 -> Bool
== :: Word2 -> Word2 -> Bool
$c== :: Word2 -> Word2 -> Bool
Eq, Int -> Word2 -> Int
Word2 -> Int
(Int -> Word2 -> Int) -> (Word2 -> Int) -> Hashable Word2
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Word2 -> Int
$chash :: Word2 -> Int
hashWithSalt :: Int -> Word2 -> Int
$chashWithSalt :: Int -> Word2 -> Int
Hashable, Eq Word2
Eq Word2
-> (Word2 -> Word2 -> Ordering)
-> (Word2 -> Word2 -> Bool)
-> (Word2 -> Word2 -> Bool)
-> (Word2 -> Word2 -> Bool)
-> (Word2 -> Word2 -> Bool)
-> (Word2 -> Word2 -> Word2)
-> (Word2 -> Word2 -> Word2)
-> Ord Word2
Word2 -> Word2 -> Bool
Word2 -> Word2 -> Ordering
Word2 -> Word2 -> Word2
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
min :: Word2 -> Word2 -> Word2
$cmin :: Word2 -> Word2 -> Word2
max :: Word2 -> Word2 -> Word2
$cmax :: Word2 -> Word2 -> Word2
>= :: Word2 -> Word2 -> Bool
$c>= :: Word2 -> Word2 -> Bool
> :: Word2 -> Word2 -> Bool
$c> :: Word2 -> Word2 -> Bool
<= :: Word2 -> Word2 -> Bool
$c<= :: Word2 -> Word2 -> Bool
< :: Word2 -> Word2 -> Bool
$c< :: Word2 -> Word2 -> Bool
compare :: Word2 -> Word2 -> Ordering
$ccompare :: Word2 -> Word2 -> Ordering
$cp1Ord :: Eq Word2
Ord, Int -> Word2 -> ShowS
[Word2] -> ShowS
Word2 -> String
(Int -> Word2 -> ShowS)
-> (Word2 -> String) -> ([Word2] -> ShowS) -> Show Word2
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Word2] -> ShowS
$cshowList :: [Word2] -> ShowS
show :: Word2 -> String
$cshow :: Word2 -> String
showsPrec :: Int -> Word2 -> ShowS
$cshowsPrec :: Int -> Word2 -> ShowS
Show)

b00, b01, b10, b11 :: Word2
b00 :: Word2
b00 = Word8 -> Word2
W2 Word8
0b00
b01 :: Word2
b01 = Word8 -> Word2
W2 Word8
0b01
b10 :: Word2
b10 = Word8 -> Word2
W2 Word8
0b10
b11 :: Word2
b11 = Word8 -> Word2
W2 Word8
0b11

pattern B00 :: Word2
pattern $bB00 :: Word2
$mB00 :: forall r. Word2 -> (Void# -> r) -> (Void# -> r) -> r
B00 = W2 0b00
pattern B01 :: Word2
pattern $bB01 :: Word2
$mB01 :: forall r. Word2 -> (Void# -> r) -> (Void# -> r) -> r
B01 = W2 0b01
pattern B10 :: Word2
pattern $bB10 :: Word2
$mB10 :: forall r. Word2 -> (Void# -> r) -> (Void# -> r) -> r
B10 = W2 0b10
pattern B11 :: Word2
pattern $bB11 :: Word2
$mB11 :: forall r. Word2 -> (Void# -> r) -> (Void# -> r) -> r
B11 = W2 0b11
{-# COMPLETE B00, B01, B10, B11 #-}

-- | 'Word2' smart constructor dropping upper bits
leastSignificant2 :: Integral integral => integral -> Word2
leastSignificant2 :: integral -> Word2
leastSignificant2 = Word8 -> Word2
W2 (Word8 -> Word2) -> (integral -> Word8) -> integral -> Word2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8
0b11 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&.) (Word8 -> Word8) -> (integral -> Word8) -> integral -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. integral -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral

newtype Word4 = W4 Word8
    deriving (Word4 -> Word4 -> Bool
(Word4 -> Word4 -> Bool) -> (Word4 -> Word4 -> Bool) -> Eq Word4
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Word4 -> Word4 -> Bool
$c/= :: Word4 -> Word4 -> Bool
== :: Word4 -> Word4 -> Bool
$c== :: Word4 -> Word4 -> Bool
Eq, Eq Word4
Eq Word4
-> (Word4 -> Word4 -> Ordering)
-> (Word4 -> Word4 -> Bool)
-> (Word4 -> Word4 -> Bool)
-> (Word4 -> Word4 -> Bool)
-> (Word4 -> Word4 -> Bool)
-> (Word4 -> Word4 -> Word4)
-> (Word4 -> Word4 -> Word4)
-> Ord Word4
Word4 -> Word4 -> Bool
Word4 -> Word4 -> Ordering
Word4 -> Word4 -> Word4
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
min :: Word4 -> Word4 -> Word4
$cmin :: Word4 -> Word4 -> Word4
max :: Word4 -> Word4 -> Word4
$cmax :: Word4 -> Word4 -> Word4
>= :: Word4 -> Word4 -> Bool
$c>= :: Word4 -> Word4 -> Bool
> :: Word4 -> Word4 -> Bool
$c> :: Word4 -> Word4 -> Bool
<= :: Word4 -> Word4 -> Bool
$c<= :: Word4 -> Word4 -> Bool
< :: Word4 -> Word4 -> Bool
$c< :: Word4 -> Word4 -> Bool
compare :: Word4 -> Word4 -> Ordering
$ccompare :: Word4 -> Word4 -> Ordering
$cp1Ord :: Eq Word4
Ord, Int -> Word4 -> ShowS
[Word4] -> ShowS
Word4 -> String
(Int -> Word4 -> ShowS)
-> (Word4 -> String) -> ([Word4] -> ShowS) -> Show Word4
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Word4] -> ShowS
$cshowList :: [Word4] -> ShowS
show :: Word4 -> String
$cshow :: Word4 -> String
showsPrec :: Int -> Word4 -> ShowS
$cshowsPrec :: Int -> Word4 -> ShowS
Show)

b0000, b0001, b0010, b0011, b0100, b0101, b0110, b0111 :: Word4
b1000, b1001, b1010, b1011, b1100, b1101, b1110, b1111 :: Word4
b0000 :: Word4
b0000 = Word8 -> Word4
W4 Word8
0b0000
b0001 :: Word4
b0001 = Word8 -> Word4
W4 Word8
0b0001
b0010 :: Word4
b0010 = Word8 -> Word4
W4 Word8
0b0010
b0011 :: Word4
b0011 = Word8 -> Word4
W4 Word8
0b0011
b0100 :: Word4
b0100 = Word8 -> Word4
W4 Word8
0b0100
b0101 :: Word4
b0101 = Word8 -> Word4
W4 Word8
0b0101
b0110 :: Word4
b0110 = Word8 -> Word4
W4 Word8
0b0110
b0111 :: Word4
b0111 = Word8 -> Word4
W4 Word8
0b0111
b1000 :: Word4
b1000 = Word8 -> Word4
W4 Word8
0b1000
b1001 :: Word4
b1001 = Word8 -> Word4
W4 Word8
0b1001
b1010 :: Word4
b1010 = Word8 -> Word4
W4 Word8
0b1010
b1011 :: Word4
b1011 = Word8 -> Word4
W4 Word8
0b1011
b1100 :: Word4
b1100 = Word8 -> Word4
W4 Word8
0b1100
b1101 :: Word4
b1101 = Word8 -> Word4
W4 Word8
0b1101
b1110 :: Word4
b1110 = Word8 -> Word4
W4 Word8
0b1110
b1111 :: Word4
b1111 = Word8 -> Word4
W4 Word8
0b1111

pattern B0000 :: Word4
pattern $bB0000 :: Word4
$mB0000 :: forall r. Word4 -> (Void# -> r) -> (Void# -> r) -> r
B0000 = W4 0b0000

-- | 'Word4' smart constructor dropping upper bits
leastSignificant4 :: Integral integral => integral -> Word4
leastSignificant4 :: integral -> Word4
leastSignificant4 = Word8 -> Word4
W4 (Word8 -> Word4) -> (integral -> Word8) -> integral -> Word4
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8
0xF Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&.) (Word8 -> Word8) -> (integral -> Word8) -> integral -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. integral -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral

newtype Word6 = W6 Word8
    deriving (Word6 -> Word6 -> Bool
(Word6 -> Word6 -> Bool) -> (Word6 -> Word6 -> Bool) -> Eq Word6
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Word6 -> Word6 -> Bool
$c/= :: Word6 -> Word6 -> Bool
== :: Word6 -> Word6 -> Bool
$c== :: Word6 -> Word6 -> Bool
Eq, Eq Word6
Eq Word6
-> (Word6 -> Word6 -> Ordering)
-> (Word6 -> Word6 -> Bool)
-> (Word6 -> Word6 -> Bool)
-> (Word6 -> Word6 -> Bool)
-> (Word6 -> Word6 -> Bool)
-> (Word6 -> Word6 -> Word6)
-> (Word6 -> Word6 -> Word6)
-> Ord Word6
Word6 -> Word6 -> Bool
Word6 -> Word6 -> Ordering
Word6 -> Word6 -> Word6
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
min :: Word6 -> Word6 -> Word6
$cmin :: Word6 -> Word6 -> Word6
max :: Word6 -> Word6 -> Word6
$cmax :: Word6 -> Word6 -> Word6
>= :: Word6 -> Word6 -> Bool
$c>= :: Word6 -> Word6 -> Bool
> :: Word6 -> Word6 -> Bool
$c> :: Word6 -> Word6 -> Bool
<= :: Word6 -> Word6 -> Bool
$c<= :: Word6 -> Word6 -> Bool
< :: Word6 -> Word6 -> Bool
$c< :: Word6 -> Word6 -> Bool
compare :: Word6 -> Word6 -> Ordering
$ccompare :: Word6 -> Word6 -> Ordering
$cp1Ord :: Eq Word6
Ord, Int -> Word6 -> ShowS
[Word6] -> ShowS
Word6 -> String
(Int -> Word6 -> ShowS)
-> (Word6 -> String) -> ([Word6] -> ShowS) -> Show Word6
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Word6] -> ShowS
$cshowList :: [Word6] -> ShowS
show :: Word6 -> String
$cshow :: Word6 -> String
showsPrec :: Int -> Word6 -> ShowS
$cshowsPrec :: Int -> Word6 -> ShowS
Show)

-- | 'Word6' smart constructor dropping upper bits
leastSignificant6 :: Integral integral => integral -> Word6
leastSignificant6 :: integral -> Word6
leastSignificant6 = Word8 -> Word6
W6 (Word8 -> Word6) -> (integral -> Word8) -> integral -> Word6
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8
0x3F Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&.) (Word8 -> Word8) -> (integral -> Word8) -> integral -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. integral -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- | 'leastSignificant6' specialized for 'Word8'
ls6 :: Word8 -> Word6
ls6 :: Word8 -> Word6
ls6 = Word8 -> Word6
W6 (Word8 -> Word6) -> (Word8 -> Word8) -> Word8 -> Word6
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8
0x3F Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&.)

newtype Word12 = W12 Word16
    deriving (Word12 -> Word12 -> Bool
(Word12 -> Word12 -> Bool)
-> (Word12 -> Word12 -> Bool) -> Eq Word12
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Word12 -> Word12 -> Bool
$c/= :: Word12 -> Word12 -> Bool
== :: Word12 -> Word12 -> Bool
$c== :: Word12 -> Word12 -> Bool
Eq, Eq Word12
Eq Word12
-> (Word12 -> Word12 -> Ordering)
-> (Word12 -> Word12 -> Bool)
-> (Word12 -> Word12 -> Bool)
-> (Word12 -> Word12 -> Bool)
-> (Word12 -> Word12 -> Bool)
-> (Word12 -> Word12 -> Word12)
-> (Word12 -> Word12 -> Word12)
-> Ord Word12
Word12 -> Word12 -> Bool
Word12 -> Word12 -> Ordering
Word12 -> Word12 -> Word12
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
min :: Word12 -> Word12 -> Word12
$cmin :: Word12 -> Word12 -> Word12
max :: Word12 -> Word12 -> Word12
$cmax :: Word12 -> Word12 -> Word12
>= :: Word12 -> Word12 -> Bool
$c>= :: Word12 -> Word12 -> Bool
> :: Word12 -> Word12 -> Bool
$c> :: Word12 -> Word12 -> Bool
<= :: Word12 -> Word12 -> Bool
$c<= :: Word12 -> Word12 -> Bool
< :: Word12 -> Word12 -> Bool
$c< :: Word12 -> Word12 -> Bool
compare :: Word12 -> Word12 -> Ordering
$ccompare :: Word12 -> Word12 -> Ordering
$cp1Ord :: Eq Word12
Ord, Int -> Word12 -> ShowS
[Word12] -> ShowS
Word12 -> String
(Int -> Word12 -> ShowS)
-> (Word12 -> String) -> ([Word12] -> ShowS) -> Show Word12
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Word12] -> ShowS
$cshowList :: [Word12] -> ShowS
show :: Word12 -> String
$cshow :: Word12 -> String
showsPrec :: Int -> Word12 -> ShowS
$cshowsPrec :: Int -> Word12 -> ShowS
Show)

-- | 'Word12' smart constructor dropping upper bits
leastSignificant12 :: Integral integral => integral -> Word12
leastSignificant12 :: integral -> Word12
leastSignificant12 = Word16 -> Word12
W12 (Word16 -> Word12) -> (integral -> Word16) -> integral -> Word12
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word16
0xFFF Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&.) (Word16 -> Word16) -> (integral -> Word16) -> integral -> Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. integral -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- | 'leastSignificant12' specialized for 'Word16'
ls12 :: Word16 -> Word12
ls12 :: Word16 -> Word12
ls12 = Word16 -> Word12
W12 (Word16 -> Word12) -> (Word16 -> Word16) -> Word16 -> Word12
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word16
0xFFF Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&.)

newtype Word24 = W24 Word32
    deriving (Word24 -> Word24 -> Bool
(Word24 -> Word24 -> Bool)
-> (Word24 -> Word24 -> Bool) -> Eq Word24
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Word24 -> Word24 -> Bool
$c/= :: Word24 -> Word24 -> Bool
== :: Word24 -> Word24 -> Bool
$c== :: Word24 -> Word24 -> Bool
Eq, Eq Word24
Eq Word24
-> (Word24 -> Word24 -> Ordering)
-> (Word24 -> Word24 -> Bool)
-> (Word24 -> Word24 -> Bool)
-> (Word24 -> Word24 -> Bool)
-> (Word24 -> Word24 -> Bool)
-> (Word24 -> Word24 -> Word24)
-> (Word24 -> Word24 -> Word24)
-> Ord Word24
Word24 -> Word24 -> Bool
Word24 -> Word24 -> Ordering
Word24 -> Word24 -> Word24
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
min :: Word24 -> Word24 -> Word24
$cmin :: Word24 -> Word24 -> Word24
max :: Word24 -> Word24 -> Word24
$cmax :: Word24 -> Word24 -> Word24
>= :: Word24 -> Word24 -> Bool
$c>= :: Word24 -> Word24 -> Bool
> :: Word24 -> Word24 -> Bool
$c> :: Word24 -> Word24 -> Bool
<= :: Word24 -> Word24 -> Bool
$c<= :: Word24 -> Word24 -> Bool
< :: Word24 -> Word24 -> Bool
$c< :: Word24 -> Word24 -> Bool
compare :: Word24 -> Word24 -> Ordering
$ccompare :: Word24 -> Word24 -> Ordering
$cp1Ord :: Eq Word24
Ord, Int -> Word24 -> ShowS
[Word24] -> ShowS
Word24 -> String
(Int -> Word24 -> ShowS)
-> (Word24 -> String) -> ([Word24] -> ShowS) -> Show Word24
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Word24] -> ShowS
$cshowList :: [Word24] -> ShowS
show :: Word24 -> String
$cshow :: Word24 -> String
showsPrec :: Int -> Word24 -> ShowS
$cshowsPrec :: Int -> Word24 -> ShowS
Show)

-- | 'Word24' smart constructor dropping upper bits
leastSignificant24 :: Integral integral => integral -> Word24
leastSignificant24 :: integral -> Word24
leastSignificant24 = Word32 -> Word24
W24 (Word32 -> Word24) -> (integral -> Word32) -> integral -> Word24
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word32
0xFFFFFF Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&.) (Word32 -> Word32) -> (integral -> Word32) -> integral -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. integral -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- | 'leastSignificant24' specialized for 'Word32'
ls24 :: Word32 -> Word24
ls24 :: Word32 -> Word24
ls24 = Word32 -> Word24
W24 (Word32 -> Word24) -> (Word32 -> Word32) -> Word32 -> Word24
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word32
0xFFF Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&.)

newtype Word60 = W60 Word64
    deriving (Int -> Word60
Word60 -> Int
Word60 -> [Word60]
Word60 -> Word60
Word60 -> Word60 -> [Word60]
Word60 -> Word60 -> Word60 -> [Word60]
(Word60 -> Word60)
-> (Word60 -> Word60)
-> (Int -> Word60)
-> (Word60 -> Int)
-> (Word60 -> [Word60])
-> (Word60 -> Word60 -> [Word60])
-> (Word60 -> Word60 -> [Word60])
-> (Word60 -> Word60 -> Word60 -> [Word60])
-> Enum Word60
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 :: Word60 -> Word60 -> Word60 -> [Word60]
$cenumFromThenTo :: Word60 -> Word60 -> Word60 -> [Word60]
enumFromTo :: Word60 -> Word60 -> [Word60]
$cenumFromTo :: Word60 -> Word60 -> [Word60]
enumFromThen :: Word60 -> Word60 -> [Word60]
$cenumFromThen :: Word60 -> Word60 -> [Word60]
enumFrom :: Word60 -> [Word60]
$cenumFrom :: Word60 -> [Word60]
fromEnum :: Word60 -> Int
$cfromEnum :: Word60 -> Int
toEnum :: Int -> Word60
$ctoEnum :: Int -> Word60
pred :: Word60 -> Word60
$cpred :: Word60 -> Word60
succ :: Word60 -> Word60
$csucc :: Word60 -> Word60
Enum, Word60 -> Word60 -> Bool
(Word60 -> Word60 -> Bool)
-> (Word60 -> Word60 -> Bool) -> Eq Word60
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Word60 -> Word60 -> Bool
$c/= :: Word60 -> Word60 -> Bool
== :: Word60 -> Word60 -> Bool
$c== :: Word60 -> Word60 -> Bool
Eq, Eq Word60
Eq Word60
-> (Word60 -> Word60 -> Ordering)
-> (Word60 -> Word60 -> Bool)
-> (Word60 -> Word60 -> Bool)
-> (Word60 -> Word60 -> Bool)
-> (Word60 -> Word60 -> Bool)
-> (Word60 -> Word60 -> Word60)
-> (Word60 -> Word60 -> Word60)
-> Ord Word60
Word60 -> Word60 -> Bool
Word60 -> Word60 -> Ordering
Word60 -> Word60 -> Word60
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
min :: Word60 -> Word60 -> Word60
$cmin :: Word60 -> Word60 -> Word60
max :: Word60 -> Word60 -> Word60
$cmax :: Word60 -> Word60 -> Word60
>= :: Word60 -> Word60 -> Bool
$c>= :: Word60 -> Word60 -> Bool
> :: Word60 -> Word60 -> Bool
$c> :: Word60 -> Word60 -> Bool
<= :: Word60 -> Word60 -> Bool
$c<= :: Word60 -> Word60 -> Bool
< :: Word60 -> Word60 -> Bool
$c< :: Word60 -> Word60 -> Bool
compare :: Word60 -> Word60 -> Ordering
$ccompare :: Word60 -> Word60 -> Ordering
$cp1Ord :: Eq Word60
Ord, Int -> Word60 -> ShowS
[Word60] -> ShowS
Word60 -> String
(Int -> Word60 -> ShowS)
-> (Word60 -> String) -> ([Word60] -> ShowS) -> Show Word60
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Word60] -> ShowS
$cshowList :: [Word60] -> ShowS
show :: Word60 -> String
$cshow :: Word60 -> String
showsPrec :: Int -> Word60 -> ShowS
$cshowsPrec :: Int -> Word60 -> ShowS
Show)

instance Num Word60 where
    W60 Word64
x + :: Word60 -> Word60 -> Word60
+ W60 Word64
y = Word64 -> Word60
ls60 (Word64 -> Word60) -> Word64 -> Word60
forall a b. (a -> b) -> a -> b
$ Word64
x Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
y
    W60 Word64
x * :: Word60 -> Word60 -> Word60
* W60 Word64
y = Word64 -> Word60
ls60 (Word64 -> Word60) -> Word64 -> Word60
forall a b. (a -> b) -> a -> b
$ Word64
x Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
y
    abs :: Word60 -> Word60
abs = Word60 -> Word60
forall a. a -> a
id
    signum :: Word60 -> Word60
signum (W60 Word64
x) = Word64 -> Word60
W60 (Word64 -> Word60) -> Word64 -> Word60
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64
forall a. Num a => a -> a
signum Word64
x
    fromInteger :: Integer -> Word60
fromInteger = Integer -> Word60
forall integral. Integral integral => integral -> Word60
leastSignificant60
    negate :: Word60 -> Word60
negate (W60 Word64
x) = Word64 -> Word60
W60 (Word64 -> Word60) -> Word64 -> Word60
forall a b. (a -> b) -> a -> b
$ Word64
0x1000000000000000 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
x

instance Bounded Word60 where
    minBound :: Word60
minBound = Word64 -> Word60
W60 Word64
0
    maxBound :: Word60
maxBound = Word64 -> Word60
W60 Word64
0xFFFFFFFFFFFFFFF

instance Hashable Word60 where
    hashWithSalt :: Int -> Word60 -> Int
hashWithSalt = (Word60 -> Word64) -> Int -> Word60 -> Int
forall b a. Hashable b => (a -> b) -> Int -> a -> Int
hashUsing @Word64 Word60 -> Word64
coerce

-- | 'Word60' smart constructor dropping upper bits
leastSignificant60 :: Integral integral => integral -> Word60
leastSignificant60 :: integral -> Word60
leastSignificant60 = Word64 -> Word60
W60 (Word64 -> Word60) -> (integral -> Word64) -> integral -> Word60
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64
0xFFFFFFFFFFFFFFF Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&.) (Word64 -> Word64) -> (integral -> Word64) -> integral -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. integral -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- | 'leastSignificant60' specialized for 'Word64'
ls60 :: Word64 -> Word60
ls60 :: Word64 -> Word60
ls60 = Word64 -> Word60
W60 (Word64 -> Word60) -> (Word64 -> Word64) -> Word64 -> Word60
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64
0xFFFFFFFFFFFFFFF Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&.)

-- | 'Word60' smart constructor checking domain
toWord60 :: Word64 -> Maybe Word60
toWord60 :: Word64 -> Maybe Word60
toWord60 Word64
w
    | Word64
w Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
0x1000000000000000 = Word60 -> Maybe Word60
forall a. a -> Maybe a
Just (Word60 -> Maybe Word60) -> Word60 -> Maybe Word60
forall a b. (a -> b) -> a -> b
$ Word64 -> Word60
W60 Word64
w
    | Bool
otherwise              = Maybe Word60
forall a. Maybe a
Nothing

class SafeCast v w where
    safeCast :: v -> w

instance SafeCast Word2  Int     where safeCast :: Word2 -> Int
safeCast = forall b. (Integral Word8, Num b) => Word8 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word8 (Word8 -> Int) -> (Word2 -> Word8) -> Word2 -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word2 -> Word8
coerce
instance SafeCast Word2  Word4   where safeCast :: Word2 -> Word4
safeCast = Word2 -> Word4
coerce
instance SafeCast Word2  Word8   where safeCast :: Word2 -> Word8
safeCast = Word2 -> Word8
coerce
instance SafeCast Word2  Word64  where safeCast :: Word2 -> Word64
safeCast = forall b. (Integral Word8, Num b) => Word8 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word8 (Word8 -> Word64) -> (Word2 -> Word8) -> Word2 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word2 -> Word8
coerce
instance SafeCast Word4  Int     where safeCast :: Word4 -> Int
safeCast = forall b. (Integral Word8, Num b) => Word8 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word8 (Word8 -> Int) -> (Word4 -> Word8) -> Word4 -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word4 -> Word8
coerce
instance SafeCast Word4  Word64  where safeCast :: Word4 -> Word64
safeCast = forall b. (Integral Word8, Num b) => Word8 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word8 (Word8 -> Word64) -> (Word4 -> Word8) -> Word4 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word4 -> Word8
coerce
instance SafeCast Word4  Word8   where safeCast :: Word4 -> Word8
safeCast = Word4 -> Word8
coerce
instance SafeCast Word6  Int     where safeCast :: Word6 -> Int
safeCast = forall b. (Integral Word8, Num b) => Word8 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word8 (Word8 -> Int) -> (Word6 -> Word8) -> Word6 -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word6 -> Word8
coerce
instance SafeCast Word6  Word8   where safeCast :: Word6 -> Word8
safeCast = Word6 -> Word8
coerce
instance SafeCast Word6  Word60  where safeCast :: Word6 -> Word60
safeCast = forall b. Coercible Word64 b => Word64 -> b
coerce @Word64
                                                (Word64 -> Word60) -> (Word6 -> Word64) -> Word6 -> Word60
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b. (Integral Word8, Num b) => Word8 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word8 (Word8 -> Word64) -> (Word6 -> Word8) -> Word6 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word6 -> Word8
coerce
instance SafeCast Word6  Word64  where safeCast :: Word6 -> Word64
safeCast = forall b. (Integral Word8, Num b) => Word8 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word8 (Word8 -> Word64) -> (Word6 -> Word8) -> Word6 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word6 -> Word8
coerce
instance SafeCast Word8  Word32  where safeCast :: Word8 -> Word32
safeCast = Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance SafeCast Word8  Word64  where safeCast :: Word8 -> Word64
safeCast = Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance SafeCast Word12 Word64  where safeCast :: Word12 -> Word64
safeCast = forall b. (Integral Word16, Num b) => Word16 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word16 (Word16 -> Word64) -> (Word12 -> Word16) -> Word12 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word12 -> Word16
coerce
instance SafeCast Word24 Word64  where safeCast :: Word24 -> Word64
safeCast = forall b. (Integral Word32, Num b) => Word32 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word32 (Word32 -> Word64) -> (Word24 -> Word32) -> Word24 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word24 -> Word32
coerce
instance SafeCast Word24 Word32  where safeCast :: Word24 -> Word32
safeCast = Word24 -> Word32
coerce
instance SafeCast Word60 Word64  where safeCast :: Word60 -> Word64
safeCast = Word60 -> Word64
coerce
instance SafeCast Word64 Integer where safeCast :: Word64 -> Integer
safeCast = Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- Fixed are Integers inside, so have arbitrary magnitude
instance HasResolution e => SafeCast Word64 (Fixed e) where
    safeCast :: Word64 -> Fixed e
safeCast = Word64 -> Fixed e
forall a b. (Integral a, Num b) => a -> b
fromIntegral