1 {-# LANGUAGE CPP #-} 2 {-# OPTIONS_GHC -fno-warn-missing-methods #-} 3 -- | 4 -- Module : Data.Text.Fusion.Internal 5 -- Copyright : (c) Roman Leshchinskiy 2008, 6 -- (c) Bryan O'Sullivan 2009 7 -- 8 -- License : BSD-style 9 -- Maintainer : bos@serpentine.com, rtomharper@googlemail.com, 10 -- duncan@haskell.org 11 -- Stability : experimental 12 -- Portability : portable 13 -- 14 -- Size hints. 15 16 module Data.Text.Fusion.Size 17 ( 18 Size 19 , exactly 20 , exactSize 21 , maxSize 22 , unknownSize 23 , smaller 24 , larger 25 , toMax 26 , upperBound 27 , lowerBound 28 , isEmpty 29 ) where 30 31 #if defined(ASSERTS) 32 import Control.Exception (assert) 33 #endif 34 35 data Size = Exact {-# UNPACK #-} !Int -- ^ Exact size. 36 | Max {-# UNPACK #-} !Int -- ^ Upper bound on size. 37 | Unknown -- ^ Unknown size. 38 deriving (-- never entered-- never enteredEq, -- never entered-- never enteredShow) 39 40 exactly :: Size -> Maybe Int 41 -- entered 200 timesexactly (Exact n) = Just n 42 exactly _ = Nothing 43 {-# INLINE exactly #-} 44 45 exactSize :: Int -> Size 46 -- entered 243 timesexactSize n = 47 #if defined(ASSERTS) 48 assert (n >= 0) 49 #endif 50 Exact n 51 {-# INLINE exactSize #-} 52 53 maxSize :: Int -> Size 54 -- entered 260,743 timesmaxSize n = 55 #if defined(ASSERTS) 56 assert (n >= 0) 57 #endif 58 Max n 59 {-# INLINE maxSize #-} 60 61 unknownSize :: Size 62 -- entered 56,320 timesunknownSize = Unknown 63 {-# INLINE unknownSize #-} 64 65 instance Num Size where 66 -- entered 52,191 times(+) = addSize 67 -- entered 26,800 times(-) = subtractSize 68 -- entered 1181 times(*) = mulSize 69 70 -- entered 100,373 timesfromInteger = f where f = Exact . fromInteger 71 {-# INLINE f #-} 72 73 addSize :: Size -> Size -> Size 74 -- entered 57,930 timesaddSize (Exact m) (Exact n) = Exact (m+n) 75 addSize (Exact m) (Max n) = Max (m+n) 76 addSize (Max m) (Exact n) = Max (m+n) 77 addSize (Max m) (Max n) = Max (m+n) 78 addSize _ _ = Unknown 79 {-# INLINE addSize #-} 80 81 subtractSize :: Size -> Size -> Size 82 -- entered 26,800 timessubtractSize (Exact m) (Exact n) = Exact (max (m-n) 0) 83 subtractSize (Exact m) (Max _) = Max m 84 subtractSize (Max m) (Exact n) = Max (max (m-n) 0) 85 subtractSize a@(Max _) (Max _) = a 86 subtractSize a@(Max _) Unknown = a 87 subtractSize _ _ = Unknown 88 {-# INLINE subtractSize #-} 89 90 mulSize :: Size -> Size -> Size 91 -- entered 1181 timesmulSize (Exact m) (Exact n) = Exact (m*n) 92 mulSize (Exact m) (Max n) = Max (m*n) 93 mulSize (Max m) (Exact n) = Max (m*n) 94 mulSize (Max m) (Max n) = Max (m*n) 95 mulSize _ _ = Unknown 96 {-# INLINE mulSize #-} 97 98 -- | Minimum of two size hints. 99 smaller :: Size -> Size -> Size 100 -- entered 10,740 timessmaller (Exact m) (Exact n) = Exact (m `min` n) 101 smaller (Exact m) (Max n) = Max (m `min` n) 102 smaller (Exact m) Unknown = Max m 103 smaller (Max m) (Exact n) = Max (m `min` n) 104 smaller (Max m) (Max n) = Max (m `min` n) 105 smaller a@(Max _) Unknown = a 106 smaller Unknown (Exact n) = Max n 107 smaller Unknown (Max n) = Max n 108 smaller Unknown Unknown = Unknown 109 {-# INLINE smaller #-} 110 111 -- | Maximum of two size hints. 112 larger :: Size -> Size -> Size 113 -- entered 6886 timeslarger (Exact m) (Exact n) = Exact (m `max` n) 114 larger a@(Exact m) b@(Max n) | m >= n = a 115 | otherwise = b 116 larger a@(Max m) b@(Exact n) | n >= m = b 117 | otherwise = a 118 larger (Max m) (Max n) = Max (m `max` n) 119 larger _ _ = Unknown 120 {-# INLINE larger #-} 121 122 -- | Convert a size hint to an upper bound. 123 toMax :: Size -> Size 124 -- never enteredtoMax (Exact n) = Max n 125 toMax a@(Max _) = a 126 toMax Unknown = Unknown 127 {-# INLINE toMax #-} 128 129 -- | Compute the minimum size from a size hint. 130 lowerBound :: Size -> Int 131 -- never enteredlowerBound (Exact n) = n 132 lowerBound _ = 0 133 {-# INLINE lowerBound #-} 134 135 -- | Compute the maximum size from a size hint, if possible. 136 upperBound :: Int -> Size -> Int 137 -- entered 146,350 timesupperBound _ (Exact n) = n 138 upperBound _ (Max n) = n 139 upperBound k _ = k 140 {-# INLINE upperBound #-} 141 142 isEmpty :: Size -> Bool 143 -- entered 72,605 timesisEmpty (Exact n) = n <= 0 144 isEmpty (Max n) = n <= 0 145 isEmpty _ = False 146 {-# INLINE isEmpty #-}