byteslice 0.2.6.0 → 0.2.7.0
raw patch · 12 files changed
+111/−70 lines, 12 filesdep +transformersdep ~basedep ~bytestringdep ~vectorPVP ok
version bump matches the API change (PVP)
Dependencies added: transformers
Dependency ranges changed: base, bytestring, vector
API changes (from Hackage documentation)
+ Data.Bytes: foldlM :: Monad m => (a -> Word8 -> m a) -> a -> Bytes -> m a
+ Data.Bytes: foldrM :: Monad m => (Word8 -> a -> m a) -> a -> Bytes -> m a
Files
- CHANGELOG.md +6/−0
- byteslice.cabal +8/−8
- src-new-reps/Reps.hs +16/−0
- src-no-unlifted-newtypes/UnliftedBytes.hs +0/−23
- src-old-reps/Reps.hs +22/−0
- src-unlifted-newtypes/UnliftedBytes.hs +0/−26
- src/Data/Bytes.hs +18/−6
- src/Data/Bytes/Pure.hs +23/−0
- src/Data/Bytes/Text/AsciiExt.hs +2/−2
- src/Data/Bytes/Text/Latin1.hs +4/−4
- src/Data/Bytes/Types.hs +1/−1
- test/Main.hs +11/−0
CHANGELOG.md view
@@ -1,5 +1,11 @@ # Revision history for byteslice +## 0.2.7.0 -- 2022-02-16++* Add support for GHC 9.2.+* Drop support for GHC 8.8 and earlier.+* Add `foldlM` and `foldrM` for mondic folds over byte sequences.+ ## 0.2.6.0 -- 2021-09-15 * Add `BytesN` and `ByteArrayN`.
byteslice.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: byteslice-version: 0.2.6.0+version: 0.2.7.0 synopsis: Slicing managed and unmanaged memory description: This library provides types that allow the user to talk about a slice of@@ -37,11 +37,11 @@ Data.Bytes.Byte Data.Bytes.Pure Data.Bytes.IO- UnliftedBytes+ Reps Cstrlen build-depends:- , base >=4.11.1 && <5- , bytestring >=0.10.8 && <0.11+ , base >=4.14 && <5+ , bytestring >=0.10.8 && <0.12 , primitive >=0.7 && <0.8 , primitive-unlifted >=0.1.2 && <0.2 , primitive-addr >=0.1 && <0.2@@ -50,11 +50,10 @@ , vector >=0.12 && <0.13 hs-source-dirs: src ghc-options: -Wall -O2- if impl(ghc>=8.10)- hs-source-dirs: src-unlifted-newtypes+ if impl(ghc>=9.2)+ hs-source-dirs: src-new-reps else- hs-source-dirs: src-no-unlifted-newtypes- ghc-options: -fno-warn-dodgy-imports -fno-warn-dodgy-exports+ hs-source-dirs: src-old-reps if impl(ghc>=9.0) hs-source-dirs: src-ghc-cstrlen else@@ -82,6 +81,7 @@ , tasty , tasty-hunit , tasty-quickcheck+ , transformers benchmark bench type: exitcode-stdio-1.0
+ src-new-reps/Reps.hs view
@@ -0,0 +1,16 @@+{-# language GADTSyntax #-}+{-# language KindSignatures #-}+{-# language MagicHash #-}+{-# language TypeInType #-}+{-# language UnboxedTuples #-}+{-# language UnliftedNewtypes #-}++module Reps+ ( Bytes#(..)+ , word8ToWord#+ ) where++import GHC.Exts (ByteArray#,Int#,RuntimeRep(..),Levity(Unlifted),TYPE,word8ToWord#)++newtype Bytes# :: TYPE ('TupleRep '[ 'BoxedRep 'Unlifted,'IntRep,'IntRep]) where+ Bytes# :: (# ByteArray#, Int#, Int# #) -> Bytes#
− src-no-unlifted-newtypes/UnliftedBytes.hs
@@ -1,23 +0,0 @@-{-# language MagicHash #-}-{-# language TypeFamilies #-}-{-# language TypeInType #-}-{-# language UndecidableInstances #-}--module UnliftedBytes- ( Bytes#- , lift- , unlift- ) where--import Data.Bytes.Internal (Bytes)-import GHC.TypeLits-import GHC.Exts (RuntimeRep(..),TYPE)--type family Bytes# :: TYPE ('TupleRep '[ 'UnliftedRep,'IntRep,'IntRep]) where- Bytes# = TypeError ('Text "Bytes# not available before GHC 8.10")--lift :: Bytes# -> Bytes-lift _ = errorWithoutStackTrace "UnliftedBytes: lift not implemented"--unlift :: Bytes -> Bytes#-unlift _ = errorWithoutStackTrace "UnliftedBytes: unlift not implemented"
+ src-old-reps/Reps.hs view
@@ -0,0 +1,22 @@+{-# language GADTSyntax #-}+{-# language KindSignatures #-}+{-# language MagicHash #-}+{-# language TypeInType #-}+{-# language UnboxedTuples #-}+{-# language UnliftedNewtypes #-}++module Reps+ ( Bytes#(..)+ , word8ToWord#+ ) where++import GHC.Exts (ByteArray#,Int#,Word#,RuntimeRep(..),TYPE)++newtype Bytes# :: TYPE ('TupleRep '[ 'UnliftedRep,'IntRep,'IntRep]) where+ Bytes# :: (# ByteArray#, Int#, Int# #) -> Bytes#++-- In GHC 9.2, the lifted Word8 type started being backed by the+-- unlifted Word8# instead of by Word#. This is a compatibility hack.+word8ToWord# :: Word# -> Word#+{-# inline word8ToWord# #-}+word8ToWord# w = w
− src-unlifted-newtypes/UnliftedBytes.hs
@@ -1,26 +0,0 @@-{-# language GADTSyntax #-}-{-# language KindSignatures #-}-{-# language MagicHash #-}-{-# language TypeInType #-}-{-# language UnboxedTuples #-}-{-# language UnliftedNewtypes #-}--module UnliftedBytes- ( Bytes#(..)- , lift- , unlift- ) where--import Data.Bytes.Internal (Bytes(Bytes))-import Data.Primitive (ByteArray(ByteArray))-import GHC.Exts (Int(I#),ByteArray#,Int#,RuntimeRep(..),TYPE)--newtype Bytes# :: TYPE ('TupleRep '[ 'UnliftedRep,'IntRep,'IntRep]) where- Bytes# :: (# ByteArray#, Int#, Int# #) -> Bytes#--lift :: Bytes# -> Bytes-lift (Bytes# (# arr, off, len #)) = Bytes (ByteArray arr) (I# off) (I# len)--unlift :: Bytes -> Bytes#-unlift (Bytes (ByteArray arr) (I# off) (I# len)) =- Bytes# (# arr, off, len #)
src/Data/Bytes.hs view
@@ -54,6 +54,9 @@ , Pure.foldr' -- * Folds with Indices , Pure.ifoldl'+ -- * Monadic Folds+ , Pure.foldlM+ , Pure.foldrM -- * Common Folds , elem -- * Splitting@@ -162,7 +165,7 @@ import GHC.Exts (Addr#,Word#,Int#) import GHC.Exts (Int(I#),Ptr(Ptr)) import GHC.Word (Word8(W8#),Word32)-import UnliftedBytes (lift,unlift)+import Reps (Bytes#(..),word8ToWord#) import qualified Data.Bytes.Byte as Byte import qualified Data.Bytes.Chunks as Chunks@@ -397,14 +400,14 @@ -- | Is the byte a member of the byte sequence? elem :: Word8 -> Bytes -> Bool-elem (W8# w) b = case elemLoop 0# w b of+elem (W8# w) b = case elemLoop 0# (word8ToWord# w) b of 1# -> True _ -> False elemLoop :: Int# -> Word# -> Bytes -> Int# elemLoop !r !w (Bytes arr@(ByteArray arr# ) off@(I# off# ) len) = case len of 0 -> r- _ -> elemLoop (Exts.orI# r (Exts.eqWord# w (Exts.indexWord8Array# arr# off# ) )) w (Bytes arr (off + 1) (len - 1))+ _ -> elemLoop (Exts.orI# r (Exts.eqWord# w (word8ToWord# (Exts.indexWord8Array# arr# off# )) )) w (Bytes arr (off + 1) (len - 1)) -- | Take bytes while the predicate is true. takeWhile :: (Word8 -> Bool) -> Bytes -> Bytes@@ -482,7 +485,7 @@ -- to a byte sequence. Any character with a codepoint above @U+007F@ is -- replaced by @U+0000@. fromAsciiString :: String -> Bytes-{-# DEPRECATED fromAsciiString "use Data.Bytes.Ascii.fromString instead" #-}+{-# DEPRECATED fromAsciiString "use Data.Bytes.Text.Ascii.fromString instead" #-} {-# INLINE fromAsciiString #-} fromAsciiString = Ascii.fromString @@ -490,13 +493,13 @@ -- by ISO-8859-1. These are encoded with ISO-8859-1. Any character -- with a codepoint above @U+00FF@ is replaced by an unspecified byte. fromLatinString :: String -> Bytes-{-# DEPRECATED fromLatinString "use Data.Bytes.Latin1.fromString instead" #-}+{-# DEPRECATED fromLatinString "use Data.Bytes.Text.Latin1.fromString instead" #-} {-# INLINE fromLatinString #-} fromLatinString = Latin1.fromString -- | Interpret a byte sequence as text encoded by ISO-8859-1. toLatinString :: Bytes -> String-{-# DEPRECATED toLatinString "use Data.Bytes.Latin1.toString instead" #-}+{-# DEPRECATED toLatinString "use Data.Bytes.Text.Latin1.toString instead" #-} {-# INLINE toLatinString #-} toLatinString = Latin1.toString @@ -718,3 +721,12 @@ {-# DEPRECATED toLowerAsciiByteArrayClone "use Data.Bytes/Text/AsciiExt.toLowerU" #-} {-# INLINE toLowerAsciiByteArrayClone #-} toLowerAsciiByteArrayClone = AsciiExt.toLowerU++lift :: Bytes# -> Bytes+{-# inline lift #-}+lift (Bytes# (# arr, off, len #)) = Bytes (ByteArray arr) (I# off) (I# len)++unlift :: Bytes -> Bytes#+{-# inline unlift #-}+unlift (Bytes (ByteArray arr) (I# off) (I# len)) =+ Bytes# (# arr, off, len #)
src/Data/Bytes/Pure.hs view
@@ -18,6 +18,8 @@ , toPinnedByteArrayClone , fromByteArray , length+ , foldlM+ , foldrM , foldl , foldl' , foldr@@ -151,6 +153,16 @@ 0 -> a _ -> go (f a (PM.indexByteArray arr off)) (off + 1) (len - 1) +-- | Left monadic fold over bytes, non-strict in the accumulator.+foldlM :: Monad m => (a -> Word8 -> m a) -> a -> Bytes -> m a+{-# inline foldlM #-}+foldlM f a0 (Bytes arr off0 len0) = go a0 off0 len0 where+ go a !off !len = case len of+ 0 -> pure a+ _ -> do+ a' <- f a (PM.indexByteArray arr off)+ go a' (off + 1) (len - 1)+ -- | Right fold over bytes, non-strict in the accumulator. foldr :: (Word8 -> a -> a) -> a -> Bytes -> a {-# inline foldr #-}@@ -178,6 +190,17 @@ (-1) -> a _ -> go (f (PM.indexByteArray arr off) a) (off - 1) (ix - 1) +-- | Right monadic fold over bytes, non-strict in the accumulator.+foldrM :: Monad m => (Word8 -> a -> m a) -> a -> Bytes -> m a+{-# inline foldrM #-}+foldrM f a0 (Bytes arr off0 len0) =+ go a0 (off0 + len0 - 1) (len0 - 1) + where+ go !a !off !ix = case ix of+ (-1) -> pure a+ _ -> do+ a' <- f (PM.indexByteArray arr off) a+ go a' (off - 1) (ix - 1) -- | Yields a pointer to the beginning of the byte sequence. It is only safe -- to call this on a 'Bytes' backed by a pinned @ByteArray@.
src/Data/Bytes/Text/AsciiExt.hs view
@@ -45,7 +45,7 @@ -- To maintain a running state, see 'hFoldLines'. -- -- Lines are extracted with with 'BC8.hGetLine', which does not document its--- dectection algorithm. As of writing (bytestring v0.11.1.0), lines are+-- detection algorithm. As of writing (bytestring v0.11.1.0), lines are -- delimited by a single @\n@ character (UNIX-style, as all things should be). hForLines_ :: Handle -> (Bytes -> IO a) -> IO () hForLines_ h body = loop@@ -61,7 +61,7 @@ -- If you do not need to keep a state, see `hForLines_`. -- -- Lines are extracted with with 'BC8.hGetLine', which does not document its--- dectection algorithm. As of writing (bytestring v0.11.1.0), lines are+-- detection algorithm. As of writing (bytestring v0.11.1.0), lines are -- delimited by a single @\n@ character (UNIX-style, as all things should be). hFoldLines :: Handle -> a -> (a -> Bytes -> IO a) -> IO a hFoldLines h z body = loop z
src/Data/Bytes/Text/Latin1.hs view
@@ -35,10 +35,10 @@ ) where import Data.Bytes.Types (Bytes(..))-import Data.Char (ord)+import Data.Char (ord,chr) import Data.Primitive (ByteArray(ByteArray))-import GHC.Exts (Int(I#),Char(C#),word2Int#,chr#)-import GHC.Word (Word8(W8#))+import Data.Word (Word8)+import GHC.Exts (Int(I#),Char(C#)) import qualified Data.Bytes.Pure as Bytes import qualified GHC.Exts as Exts@@ -54,7 +54,7 @@ -- | Interpret a byte sequence as text encoded by ISO-8859-1. toString :: Bytes -> String {-# INLINE toString #-}-toString = Bytes.foldr (\(W8# w) xs -> C# (chr# (word2Int# w)) : xs) []+toString = Bytes.foldr (\w xs -> chr (fromIntegral @Word8 @Int w) : xs) [] -- TODO presumably also fromText and fromShortText
src/Data/Bytes/Types.hs view
@@ -17,7 +17,7 @@ import Data.Primitive (ByteArray(..),MutableByteArray(..)) import Data.Primitive.Addr (Addr) import GHC.TypeNats (Nat)-import UnliftedBytes (Bytes#(..))+import Reps (Bytes#(..)) -- | A slice of a 'ByteArray' whose compile-time-known length is represented -- by a phantom type variable. Consumers of this data constructor must be
test/Main.hs view
@@ -17,6 +17,7 @@ import Test.Tasty.HUnit ((@=?),testCase) import Test.Tasty.QuickCheck ((===),testProperty,property,Discard(Discard)) import Test.Tasty.QuickCheck ((==>),Arbitrary)+import Control.Monad.Trans.Writer (Writer,tell) import qualified Data.ByteString as ByteString import qualified Data.Bytes as Bytes@@ -124,6 +125,16 @@ List.foldl (-) 0 xs === Bytes.foldl (-) 0 (Bytes.unsafeDrop 1 (Exts.fromList (x : xs)))+ , testProperty "foldlM" $ \(x :: Word8) (xs :: [Word8]) ->+ let f acc y = (tell [x] >> pure (acc - y)) :: Writer [Word8] Word8 in+ Foldable.foldlM f 0 xs+ ===+ Bytes.foldlM f 0 (Bytes.unsafeDrop 1 (Exts.fromList (x : xs)))+ , testProperty "foldrM" $ \(x :: Word8) (xs :: [Word8]) ->+ let f acc y = (tell [x] >> pure (acc - y)) :: Writer [Word8] Word8 in+ Foldable.foldrM f 0 xs+ ===+ Bytes.foldrM f 0 (Bytes.unsafeDrop 1 (Exts.fromList (x : xs))) , testProperty "foldl'" $ \(x :: Word8) (xs :: [Word8]) -> List.foldl' (-) 0 xs ===