module Data.Vector.Fusion.Bundle.Size (
Size(..), clampedSubtract, smaller, smallerThan, larger, toMax, upperBound, lowerBound
) where
import Data.Vector.Fusion.Util ( delay_inline )
data Size = Exact {-# UNPACK #-} !Int
| Max {-# UNPACK #-} !Int
| Unknown
deriving( Size -> Size -> Bool
(Size -> Size -> Bool) -> (Size -> Size -> Bool) -> Eq Size
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Size -> Size -> Bool
== :: Size -> Size -> Bool
$c/= :: Size -> Size -> Bool
/= :: Size -> Size -> Bool
Eq, Int -> Size -> ShowS
[Size] -> ShowS
Size -> String
(Int -> Size -> ShowS)
-> (Size -> String) -> ([Size] -> ShowS) -> Show Size
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Size -> ShowS
showsPrec :: Int -> Size -> ShowS
$cshow :: Size -> String
show :: Size -> String
$cshowList :: [Size] -> ShowS
showList :: [Size] -> ShowS
Show )
instance Num Size where
Exact Int
m + :: Size -> Size -> Size
+ Exact Int
n = (Int -> Size) -> Int -> Int -> Size
checkedAdd Int -> Size
Exact Int
m Int
n
Exact Int
m + Max Int
n = (Int -> Size) -> Int -> Int -> Size
checkedAdd Int -> Size
Max Int
m Int
n
Max Int
m + Exact Int
n = (Int -> Size) -> Int -> Int -> Size
checkedAdd Int -> Size
Max Int
m Int
n
Max Int
m + Max Int
n = (Int -> Size) -> Int -> Int -> Size
checkedAdd Int -> Size
Max Int
m Int
n
Size
_ + Size
_ = Size
Unknown
Exact Int
m - :: Size -> Size -> Size
- Exact Int
n = (Int -> Size) -> Int -> Int -> Size
checkedSubtract Int -> Size
Exact Int
m Int
n
Exact Int
m - Max Int
_ = Int -> Size
Max Int
m
Max Int
m - Exact Int
n = (Int -> Size) -> Int -> Int -> Size
checkedSubtract Int -> Size
Max Int
m Int
n
Max Int
m - Max Int
_ = Int -> Size
Max Int
m
Max Int
m - Size
Unknown = Int -> Size
Max Int
m
Size
_ - Size
_ = Size
Unknown
fromInteger :: Integer -> Size
fromInteger Integer
n = Int -> Size
Exact (Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
n)
* :: Size -> Size -> Size
(*) = String -> Size -> Size -> Size
forall a. HasCallStack => String -> a
error String
"vector: internal error * for Bundle.size isn't defined"
abs :: Size -> Size
abs = String -> Size -> Size
forall a. HasCallStack => String -> a
error String
"vector: internal error abs for Bundle.size isn't defined"
signum :: Size -> Size
signum = String -> Size -> Size
forall a. HasCallStack => String -> a
error String
"vector: internal error signum for Bundle.size isn't defined"
{-# INLINE checkedAdd #-}
checkedAdd :: (Int -> Size) -> Int -> Int -> Size
checkedAdd :: (Int -> Size) -> Int -> Int -> Size
checkedAdd Int -> Size
con Int
m Int
n
| Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
m Bool -> Bool -> Bool
|| Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n =
String -> Size
forall a. HasCallStack => String -> a
error (String -> Size) -> String -> Size
forall a b. (a -> b) -> a -> b
$ String
"Data.Vector.Fusion.Bundle.Size.checkedAdd: overflow: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
r
| Bool
otherwise = Int -> Size
con Int
r
where
r :: Int
r = Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n
{-# INLINE checkedSubtract #-}
checkedSubtract :: (Int -> Size) -> Int -> Int -> Size
checkedSubtract :: (Int -> Size) -> Int -> Int -> Size
checkedSubtract Int -> Size
con Int
m Int
n
| Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
String -> Size
forall a. HasCallStack => String -> a
error (String -> Size) -> String -> Size
forall a b. (a -> b) -> a -> b
$ String
"Data.Vector.Fusion.Bundle.Size.checkedSubtract: underflow: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
r
| Bool
otherwise = Int -> Size
con Int
r
where
r :: Int
r = Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n
{-# INLINE clampedSubtract #-}
clampedSubtract :: Size -> Size -> Size
clampedSubtract :: Size -> Size -> Size
clampedSubtract (Exact Int
m) (Exact Int
n) = Int -> Size
Exact (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n))
clampedSubtract (Max Int
m) (Exact Int
n)
| Int
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n = Int -> Size
Exact Int
0
| Bool
otherwise = Int -> Size
Max (Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)
clampedSubtract (Exact Int
m) (Max Int
_) = Int -> Size
Max Int
m
clampedSubtract (Max Int
m) (Max Int
_) = Int -> Size
Max Int
m
clampedSubtract Size
_ Size
_ = Size
Unknown
smaller :: Size -> Size -> Size
{-# INLINE smaller #-}
smaller :: Size -> Size -> Size
smaller (Exact Int
m) (Exact Int
n) = Int -> Size
Exact ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
m Int
n)
smaller (Exact Int
m) (Max Int
n) = Int -> Size
Max ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
m Int
n)
smaller (Exact Int
m) Size
Unknown = Int -> Size
Max Int
m
smaller (Max Int
m) (Exact Int
n) = Int -> Size
Max ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
m Int
n)
smaller (Max Int
m) (Max Int
n) = Int -> Size
Max ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
m Int
n)
smaller (Max Int
m) Size
Unknown = Int -> Size
Max Int
m
smaller Size
Unknown (Exact Int
n) = Int -> Size
Max Int
n
smaller Size
Unknown (Max Int
n) = Int -> Size
Max Int
n
smaller Size
Unknown Size
Unknown = Size
Unknown
smallerThan :: Int -> Size -> Size
{-# INLINE smallerThan #-}
smallerThan :: Int -> Size -> Size
smallerThan Int
m (Exact Int
n) = Int -> Size
Exact ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
m Int
n)
smallerThan Int
m (Max Int
n) = Int -> Size
Max ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
m Int
n)
smallerThan Int
_ Size
Unknown = Size
Unknown
larger :: Size -> Size -> Size
{-# INLINE larger #-}
larger :: Size -> Size -> Size
larger (Exact Int
m) (Exact Int
n) = Int -> Size
Exact ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
m Int
n)
larger (Exact Int
m) (Max Int
n) | Int
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n = Int -> Size
Exact Int
m
| Bool
otherwise = Int -> Size
Max Int
n
larger (Max Int
m) (Exact Int
n) | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
m = Int -> Size
Exact Int
n
| Bool
otherwise = Int -> Size
Max Int
m
larger (Max Int
m) (Max Int
n) = Int -> Size
Max ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
m Int
n)
larger Size
_ Size
_ = Size
Unknown
toMax :: Size -> Size
toMax :: Size -> Size
toMax (Exact Int
n) = Int -> Size
Max Int
n
toMax (Max Int
n) = Int -> Size
Max Int
n
toMax Size
Unknown = Size
Unknown
lowerBound :: Size -> Int
lowerBound :: Size -> Int
lowerBound (Exact Int
n) = Int
n
lowerBound Size
_ = Int
0
upperBound :: Size -> Maybe Int
upperBound :: Size -> Maybe Int
upperBound (Exact Int
n) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
n
upperBound (Max Int
n) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
n
upperBound Size
Unknown = Maybe Int
forall a. Maybe a
Nothing