Use Safe Haskell if GHC >= 7.2
[darcs-mirrors/vector.git] / Data / Vector / Fusion / Stream / Size.hs
1 #if __GLASGOW_HASKELL__ >= 701
2 {-# LANGUAGE Safe #-}
3 #endif
4 -- |
5 -- Module : Data.Vector.Fusion.Stream.Size
6 -- Copyright : (c) Roman Leshchinskiy 2008-2010
7 -- License : BSD-style
8 --
9 -- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>
10 -- Stability : experimental
11 -- Portability : portable
12 --
13 -- Size hints for streams.
14 --
15
16 module Data.Vector.Fusion.Stream.Size (
17 Size(..), smaller, larger, toMax, upperBound
18 ) where
19
20 import Data.Vector.Fusion.Util ( delay_inline )
21
22 -- | Size hint
23 data Size = Exact Int -- ^ Exact size
24 | Max Int -- ^ Upper bound on the size
25 | Unknown -- ^ Unknown size
26 deriving( Eq, Show )
27
28 instance Num Size where
29 Exact m + Exact n = Exact (m+n)
30 Exact m + Max n = Max (m+n)
31
32 Max m + Exact n = Max (m+n)
33 Max m + Max n = Max (m+n)
34
35 _ + _ = Unknown
36
37
38 Exact m - Exact n = Exact (m-n)
39 Exact m - Max n = Max m
40
41 Max m - Exact n = Max (m-n)
42 Max m - Max n = Max m
43 Max m - Unknown = Max m
44
45 _ - _ = Unknown
46
47
48 fromInteger n = Exact (fromInteger n)
49
50 -- | Minimum of two size hints
51 smaller :: Size -> Size -> Size
52 {-# INLINE smaller #-}
53 smaller (Exact m) (Exact n) = Exact (delay_inline min m n)
54 smaller (Exact m) (Max n) = Max (delay_inline min m n)
55 smaller (Exact m) Unknown = Max m
56 smaller (Max m) (Exact n) = Max (delay_inline min m n)
57 smaller (Max m) (Max n) = Max (delay_inline min m n)
58 smaller (Max m) Unknown = Max m
59 smaller Unknown (Exact n) = Max n
60 smaller Unknown (Max n) = Max n
61 smaller Unknown Unknown = Unknown
62
63 -- | Maximum of two size hints
64 larger :: Size -> Size -> Size
65 {-# INLINE larger #-}
66 larger (Exact m) (Exact n) = Exact (delay_inline max m n)
67 larger (Exact m) (Max n) | m >= n = Exact m
68 | otherwise = Max n
69 larger (Max m) (Exact n) | n >= m = Exact n
70 | otherwise = Max m
71 larger (Max m) (Max n) = Max (delay_inline max m n)
72 larger _ _ = Unknown
73
74 -- | Convert a size hint to an upper bound
75 toMax :: Size -> Size
76 toMax (Exact n) = Max n
77 toMax (Max n) = Max n
78 toMax Unknown = Unknown
79
80 -- | Compute the minimum size from a size hint
81 lowerBound :: Size -> Int
82 lowerBound (Exact n) = n
83 lowerBound _ = 0
84
85 -- | Compute the maximum size from a size hint if possible
86 upperBound :: Size -> Maybe Int
87 upperBound (Exact n) = Just n
88 upperBound (Max n) = Just n
89 upperBound Unknown = Nothing
90