Z-Data 0.1.7.2 → 0.1.8.0
raw patch · 18 files changed
+315/−112 lines, 18 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Z.Data.CBytes: withCBytesListSafe :: [CBytes] -> (Ptr (Ptr Word8) -> Int -> IO a) -> IO a
- Z.Data.Parser: parse_ :: Parser a -> Bytes -> Either ParseError a
- Z.Data.Parser.Base: parse_ :: Parser a -> Bytes -> Either ParseError a
- Z.Data.Vector: ascii :: QuasiQuoter
- Z.Data.Vector.QQ: ascii :: QuasiQuoter
+ Z.Data.Array.Unaligned: unalignedSize# :: Unaligned a => a -> Int#
+ Z.Data.CBytes: withCBytesList :: [CBytes] -> (Ptr (Ptr Word8) -> Int -> IO a) -> IO a
+ Z.Data.Parser: hex' :: forall a. (Integral a, FiniteBits a) => Parser a
+ Z.Data.Parser: hex_ :: (Integral a, Bits a) => Parser a
+ Z.Data.Parser: int_ :: (Integral a, Bounded a) => Parser a
+ Z.Data.Parser: integer :: Parser Integer
+ Z.Data.Parser: parse' :: Parser a -> Bytes -> Either ParseError a
+ Z.Data.Parser: uint_ :: forall a. (Integral a, Bounded a) => Parser a
+ Z.Data.Parser.Base: parse' :: Parser a -> Bytes -> Either ParseError a
+ Z.Data.Parser.Base: takeN :: (Word8 -> Bool) -> Int -> Parser Bytes
+ Z.Data.Parser.Numeric: hex' :: forall a. (Integral a, FiniteBits a) => Parser a
+ Z.Data.Parser.Numeric: hex_ :: (Integral a, Bits a) => Parser a
+ Z.Data.Parser.Numeric: int_ :: (Integral a, Bounded a) => Parser a
+ Z.Data.Parser.Numeric: integer :: Parser Integer
+ Z.Data.Parser.Numeric: uint_ :: forall a. (Integral a, Bounded a) => Parser a
+ Z.Data.Text.Base: instance Data.CaseInsensitive.Internal.FoldCase Z.Data.Text.Base.Text
+ Z.Data.Text.ShowT: instance Z.Data.Text.ShowT.ShowT (GHC.ForeignPtr.ForeignPtr a)
+ Z.Data.Text.ShowT: instance Z.Data.Text.ShowT.ShowT (GHC.Ptr.Ptr a)
+ Z.Data.Vector: vecASCII :: QuasiQuoter
+ Z.Data.Vector.QQ: vecASCII :: QuasiQuoter
+ Z.Foreign: data RealWorld :: Type
- Z.Data.Parser: hex :: (Integral a, Bits a) => Parser a
+ Z.Data.Parser: hex :: forall a. (Integral a, FiniteBits a) => Parser a
- Z.Data.Parser: int :: Integral a => Parser a
+ Z.Data.Parser: int :: forall a. (Integral a, Bounded a) => Parser a
- Z.Data.Parser: uint :: Integral a => Parser a
+ Z.Data.Parser: uint :: forall a. (Integral a, Bounded a) => Parser a
- Z.Data.Parser.Numeric: hex :: (Integral a, Bits a) => Parser a
+ Z.Data.Parser.Numeric: hex :: forall a. (Integral a, FiniteBits a) => Parser a
- Z.Data.Parser.Numeric: int :: Integral a => Parser a
+ Z.Data.Parser.Numeric: int :: forall a. (Integral a, Bounded a) => Parser a
- Z.Data.Parser.Numeric: uint :: Integral a => Parser a
+ Z.Data.Parser.Numeric: uint :: forall a. (Integral a, Bounded a) => Parser a
Files
- ChangeLog.md +8/−0
- Z-Data.cabal +1/−1
- Z/Data/Array/Unaligned.hs +50/−2
- Z/Data/CBytes.hs +7/−7
- Z/Data/JSON/Base.hs +2/−2
- Z/Data/JSON/Value.hs +1/−1
- Z/Data/Parser.hs +4/−3
- Z/Data/Parser/Base.hs +20/−5
- Z/Data/Parser/Numeric.hs +132/−29
- Z/Data/Text/Base.hs +17/−11
- Z/Data/Text/ShowT.hs +14/−3
- Z/Data/Vector.hs +1/−1
- Z/Data/Vector/FlatIntMap.hs +2/−1
- Z/Data/Vector/FlatMap.hs +2/−1
- Z/Data/Vector/QQ.hs +19/−8
- Z/Foreign.hs +2/−4
- test/Z/Data/Parser/BaseSpec.hs +1/−1
- test/Z/Data/Parser/NumericSpec.hs +32/−32
ChangeLog.md view
@@ -1,5 +1,13 @@ # Revision history for Z-Data +## 0.1.8.0 -- 2020-10-23++* Rename `ascii` to `vecASCII` in `Z.Data.Vector.QQ` to match array QQ.+* Add `FoldCase` instance to `Text`.+* Add `hex'`, `hex_`, `uint_`, `int_`, `integer` to `Z.Data.Parser`, change `hex`, `uint`, `int` to fail in case of overflow.+* Add `takeN` to `Z.Data.Parser`.+* Rename `withCBytesListSafe` to `withCBytesList` to match rest of the module.+ ## 0.1.7.2 -- 2020-10-17 * Add `withPrimArrayListUnsafe`, `withPrimArrayListSafe`, `withCBytesUnsafe`, `withCBytesListSafe`.
Z-Data.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: Z-Data-version: 0.1.7.2+version: 0.1.8.0 synopsis: Array, vector and text description: This package provides array, slice and text operations license: BSD-3-Clause
Z/Data/Array/Unaligned.hs view
@@ -50,11 +50,19 @@ -- @ -- class Unaligned a where- {-# MINIMAL unalignedSize, indexWord8ArrayAs#, writeWord8ArrayAs#, readWord8ArrayAs# |- unalignedSize, indexBA, peekMBA, pokeMBA #-}+ {-# MINIMAL (unalignedSize# | unalignedSize),+ (indexWord8ArrayAs# | indexBA),+ (writeWord8ArrayAs# | peekMBA),+ (readWord8ArrayAs# | pokeMBA) #-} -- | byte size unalignedSize :: a -> Int+ {-# INLINE unalignedSize #-}+ unalignedSize a = I# (unalignedSize# a) + unalignedSize# :: a -> Int#+ {-# INLINE unalignedSize# #-}+ unalignedSize# a = case unalignedSize a of I# siz_a# -> siz_a#+ -- | index element off byte array with offset in bytes(maybe unaligned) indexWord8ArrayAs# :: ByteArray# -> Int# -> a {-# INLINE indexWord8ArrayAs# #-}@@ -895,6 +903,46 @@ in BE (C# (chr# x#)) #endif +{- not really useful+instance (Unaligned a, Unaligned b) => Unaligned (a, b) where+ {-# INLINE unalignedSize #-}+ unalignedSize (a, b) = unalignedSize a + unalignedSize b+ {-# INLINE writeWord8ArrayAs# #-}+ writeWord8ArrayAs# mba# i# (a, b) s0 =+ let s1 = writeWord8ArrayAs# mba# i# a s0+ in writeWord8ArrayAs# mba# (i# +# unalignedSize# a) b s1+ {-# INLINE readWord8ArrayAs# #-}+ readWord8ArrayAs# mba# i# s0 =+ let !(# s1, a #) = readWord8ArrayAs# mba# i# s0+ !(# s2, b #) = readWord8ArrayAs# mba# (i# +# unalignedSize# a) s1+ in (# s2, (a, b) #)+ {-# INLINE indexWord8ArrayAs# #-}+ indexWord8ArrayAs# ba# i# =+ let a = indexWord8ArrayAs# ba# i#+ b = indexWord8ArrayAs# ba# (i# +# unalignedSize# a)+ in (a, b)++instance (Unaligned a, Unaligned b, Unaligned c) => Unaligned (a, b, c) where+ {-# INLINE unalignedSize #-}+ unalignedSize (a, b, c) = unalignedSize a + unalignedSize b + unalignedSize c+ {-# INLINE writeWord8ArrayAs# #-}+ writeWord8ArrayAs# mba# i# (a, b, c) s0 =+ let s1 = writeWord8ArrayAs# mba# i# a s0+ s2 = writeWord8ArrayAs# mba# (i# +# unalignedSize# a) b s1+ in writeWord8ArrayAs# mba# (i# +# unalignedSize# a +# unalignedSize# b) c s2+ {-# INLINE readWord8ArrayAs# #-}+ readWord8ArrayAs# mba# i# s0 =+ let !(# s1, a #) = readWord8ArrayAs# mba# i# s0+ !(# s2, b #) = readWord8ArrayAs# mba# (i# +# unalignedSize# a) s1+ !(# s3, c #) = readWord8ArrayAs# mba# (i# +# unalignedSize# a +# unalignedSize# b) s2+ in (# s3, (a, b, c) #)+ {-# INLINE indexWord8ArrayAs# #-}+ indexWord8ArrayAs# ba# i# =+ let a = indexWord8ArrayAs# ba# i#+ b = indexWord8ArrayAs# ba# (i# +# unalignedSize# a)+ c = indexWord8ArrayAs# ba# (i# +# unalignedSize# a +# unalignedSize# b)+ in (a, b, c)+-} -------------------------------------------------------------------------------- -- Prim instances for newtypes in Foreign.C.Types
Z/Data/CBytes.hs view
@@ -23,7 +23,7 @@ , empty, singleton, append, concat, intercalate, intercalateElem , fromCString, fromCStringN , withCBytesUnsafe, withCBytes, allocCBytesUnsafe, allocCBytes- , withCBytesListUnsafe, withCBytesListSafe+ , withCBytesListUnsafe, withCBytesList -- * re-export , CString , V.c2w, V.w2c@@ -79,7 +79,7 @@ -- -- 'CBytes' don't support O(1) slicing, it's not suitable to use it to store large byte -- chunk, If you need advance editing, convert 'CBytes' to 'V.Bytes' with 'CB' pattern or--- 'toBytes'\/'fromBytes', then use vector combinators.+-- 'toBytes' \/ 'fromBytes', then use vector combinators. -- -- When textual represatation is needed e.g. converting to 'String', 'T.Text', 'Show' instance, etc., -- we assume 'CBytes' using UTF-8 encodings, 'CBytes' can be used with @OverloadedString@,@@ -94,7 +94,7 @@ { -- | Convert to a @\\NUL@ terminated 'PrimArray', --- -- there's an invariance that this array never contains extra @\\NUL@ except terminator.+ -- There's an invariance that this array never contains extra @\\NUL@ except terminator. rawPrimArray :: PrimArray Word8 } @@ -480,7 +480,7 @@ -- | Write 'CBytes' \'s byte sequence to buffer. ----- This function is different from 'ShowT' instance in that it directly write byte sequence without+-- This function is different from 'T.ShowT' instance in that it directly write byte sequence without -- checking if it's UTF8 encoded. toBuilder :: CBytes -> B.Builder () toBuilder = B.bytes . toBytes@@ -552,9 +552,9 @@ -- | Pass 'CBytes' list to foreign function as a @const char**@. -- -- Check "Z.Foreign" module for more detail on how to marshall params in C side.-withCBytesListSafe :: [CBytes] -> (Ptr (Ptr Word8) -> Int -> IO a) -> IO a-{-# INLINABLE withCBytesListSafe #-}-withCBytesListSafe pas = withPrimArrayListSafe (List.map rawPrimArray pas)+withCBytesList :: [CBytes] -> (Ptr (Ptr Word8) -> Int -> IO a) -> IO a+{-# INLINABLE withCBytesList #-}+withCBytesList pas = withPrimArrayListSafe (List.map rawPrimArray pas) -- | Create a 'CBytes' with IO action. --
Z/Data/JSON/Base.hs view
@@ -119,7 +119,7 @@ -- | Decode a JSON doc, only trailing JSON whitespace are allowed. decode' :: FromValue a => V.Bytes -> Either DecodeError a {-# INLINE decode' #-}-decode' bs = case P.parse_ (JV.value <* JV.skipSpaces <* P.endOfInput) bs of+decode' bs = case P.parse' (JV.value <* JV.skipSpaces <* P.endOfInput) bs of Left pErr -> Left (Left pErr) Right v -> case convert fromValue v of Left cErr -> Left (Right cErr)@@ -948,7 +948,7 @@ fromValue = withFlatMapR "Z.Data.Vector.FlatIntMap.FlatIntMap" $ \ m -> let kvs = FM.sortedKeyValues m in FIM.packVectorR <$> (forM kvs $ \ (k, v) -> do- case P.parse_ P.int (T.getUTF8Bytes k) of+ case P.parse' P.int (T.getUTF8Bytes k) of Right k' -> do v' <- fromValue v <?> Key k return (V.IPair k' v')
Z/Data/JSON/Value.hs view
@@ -137,7 +137,7 @@ -- bytes left, parsing will fail. parseValue' :: V.Bytes -> Either P.ParseError Value {-# INLINE parseValue' #-}-parseValue' = P.parse_ (value <* skipSpaces <* P.endOfInput)+parseValue' = P.parse' (value <* skipSpaces <* P.endOfInput) -- | Increamental parse 'Value' without consuming trailing bytes. parseValueChunks :: Monad m => m V.Bytes -> V.Bytes -> m (V.Bytes, Either P.ParseError Value)
Z/Data/Parser.hs view
@@ -30,7 +30,7 @@ , Parser , (<?>) -- * Running a parser- , parse, parse_, parseChunk, parseChunks, finishParsing+ , parse, parse', parseChunk, parseChunks, finishParsing , runAndKeepTrack, match -- * Basic parsers , ensureN, endOfInput, atEnd@@ -43,9 +43,10 @@ , text -- * Numeric parsers -- ** Decimal- , uint, int+ , uint, int, integer+ , uint_, int_ -- ** Hex- , hex+ , hex, hex', hex_ -- ** Fractional , rational , float, double
Z/Data/Parser/Base.hs view
@@ -19,7 +19,7 @@ , Parser(..) , (<?>) -- * Running a parser- , parse, parse_, parseChunk, parseChunks, finishParsing+ , parse, parse', parseChunk, parseChunks, finishParsing , runAndKeepTrack, match -- * Basic parsers , ensureN, endOfInput, atEnd@@ -28,7 +28,7 @@ -- * More parsers , scan, scanChunks, peekMaybe, peek, satisfy, satisfyWith , word8, char8, skipWord8, endOfLine, skip, skipWhile, skipSpaces- , take, takeTill, takeWhile, takeWhile1, bytes, bytesCI+ , take, takeN, takeTill, takeWhile, takeWhile1, bytes, bytesCI , text -- * Misc , isSpace@@ -150,9 +150,9 @@ fail' msg = Parser (\ kf _ inp -> kf [msg] inp) -- | Parse the complete input, without resupplying-parse_ :: Parser a -> V.Bytes -> Either ParseError a-{-# INLINE parse_ #-}-parse_ (Parser p) inp = snd $ finishParsing (p Failure Success inp)+parse' :: Parser a -> V.Bytes -> Either ParseError a+{-# INLINE parse' #-}+parse' (Parser p) inp = snd $ finishParsing (p Failure Success inp) -- | Parse the complete input, without resupplying, return the rest bytes parse :: Parser a -> V.Bytes -> (V.Bytes, Either ParseError a)@@ -617,6 +617,21 @@ if V.null bs then fail' "Z.Data.Parser.Base.takeWhile1: no satisfied byte" else return bs++-- | Similar to 'take', but requires the predicate to succeed on next N bytes+-- of input, and take N bytes(no matter if N+1 byte satisfy predicate or not).+--+takeN :: (Word8 -> Bool) -> Int -> Parser V.Bytes+{-# INLINE takeN #-}+takeN p n = do+ bs <- take n+ if go bs 0+ then return bs+ else fail' "Z.Data.Parser.Base.takeWhileN: byte does not satisfy"+ where+ go bs@(V.PrimVector _ _ l) !i+ | i < l = p (V.unsafeIndex bs i) && go bs (i+1)+ | otherwise = True -- | @bytes s@ parses a sequence of bytes that identically match @s@. --
Z/Data/Parser/Numeric.hs view
@@ -13,9 +13,10 @@ module Z.Data.Parser.Numeric ( -- * Decimal- uint, int+ uint, int, integer+ , uint_, int_ -- * Hex- , hex+ , hex, hex', hex_ -- * Fractional , rational , float, double@@ -48,7 +49,8 @@ import qualified Z.Data.Vector.Base as V import qualified Z.Data.Vector.Extra as V -#define WORD64_MAX_DIGITS_LEN 18+#define WORD64_MAX_DIGITS_LEN 19+#define INT64_MAX_DIGITS_LEN 18 #define PLUS 43 #define MINUS 45@@ -57,17 +59,48 @@ #define BIG_E 69 #define C_0 48 --- | Parse and decode an unsigned hex number. The hex digits+-- | Parse and decode an unsigned hex number, fail in case of overflow. The hex digits -- @\'a\'@ through @\'f\'@ may be upper or lower case. -- -- This parser does not accept a leading @\"0x\"@ string, and consider--- sign bit part of the binary hex nibbles, i.e.--- 'parse hex "0xFF" == Right (-1 :: Int8)'+-- sign bit part of the binary hex nibbles, e.g. ---hex :: (Integral a, Bits a) => Parser a+-- >>> parse' hex "FF" == Right (-1 :: Int8)+-- >>> parse' hex "7F" == Right (127 :: Int8)+-- >>> parse' hex "7Ft" == Right (127 :: Int8)+-- >>> parse' hex "7FF" == Left ["Z.Data.Parser.Numeric.hex","hex numeric number overflow"]+--+hex :: forall a.(Integral a, FiniteBits a) => Parser a {-# INLINE hex #-}-hex = "Z.Data.Parser.Numeric.hex" <?> hexLoop 0 <$> P.takeWhile1 isHexDigit+hex = "Z.Data.Parser.Numeric.hex" <?> do+ bs <- P.takeWhile1 isHexDigit+ if V.length bs <= finiteBitSize (undefined :: a) `unsafeShiftR` 2+ then return (hexLoop 0 bs)+ else P.fail' "hex numeric number overflow" +-- | Same with 'hex', but only take as many as (bit_size/4) bytes.+--+-- >>> parse' hex "FF" == Right (-1 :: Int8)+-- >>> parse' hex "7F" == Right (127 :: Int8)+-- >>> parse' hex "7Ft" == Right (127 :: Int8)+-- >>> parse' hex "7FF" == Right (127 :: Int8)+hex' :: forall a.(Integral a, FiniteBits a) => Parser a+{-# INLINE hex' #-}+hex' = "Z.Data.Parser.Numeric.hex'" <?> do+ hexLoop 0 <$>+ P.takeN isHexDigit (finiteBitSize (undefined :: a) `unsafeShiftR` 2)+ where++-- | Same with 'hex', but silently cast in case of overflow.+--+-- >>> parse' hex "FF" == Right (-1 :: Int8)+-- >>> parse' hex "7F" == Right (127 :: Int8)+-- >>> parse' hex "7Ft" == Right (127 :: Int8)+-- >>> parse' hex "7FF" == Right (-1 :: Int8)+hex_ :: (Integral a, Bits a) => Parser a+{-# INLINE hex_ #-}+hex_ = "Z.Data.Parser.Numeric.hex_" <?> hexLoop 0 <$> P.takeWhile1 isHexDigit+ -- | decode hex digits sequence within an array. hexLoop :: (Integral a, Bits a) => a -- ^ accumulator, usually start from 0@@ -87,12 +120,33 @@ {-# INLINE isHexDigit #-} isHexDigit w = w - 48 <= 9 || w - 65 <= 5 || w - 97 <= 5 +-- | Same with 'uint', but sliently cast in case of overflow.+uint_ :: forall a. (Integral a, Bounded a) => Parser a+{-# INLINE uint_ #-}+uint_ = "Z.Data.Parser.Numeric.uint_" <?> decLoop 0 <$> P.takeWhile1 isDigit+ -- | Parse and decode an unsigned decimal number.-uint :: (Integral a) => Parser a+--+-- Will fail in case of overflow.+uint :: forall a. (Integral a, Bounded a) => Parser a {-# INLINE uint #-}-uint = "Z.Data.Parser.Numeric.uint" <?> decLoop 0 <$> P.takeWhile1 isDigit+uint = "Z.Data.Parser.Numeric.uint" <?> do+ bs <- P.takeWhile1 isDigit+ if V.length bs <= WORD64_MAX_DIGITS_LEN+ then do+ let w64 = decLoop @Word64 0 bs+ if w64 <= fromIntegral (maxBound :: a)+ then return (fromIntegral w64)+ else P.fail' "decimal numeric value overflow"+ else do+ let w64 = decLoop @Integer 0 bs+ if w64 <= fromIntegral (maxBound :: a)+ then return (fromIntegral w64)+ else P.fail' "decimal numeric value overflow" --- | decode digits sequence within an array.+-- | Decode digits sequence within an array.+--+-- This function may overflow if result can't fit into type. decLoop :: Integral a => a -- ^ accumulator, usually start from 0 -> V.Bytes@@ -117,17 +171,66 @@ -- | Parse a decimal number with an optional leading @\'+\'@ or @\'-\'@ sign -- character.-int :: (Integral a) => Parser a+--+-- This parser will fail if overflow happens.+int :: forall a. (Integral a, Bounded a) => Parser a {-# INLINE int #-} int = "Z.Data.Parser.Numeric.int" <?> do w <- P.peek if w == MINUS- then P.skipWord8 *> (negate <$> uint')- else if w == PLUS then P.skipWord8 *> uint' else uint'+ then P.skipWord8 *> loopNe+ else if w == PLUS then P.skipWord8 *> loop else loop where- -- strip uint's message- uint' = decLoop 0 <$> P.takeWhile1 isDigit+ loop = do+ bs <- P.takeWhile1 isDigit+ if V.length bs <= WORD64_MAX_DIGITS_LEN+ then do+ let w64 = decLoop @Word64 0 bs+ if w64 <= fromIntegral (maxBound :: a)+ then return (fromIntegral w64)+ else P.fail' "decimal numeric value overflow"+ else do+ let w64 = decLoop @Integer 0 bs+ if w64 <= fromIntegral (maxBound :: a)+ then return (fromIntegral w64)+ else P.fail' "decimal numeric value overflow"+ loopNe = do+ bs <- P.takeWhile1 isDigit+ if V.length bs <= INT64_MAX_DIGITS_LEN+ then do+ let i64 = negate (decLoop @Int64 0 bs)+ if i64 >= fromIntegral (minBound :: a)+ then return (fromIntegral i64)+ else P.fail' "decimal numeric value overflow"+ else do+ let i64 = negate (decLoop @Integer 0 bs)+ if i64 >= fromIntegral (minBound :: a)+ then return (fromIntegral i64)+ else P.fail' "decimal numeric value overflow" +-- | Same with 'int', but sliently cast if overflow happens.+int_ :: (Integral a, Bounded a) => Parser a+{-# INLINE int_ #-}+int_ = "Z.Data.Parser.Numeric.int_" <?> do+ w <- P.peek+ if w == MINUS+ then P.skipWord8 *> (negate <$> loop)+ else if w == PLUS then P.skipWord8 *> loop else loop+ where+ loop = decLoop 0 <$> P.takeWhile1 isDigit++-- | Parser specifically optimized for 'Integer'.+--+integer :: Parser Integer+integer = "Z.Data.Parser.Numeric.integer" <?> do+ w <- P.peek+ if w == MINUS+ then P.skipWord8 *> (negate <$> integer')+ else if w == PLUS then P.skipWord8 *> integer' else integer'+ where+ -- strip integer's message+ integer' = decLoopIntegerFast <$> P.takeWhile1 isDigit+ -- | Parse a rational number. -- -- The syntax accepted by this parser is the same as for 'double'.@@ -153,19 +256,19 @@ -- -- Examples with behaviour identical to 'read': ----- >parse_ double "3" == ("", Right 3.0)--- >parse_ double "3.1" == ("", Right 3.1)--- >parse_ double "3e4" == ("", Right 30000.0)--- >parse_ double "3.1e4" == ("", Right 31000.0)+-- >parse' double "3" == ("", Right 3.0)+-- >parse' double "3.1" == ("", Right 3.1)+-- >parse' double "3e4" == ("", Right 30000.0)+-- >parse' double "3.1e4" == ("", Right 31000.0) ----- >parse_ double ".3" == (".3", Left ParserError)--- >parse_ double "e3" == ("e3", Left ParserError)+-- >parse' double ".3" == (".3", Left ParserError)+-- >parse' double "e3" == ("e3", Left ParserError) -- -- Examples of differences from 'read': ----- >parse_ double "3.foo" == (".foo", Right 3.0)--- >parse_ double "3e" == ("e", Right 3.0)--- >parse_ double "-3e" == ("e", Right -3.0)+-- >parse' double "3.foo" == (".foo", Right 3.0)+-- >parse' double "3e" == ("e", Right 3.0)+-- >parse' double "-3e" == ("e", Right -3.0) -- -- This function does not accept string representations of \"NaN\" or -- \"Infinity\".@@ -252,13 +355,13 @@ -- non-backtrack strict number parser separately using LL(1) lookahead. This parser also -- agree with 'read' on extra dot or e handling: ----- >parse_ double "3.foo" == Left ParseError--- >parse_ double "3e" == Left ParseError+-- >parse' double "3.foo" == Left ParseError+-- >parse' double "3e" == Left ParseError -- -- Leading zeros or @+@ sign is also not allowed: ----- >parse_ double "+3.14" == Left ParseError--- >parse_ double "0014" == Left ParseError+-- >parse' double "+3.14" == Left ParseError+-- >parse' double "0014" == Left ParseError -- -- If you have a similar grammer, you can use this parser to save considerable time. --
Z/Data/Text/Base.hs view
@@ -119,27 +119,28 @@ import Control.Monad.ST import Control.Monad import Data.Bits-import Data.Char hiding (toLower, toUpper, toTitle)-import Data.Foldable (foldlM)-import Data.Hashable (Hashable(..))-import qualified Data.List as List+import Data.Char hiding (toLower, toUpper, toTitle)+import qualified Data.CaseInsensitive as CI+import Data.Foldable (foldlM)+import Data.Hashable (Hashable(..))+import qualified Data.List as List import Data.Primitive.PrimArray import Data.Typeable import Data.Word-import Foreign.C.Types (CSize(..))+import Foreign.C.Types (CSize(..)) import GHC.Exts import GHC.Types import GHC.Stack-import GHC.CString (unpackCString#, unpackCStringUtf8#)+import GHC.CString (unpackCString#, unpackCStringUtf8#) import Z.Data.Array import Z.Data.Text.UTF8Codec import Z.Data.Text.UTF8Rewind-import Z.Data.Vector.Base (Bytes, PrimVector(..), c_strlen)-import qualified Z.Data.Vector.Base as V-import qualified Z.Data.Vector.Search as V-import System.IO.Unsafe (unsafeDupablePerformIO)+import Z.Data.Vector.Base (Bytes, PrimVector(..), c_strlen)+import qualified Z.Data.Vector.Base as V+import qualified Z.Data.Vector.Search as V+import System.IO.Unsafe (unsafeDupablePerformIO) -import Prelude hiding (concat, concatMap,+import Prelude hiding (concat, concatMap, elem, notElem, null, length, map, foldl, foldl1, foldr, foldr1, maximum, minimum, product, sum,@@ -200,6 +201,11 @@ instance IsString Text where {-# INLINE fromString #-} fromString = pack++-- | case fold with default locale.+instance CI.FoldCase Text where+ {-# INLINE foldCase #-}+ foldCase = caseFold -- | /O(n)/ Get the nth codepoint from 'Text', throw 'IndexOutOfTextRange' -- when out of bound.
Z/Data/Text/ShowT.hs view
@@ -17,7 +17,7 @@ module Z.Data.Text.ShowT ( -- * ShowT class- ShowT(..), showT, toBuilder, toBytes, toString+ ShowT(..), showT, toBuilder, toBytes, toString -- * Textual Builder , TextBuilder , getBuilder@@ -65,14 +65,15 @@ import Data.Proxy (Proxy(..)) import Data.Ratio (Ratio, numerator, denominator) import Data.Tagged (Tagged (..))-import Data.Word import qualified Data.Semigroup as Semigroup import Data.Typeable import Foreign.C.Types import GHC.Exts-import GHC.Natural+import GHC.ForeignPtr import GHC.Generics+import GHC.Natural import GHC.Stack+import GHC.Word import Data.Version import System.Exit import Test.QuickCheck.Arbitrary (Arbitrary(..), CoArbitrary(..))@@ -651,7 +652,17 @@ deriving newtype instance ShowT CFloat deriving newtype instance ShowT CDouble +instance ShowT (Ptr a) where+ {-# INLINE toTextBuilder #-}+ toTextBuilder _ (Ptr a) =+ "0x" >> hex (W# (int2Word#(addr2Int# a)))+instance ShowT (ForeignPtr a) where+ {-# INLINE toTextBuilder #-}+ toTextBuilder _ (ForeignPtr a _) =+ "0x" >> hex (W# (int2Word#(addr2Int# a)))+ deriving anyclass instance ShowT ExitCode+ deriving anyclass instance ShowT a => ShowT (Semigroup.Min a) deriving anyclass instance ShowT a => ShowT (Semigroup.Max a) deriving anyclass instance ShowT a => ShowT (Semigroup.First a)
Z/Data/Vector.hs view
@@ -148,7 +148,7 @@ , Radix(..) , RadixDown(..) -- * QuasiQuoters- , ascii+ , vecASCII , vecW8, vecW16, vecW32, vecW64, vecWord , vecI8, vecI16, vecI32, vecI64, vecInt -- * Misc
Z/Data/Vector/FlatIntMap.hs view
@@ -325,7 +325,8 @@ foldlWithKey' f a (FlatIntMap vs) = V.foldl' (\ a' (V.IPair k v) -> f a' k v) a vs -- | /O(n)/.--- @'traverseWithKey' f s == 'pack' <$> 'traverse' (\(k, v) -> (,) k <$> f k v) ('unpack' m)@+--+-- @'traverseWithKey' f s == 'pack' \<$\> 'traverse' (\(k, v) -> (,) k \<$\> f k v) ('unpack' m)@ -- That is, behaves exactly like a regular 'traverse' except that the traversing -- function also has access to the key associated with a value. traverseWithKey :: Applicative t => (Int -> a -> t b) -> FlatIntMap a -> t (FlatIntMap b)
Z/Data/Vector/FlatMap.hs view
@@ -326,7 +326,8 @@ foldlWithKey' f a (FlatMap vs) = V.foldl' (\ a' (k,v) -> f a' k v) a vs -- | /O(n)/.--- @'traverseWithKey' f s == 'pack' <$> 'traverse' (\(k, v) -> (,) k <$> f k v) ('unpack' m)@+--+-- @'traverseWithKey' f s == 'pack' \<$\> 'traverse' (\(k, v) -> (,) k \<$>\ f k v) ('unpack' m)@ -- That is, behaves exactly like a regular 'traverse' except that the traversing -- function also has access to the key associated with a value. traverseWithKey :: Applicative t => (k -> a -> t b) -> FlatMap k a -> t (FlatMap k b)
Z/Data/Vector/QQ.hs view
@@ -7,13 +7,25 @@ Stability : experimental Portability : non-portable -This module provides functions for writing vector literals using 'QuasiQuote'.+This module provides functions for writing vector literals using 'QuasiQuote' similar to "Z.Data.Array.QQ" module. +@+> :set -XQuasiQuotes+> :t [vecASCII|asdfg|]+[vecASCII|asdfg|] :: Z.Data.Vector.Base.PrimVector GHC.Word.Word8+> [vecASCII|asdfg|]+[97,115,100,102,103]+> :t [vecI16|1,2,3,4,5|]+[vecI16|1,2,3,4,5|] :: Z.Data.Vector.Base.PrimVector GHC.Int.Int16+> [vecI16|1,2,3,4,5|]+[1,2,3,4,5]+@+ -} module Z.Data.Vector.QQ ( -- * QuasiQuoters- ascii+ vecASCII , vecW8, vecW16, vecW32, vecW64, vecWord , vecI8, vecI16, vecI32, vecI64, vecInt ) where@@ -25,12 +37,12 @@ -------------------------------------------------------------------------------- -- Quoters -ascii :: QQ.QuasiQuoter-ascii = QQ.QuasiQuoter+vecASCII :: QQ.QuasiQuoter+vecASCII = QQ.QuasiQuoter (asciiLiteral $ \ len addr -> [| PrimVector (QQ.word8ArrayFromAddr $(len) $(addr)) 0 $(len) |])- (error "Cannot use ascii as a pattern")- (error "Cannot use ascii as a type")- (error "Cannot use ascii as a dec")+ (error "Cannot use vecASCII as a pattern")+ (error "Cannot use vecASCII as a type")+ (error "Cannot use vecASCII as a dec") vecW8 :: QQ.QuasiQuoter vecW8 = QQ.QuasiQuoter@@ -107,4 +119,3 @@ (error "Cannot use vecInt as a pattern") (error "Cannot use vecInt as a type") (error "Cannot use vecInt as a dec")-
Z/Foreign.hs view
@@ -82,6 +82,7 @@ , castPtr , fromNullTerminated, fromPtr, fromPrimPtr -- ** re-export+ , RealWorld , module Data.Primitive.ByteArray , module Data.Primitive.PrimArray , module Foreign.C.Types@@ -130,8 +131,6 @@ -- USE THIS TYPE WITH UNSAFE FFI CALL ONLY. A 'MutableByteArray#' COULD BE MOVED BY GC DURING SAFE FFI CALL. type MBA# a = MutableByteArray# RealWorld -- -- | Type alias for 'ArrayArray#'. -- -- Describe a array of 'ByteArray#' which we are going to pass across FFI. Use this type with @UnliftedFFITypes@@@ -430,7 +429,7 @@ -- | Copy some bytes from a null terminated pointer(without copying the null terminator). ----- You should consider using 'Z.Data.CBytes' type for storing NULL terminated bytes first,+-- You should consider using 'Z.Data.CBytes.CBytes' type for storing NULL terminated bytes first, -- This method is provided if you really need to read 'Bytes', there's no encoding guarantee, -- result could be any bytes sequence. fromNullTerminated :: Ptr a -> IO Bytes@@ -466,4 +465,3 @@ copyPtrToMutablePrimArray marr 0 (Ptr addr#) len arr <- unsafeFreezePrimArray marr return (PrimVector arr 0 len)-
test/Z/Data/Parser/BaseSpec.hs view
@@ -20,7 +20,7 @@ parse' :: P.Parser a -> [Word8] -> Maybe a-parse' p str = case P.parse_ p (V.pack str) of+parse' p str = case P.parse' p (V.pack str) of Left msg -> Nothing Right a -> Just a
test/Z/Data/Parser/NumericSpec.hs view
@@ -26,74 +26,74 @@ spec = do describe "numeric parsers roundtrip" . modifyMaxSuccess (*10) . modifyMaxSize (*10) $ do prop "positive hex roundtrip" $ \ i ->- P.parse_ P.hex (B.buildBytes (B.hex i)) === Right (i :: Int)+ P.parse' P.hex (B.buildBytes (B.hex i)) === Right (i :: Int) prop "positive hex roundtrip" $ \ i ->- P.parse_ P.hex (B.buildBytes (B.hex i)) === Right (i :: Int64)+ P.parse' P.hex (B.buildBytes (B.hex i)) === Right (i :: Int64) prop "positive hex roundtrip" $ \ i ->- P.parse_ P.hex (B.buildBytes (B.hex i)) === Right (i :: Int32)+ P.parse' P.hex (B.buildBytes (B.hex i)) === Right (i :: Int32) prop "positive hex roundtrip" $ \ i ->- P.parse_ P.hex (B.buildBytes (B.hex i)) === Right (i :: Int16)+ P.parse' P.hex (B.buildBytes (B.hex i)) === Right (i :: Int16) prop "positive hex roundtrip" $ \ i ->- P.parse_ P.hex (B.buildBytes (B.hex i)) === Right (i :: Int8)+ P.parse' P.hex (B.buildBytes (B.hex i)) === Right (i :: Int8) prop "positive hex roundtrip" $ \ i ->- P.parse_ P.hex (B.buildBytes (B.hex i)) === Right (i :: Word)+ P.parse' P.hex (B.buildBytes (B.hex i)) === Right (i :: Word) prop "positive hex roundtrip" $ \ i ->- P.parse_ P.hex (B.buildBytes (B.hex i)) === Right (i :: Word64)+ P.parse' P.hex (B.buildBytes (B.hex i)) === Right (i :: Word64) prop "positive hex roundtrip" $ \ i ->- P.parse_ P.hex (B.buildBytes (B.hex i)) === Right (i :: Word32)+ P.parse' P.hex (B.buildBytes (B.hex i)) === Right (i :: Word32) prop "positive hex roundtrip" $ \ i ->- P.parse_ P.hex (B.buildBytes (B.hex i)) === Right (i :: Word16)+ P.parse' P.hex (B.buildBytes (B.hex i)) === Right (i :: Word16) prop "positive hex roundtrip" $ \ i ->- P.parse_ P.hex (B.buildBytes (B.hex i)) === Right (i :: Word8)+ P.parse' P.hex (B.buildBytes (B.hex i)) === Right (i :: Word8) prop "positive int roundtrip" $ \ (Positive i) ->- P.parse_ P.uint (B.buildBytes (B.int i)) === Right (i :: Int)+ P.parse' P.uint (B.buildBytes (B.int i)) === Right (i :: Int) prop "positive int roundtrip" $ \ (Positive i) ->- P.parse_ P.uint (B.buildBytes (B.int i)) === Right (i :: Int64)+ P.parse' P.uint (B.buildBytes (B.int i)) === Right (i :: Int64) prop "positive int roundtrip" $ \ (Positive i) ->- P.parse_ P.uint (B.buildBytes (B.int i)) === Right (i :: Int32)+ P.parse' P.uint (B.buildBytes (B.int i)) === Right (i :: Int32) prop "positive int roundtrip" $ \ (Positive i) ->- P.parse_ P.uint (B.buildBytes (B.int i)) === Right (i :: Int16)+ P.parse' P.uint (B.buildBytes (B.int i)) === Right (i :: Int16) prop "positive int roundtrip" $ \ (Positive i) ->- P.parse_ P.uint (B.buildBytes (B.int i)) === Right (i :: Int8)+ P.parse' P.uint (B.buildBytes (B.int i)) === Right (i :: Int8) prop "positive int roundtrip" $ \ (Positive i) ->- P.parse_ P.uint (B.buildBytes (B.int i)) === Right (i :: Word)+ P.parse' P.uint (B.buildBytes (B.int i)) === Right (i :: Word) prop "positive int roundtrip" $ \ (Positive i) ->- P.parse_ P.uint (B.buildBytes (B.int i)) === Right (i :: Word64)+ P.parse' P.uint (B.buildBytes (B.int i)) === Right (i :: Word64) prop "positive int roundtrip" $ \ (Positive i) ->- P.parse_ P.uint (B.buildBytes (B.int i)) === Right (i :: Word32)+ P.parse' P.uint (B.buildBytes (B.int i)) === Right (i :: Word32) prop "positive int roundtrip" $ \ (Positive i) ->- P.parse_ P.uint (B.buildBytes (B.int i)) === Right (i :: Word16)+ P.parse' P.uint (B.buildBytes (B.int i)) === Right (i :: Word16) prop "positive int roundtrip" $ \ (Positive i) ->- P.parse_ P.uint (B.buildBytes (B.int i)) === Right (i :: Word8)+ P.parse' P.uint (B.buildBytes (B.int i)) === Right (i :: Word8) prop "positive int roundtrip" $ \ i ->- P.parse_ P.int (B.buildBytes (B.int i)) === Right (i :: Int)+ P.parse' P.int (B.buildBytes (B.int i)) === Right (i :: Int) prop "positive int roundtrip" $ \ i ->- P.parse_ P.int (B.buildBytes (B.int i)) === Right (i :: Int64)+ P.parse' P.int (B.buildBytes (B.int i)) === Right (i :: Int64) prop "positive int roundtrip" $ \ i ->- P.parse_ P.int (B.buildBytes (B.int i)) === Right (i :: Int32)+ P.parse' P.int (B.buildBytes (B.int i)) === Right (i :: Int32) prop "positive int roundtrip" $ \ i ->- P.parse_ P.int (B.buildBytes (B.int i)) === Right (i :: Int16)+ P.parse' P.int (B.buildBytes (B.int i)) === Right (i :: Int16) prop "positive int roundtrip" $ \ i ->- P.parse_ P.int (B.buildBytes (B.int i)) === Right (i :: Int8)+ P.parse' P.int (B.buildBytes (B.int i)) === Right (i :: Int8) prop "positive int roundtrip" $ \ i ->- P.parse_ P.int (B.buildBytes (B.int i)) === Right (i :: Word)+ P.parse' P.int (B.buildBytes (B.int i)) === Right (i :: Word) prop "positive int roundtrip" $ \ i ->- P.parse_ P.int (B.buildBytes (B.int i)) === Right (i :: Word64)+ P.parse' P.int (B.buildBytes (B.int i)) === Right (i :: Word64) prop "positive int roundtrip" $ \ i ->- P.parse_ P.int (B.buildBytes (B.int i)) === Right (i :: Word32)+ P.parse' P.int (B.buildBytes (B.int i)) === Right (i :: Word32) prop "positive int roundtrip" $ \ i ->- P.parse_ P.int (B.buildBytes (B.int i)) === Right (i :: Word16)+ P.parse' P.int (B.buildBytes (B.int i)) === Right (i :: Word16) prop "positive int roundtrip" $ \ i ->- P.parse_ P.int (B.buildBytes (B.int i)) === Right (i :: Word8)+ P.parse' P.int (B.buildBytes (B.int i)) === Right (i :: Word8) prop "float roundtrip" $ \ i ->- P.parse_ P.float (B.buildBytes (B.float i)) === Right (i :: Float)+ P.parse' P.float (B.buildBytes (B.float i)) === Right (i :: Float) prop "double roundtrip" $ \ i ->- P.parse_ P.double (B.buildBytes (B.double i)) === Right (i :: Double)+ P.parse' P.double (B.buildBytes (B.double i)) === Right (i :: Double) describe "floatToScientific, doubleToScientific === fromFloatDigits" $ do prop "floatToScientific == fromFloatDigits" $ \ i ->