{-# LANGUAGE MultiParamTypeClasses #-} module Data.ByteString.Nums.Careless.Int where import Prelude hiding (head, tail, null) import Data.Word import Data.Int import Data.Ratio import Data.ByteString hiding (head, pack) import Data.ByteString.Internal import Data.ByteString.Char8 hiding (foldl') import qualified Data.ByteString.Lazy.Char8 as Lazy import qualified Data.ByteString.Lazy.Internal as Lazy {-| Types that can be read from integer strings. Characters that are not decimal digits are simply skipped. -} class (Num n) => Intable b n where int :: b -> n instance Intable ByteString Word8 where int = strict_int instance Intable ByteString Word16 where int = strict_int instance Intable ByteString Word32 where int = strict_int instance Intable ByteString Word64 where int = strict_int instance Intable ByteString Word where int = strict_int instance Intable ByteString Int8 where int = strict_int instance Intable ByteString Int16 where int = strict_int instance Intable ByteString Int32 where int = strict_int instance Intable ByteString Int64 where int = strict_int instance Intable ByteString Int where int = strict_int instance Intable ByteString Float where int = strict_int instance Intable ByteString Double where int = strict_int instance Intable ByteString Rational where int = strict_int instance Intable ByteString Integer where int = strict_int instance Intable Lazy.ByteString Word8 where int = lazy_int instance Intable Lazy.ByteString Word16 where int = lazy_int instance Intable Lazy.ByteString Word32 where int = lazy_int instance Intable Lazy.ByteString Word64 where int = lazy_int instance Intable Lazy.ByteString Word where int = lazy_int instance Intable Lazy.ByteString Int8 where int = lazy_int instance Intable Lazy.ByteString Int16 where int = lazy_int instance Intable Lazy.ByteString Int32 where int = lazy_int instance Intable Lazy.ByteString Int64 where int = lazy_int instance Intable Lazy.ByteString Int where int = lazy_int instance Intable Lazy.ByteString Float where int = lazy_int instance Intable Lazy.ByteString Double where int = lazy_int instance Intable Lazy.ByteString Rational where int = lazy_int instance Intable Lazy.ByteString Integer where int = lazy_int digitize :: (Num n) => (n -> n -> n) -> n -> Word8 -> n {- {-# SPECIALIZE INLINE digitize :: (Word8 -> Word8 -> Word8) -> Word8 -> Word8 -> Word8 #-} {-# SPECIALIZE INLINE digitize :: (Word16 -> Word16 -> Word16) -> Word16 -> Word8 -> Word16 #-} {-# SPECIALIZE INLINE digitize :: (Word32 -> Word32 -> Word32) -> Word32 -> Word8 -> Word32 #-} {-# SPECIALIZE INLINE digitize :: (Word64 -> Word64 -> Word64) -> Word64 -> Word8 -> Word64 #-} {-# SPECIALIZE INLINE digitize :: (Word -> Word -> Word) -> Word -> Word8 -> Word #-} {-# SPECIALIZE INLINE digitize :: (Word8 -> Word8 -> Word8) -> Word8 -> Word8 -> Word8 #-} {-# SPECIALIZE INLINE digitize :: (Int16 -> Int16 -> Int16) -> Int16 -> Word8 -> Int16 #-} {-# SPECIALIZE INLINE digitize :: (Int32 -> Int32 -> Int32) -> Int32 -> Word8 -> Int32 #-} {-# SPECIALIZE INLINE digitize :: (Int64 -> Int64 -> Int64) -> Int64 -> Word8 -> Int64 #-} {-# SPECIALIZE INLINE digitize :: (Int -> Int -> Int) -> Int -> Word8 -> Int #-} {-# SPECIALIZE INLINE digitize :: (Float -> Float -> Float) -> Float -> Word8 -> Float #-} {-# SPECIALIZE INLINE digitize :: (Double -> Double -> Double) -> Double -> Word8 -> Double #-} {-# SPECIALIZE INLINE digitize :: (Rational -> Rational -> Rational) -> Rational -> Word8 -> Rational #-} {-# SPECIALIZE INLINE digitize :: (Integer -> Integer -> Integer) -> Integer -> Word8 -> Integer #-} -} digitize op acc byte | between byte '0' '9' = (acc * 10) `op` fromIntegral (byte - c2w '0') | otherwise = acc where between b a z = b >= c2w a && byte <= c2w z strict_int bytes = foldl' (digitize op) 0 piece where (op, piece) | null bytes = ((+), empty) | head bytes == '-' = ((-), tail bytes) | head bytes == '+' = ((+), tail bytes) | otherwise = ((+), bytes) lazy_int bytes = Lazy.foldlChunks (foldl' (digitize op)) 0 piece where (op, piece) | Lazy.null bytes = ((+), Lazy.empty) | Lazy.head bytes == '-' = ((-), Lazy.tail bytes) | Lazy.head bytes == '+' = ((+), Lazy.tail bytes) | otherwise = ((+), bytes)