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