11
11
--
12
12
13
13
module Data.Vector.Fusion.Bundle.Size (
14
- Size (.. ), smaller , larger , toMax , upperBound , lowerBound
14
+ Size (.. ), clampedSubtract , smaller , larger , toMax , upperBound , lowerBound
15
15
) where
16
16
17
17
import Data.Vector.Fusion.Util ( delay_inline )
@@ -23,19 +23,19 @@ data Size = Exact Int -- ^ Exact size
23
23
deriving ( Eq , Show )
24
24
25
25
instance Num Size where
26
- Exact m + Exact n = Exact (m + n)
27
- Exact m + Max n = Max (m + n)
26
+ Exact m + Exact n = checkedAdd Exact m n
27
+ Exact m + Max n = checkedAdd Max m n
28
28
29
- Max m + Exact n = Max (m + n)
30
- Max m + Max n = Max (m + n)
29
+ Max m + Exact n = checkedAdd Max m n
30
+ Max m + Max n = checkedAdd Max m n
31
31
32
32
_ + _ = Unknown
33
33
34
34
35
- Exact m - Exact n = Exact (m - n)
35
+ Exact m - Exact n = checkedSubtract Exact m n
36
36
Exact m - Max _ = Max m
37
37
38
- Max m - Exact n = Max (m - n)
38
+ Max m - Exact n = checkedSubtract Max m n
39
39
Max m - Max _ = Max m
40
40
Max m - Unknown = Max m
41
41
@@ -48,6 +48,34 @@ instance Num Size where
48
48
abs = error " vector: internal error abs for Bundle.size isn't defined"
49
49
signum = error " vector: internal error signum for Bundle.size isn't defined"
50
50
51
+ {-# INLINE checkedAdd #-}
52
+ checkedAdd :: (Int -> Size ) -> Int -> Int -> Size
53
+ checkedAdd con m n
54
+ | r <= m =
55
+ error $ " Data.Vector.Fusion.Bundle.Size.checkedAdd: overflow: " ++ show r
56
+ | otherwise = con r
57
+ where
58
+ r = m + n
59
+
60
+ {-# INLINE checkedSubtract #-}
61
+ checkedSubtract :: (Int -> Size ) -> Int -> Int -> Size
62
+ checkedSubtract con m n
63
+ | r < 0 =
64
+ error $ " Data.Vector.Fusion.Bundle.Size.checkedSubtract: underflow: " ++ show r
65
+ | otherwise = con r
66
+ where
67
+ r = m - n
68
+
69
+ -- | Subtract two sizes with clamping to 0, for drop-like things
70
+ {-# INLINE clampedSubtract #-}
71
+ clampedSubtract :: Size -> Size -> Size
72
+ clampedSubtract (Exact m) (Exact n) = Exact (max 0 (m - n))
73
+ clampedSubtract (Max m) (Exact n)
74
+ | m <= n = Exact 0
75
+ | otherwise = Max (m - n)
76
+ clampedSubtract (Exact m) (Max _) = Max m
77
+ clampedSubtract (Max m) (Max _) = Max m
78
+ clampedSubtract _ _ = Unknown
51
79
52
80
-- | Minimum of two size hints
53
81
smaller :: Size -> Size -> Size
0 commit comments