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