packages feed

primal-memory 0.2.0.0 → 0.3.0.0

raw patch · 16 files changed

+4226/−2827 lines, 16 filesdep ~basedep ~primalPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, primal

API changes (from Hackage documentation)

- Data.Prim.Memory: allocMem :: (MemAlloc ma, Prim e, MonadPrim s m) => Count e -> m (ma s)
- Data.Prim.Memory: allocZeroMem :: forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e) => Count e -> m (ma s)
- Data.Prim.Memory: freezeCloneMem :: forall ma m s. (MemAlloc ma, MonadPrim s m) => ma s -> m (FrozenMem ma)
- Data.Prim.Memory: freezeCopyMem :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => ma s -> Off e -> Count e -> m (FrozenMem ma)
- Data.Prim.Memory: freezeMem :: (MemAlloc ma, MonadPrim s m) => ma s -> m (FrozenMem ma)
- Data.Prim.Memory: getByteCountMem :: (MemAlloc ma, MonadPrim s m) => ma s -> m (Count Word8)
- Data.Prim.Memory: getCountMem :: forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e) => ma s -> m (Count e)
- Data.Prim.Memory: getCountRemMem :: forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e) => ma s -> m (Count e, Count Word8)
- Data.Prim.Memory: loadListByteOffMem :: (MemAlloc ma, MonadPrim s m, Prim e) => [e] -> ma s -> Off Word8 -> m ([e], Count e)
- Data.Prim.Memory: loadListByteOffMemN :: (MemWrite mw, MonadPrim s m, Prim e) => Count e -> [e] -> mw s -> Off Word8 -> m ([e], Count e)
- Data.Prim.Memory: loadListMem :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => [e] -> ma s -> m ([e], Count e)
- Data.Prim.Memory: loadListMemN :: forall e mw m s. (MemWrite mw, MonadPrim s m, Prim e) => Count e -> [e] -> mw s -> m ([e], Count e)
- Data.Prim.Memory: loadListMemN_ :: forall e mw m s. (Prim e, MemWrite mw, MonadPrim s m) => Count e -> [e] -> mw s -> m ()
- Data.Prim.Memory: loadListMem_ :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => [e] -> ma s -> m ()
- Data.Prim.Memory: loadListOffMem :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => [e] -> ma s -> Off e -> m ([e], Count e)
- Data.Prim.Memory: loadListOffMemN :: (MemWrite mw, MonadPrim s m, Prim e) => Count e -> [e] -> mw s -> Off e -> m ([e], Count e)
- Data.Prim.Memory: modifyFetchNewMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> e) -> m e
- Data.Prim.Memory: modifyFetchNewMemM :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> m e) -> m e
- Data.Prim.Memory: modifyFetchOldMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> e) -> m e
- Data.Prim.Memory: modifyFetchOldMemM :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> m e) -> m e
- Data.Prim.Memory: moveByteOffMem :: (MemWrite mw, MonadPrim s m, MemWrite mw', Prim e) => mw' s -> Off Word8 -> mw s -> Off Word8 -> Count e -> m ()
- Data.Prim.Memory: moveByteOffToMBytesMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> MBytes p s -> Off Word8 -> Count e -> m ()
- Data.Prim.Memory: moveByteOffToPtrMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m ()
- Data.Prim.Memory: moveMem :: (MonadPrim s m, MemWrite mw1, MemWrite mw2, Prim e) => mw1 s -> Off e -> mw2 s -> Off e -> Count e -> m ()
- Data.Prim.Memory: readByteOffMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> m e
- Data.Prim.Memory: readOffMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> m e
- Data.Prim.Memory: resizeMem :: (MemAlloc ma, MonadPrim s m, Prim e) => ma s -> Count e -> m (ma s)
- Data.Prim.Memory: setMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> Count e -> e -> m ()
- Data.Prim.Memory: withScrubbedMem :: forall e ma m a. (MonadUnliftPrim RW m, Prim e, MemAlloc ma, PtrAccess RW (ma RW)) => Count e -> (ma RW -> m a) -> m a
- Data.Prim.Memory: writeByteOffMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> e -> m ()
- Data.Prim.Memory: writeOffMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> e -> m ()
- Data.Prim.Memory.Addr: callocMAddr :: (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)
- Data.Prim.Memory.Addr: instance GHC.Classes.Eq (Data.Prim.Memory.Addr.Addr e)
- Data.Prim.Memory.Bytes: callocAlignedMBytes :: (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Pin s)
- Data.Prim.Memory.Bytes: callocMBytes :: (MonadPrim s m, Prim e, Typeable p) => Count e -> m (MBytes p s)
- Data.Prim.Memory.Bytes: fromListBytesN_ :: (Prim e, Typeable p) => Count e -> [e] -> Bytes p
- Data.Prim.Memory.ForeignPtr: instance Data.Prim.Memory.ForeignPtr.PtrAccess s (GHC.ForeignPtr.ForeignPtr a)
- Data.Prim.Memory.PrimArray: Inc :: Pinned
- Data.Prim.Memory.PrimArray: MPrimArray :: MBytes p s -> MPrimArray e s
- Data.Prim.Memory.PrimArray: Pin :: Pinned
- Data.Prim.Memory.PrimArray: PrimArray :: Bytes p -> PrimArray e
- Data.Prim.Memory.PrimArray: allocAlignedMPrimArray :: (MonadPrim s m, Prim e) => Count e -> m (MPrimArray 'Pin e s)
- Data.Prim.Memory.PrimArray: allocMPrimArray :: forall e p m s. (Typeable p, Prim e, MonadPrim s m) => Size -> m (MPrimArray p e s)
- Data.Prim.Memory.PrimArray: allocPinnedMPrimArray :: forall e m s. (MonadPrim s m, Prim e) => Size -> m (MPrimArray 'Pin e s)
- Data.Prim.Memory.PrimArray: allocUnpinnedMPrimArray :: forall e m s. (MonadPrim s m, Prim e) => Size -> m (MPrimArray 'Inc e s)
- Data.Prim.Memory.PrimArray: castMPrimArray :: MPrimArray p e' s -> MPrimArray p e s
- Data.Prim.Memory.PrimArray: castPrimArray :: PrimArray p e' -> PrimArray p e
- Data.Prim.Memory.PrimArray: copyPrimArrayToMPrimArray :: forall e p m s. (MonadPrim s m, Prim e) => PrimArray p e -> Int -> MPrimArray p e s -> Int -> Size -> m ()
- Data.Prim.Memory.PrimArray: data Pinned
- Data.Prim.Memory.PrimArray: freezeMPrimArray :: MonadPrim s m => MPrimArray p e s -> m (PrimArray p e)
- Data.Prim.Memory.PrimArray: fromBytesPrimArray :: Bytes p -> PrimArray p e
- Data.Prim.Memory.PrimArray: fromMBytesMPrimArray :: MBytes p s -> MPrimArray p e s
- Data.Prim.Memory.PrimArray: getSizeMPrimArray :: forall e p m s. (MonadPrim s m, Prim e) => MPrimArray p e s -> m Size
- Data.Prim.Memory.PrimArray: instance (Data.Typeable.Internal.Typeable p, Data.Prim.Class.Prim e) => GHC.Exts.IsList (Data.Prim.Memory.PrimArray.PrimArray p e)
- Data.Prim.Memory.PrimArray: instance (GHC.Show.Show e, Data.Prim.Class.Prim e) => GHC.Show.Show (Data.Prim.Memory.PrimArray.PrimArray p e)
- Data.Prim.Memory.PrimArray: instance Control.DeepSeq.NFData (Data.Prim.Memory.PrimArray.MPrimArray p e s)
- Data.Prim.Memory.PrimArray: instance Control.DeepSeq.NFData (Data.Prim.Memory.PrimArray.PrimArray p e)
- Data.Prim.Memory.PrimArray: instance Data.Prim.Memory.ForeignPtr.PtrAccess s (Data.Prim.Memory.PrimArray.MPrimArray 'Data.Prim.Memory.Bytes.Internal.Pin e s)
- Data.Prim.Memory.PrimArray: instance Data.Prim.Memory.ForeignPtr.PtrAccess s (Data.Prim.Memory.PrimArray.PrimArray 'Data.Prim.Memory.Bytes.Internal.Pin e)
- Data.Prim.Memory.PrimArray: instance Data.Prim.Memory.Internal.MemRead (Data.Prim.Memory.PrimArray.PrimArray p e)
- Data.Prim.Memory.PrimArray: instance Data.Prim.Memory.Internal.MemWrite (Data.Prim.Memory.PrimArray.MPrimArray p e)
- Data.Prim.Memory.PrimArray: instance Data.Typeable.Internal.Typeable p => Data.Prim.Memory.Internal.MemAlloc (Data.Prim.Memory.PrimArray.MPrimArray p e)
- Data.Prim.Memory.PrimArray: instance Data.Typeable.Internal.Typeable p => Data.String.IsString (Data.Prim.Memory.PrimArray.PrimArray p GHC.Types.Char)
- Data.Prim.Memory.PrimArray: instance Data.Typeable.Internal.Typeable p => GHC.Base.Monoid (Data.Prim.Memory.PrimArray.PrimArray p e)
- Data.Prim.Memory.PrimArray: instance Data.Typeable.Internal.Typeable p => GHC.Base.Semigroup (Data.Prim.Memory.PrimArray.PrimArray p e)
- Data.Prim.Memory.PrimArray: isPinnedMPrimArray :: MPrimArray p e s -> Bool
- Data.Prim.Memory.PrimArray: isPinnedPrimArray :: PrimArray p e -> Bool
- Data.Prim.Memory.PrimArray: moveMPrimArrayToMPrimArray :: forall e p m s. (MonadPrim s m, Prim e) => MPrimArray p e s -> Int -> MPrimArray p e s -> Int -> Size -> m ()
- Data.Prim.Memory.PrimArray: newtype MPrimArray (p :: Pinned) e s
- Data.Prim.Memory.PrimArray: newtype PrimArray (p :: Pinned) e
- Data.Prim.Memory.PrimArray: readMPrimArray :: (MonadPrim s m, Prim e) => MPrimArray p e s -> Int -> m e
- Data.Prim.Memory.PrimArray: reallocMPrimArray :: forall e p m s. (MonadPrim s m, Typeable p, Prim e) => MPrimArray p e s -> Size -> m (MPrimArray p e s)
- Data.Prim.Memory.PrimArray: resizeMPrimArray :: forall e p m s. (MonadPrim s m, Prim e) => MPrimArray p e s -> Size -> m (MPrimArray 'Inc e s)
- Data.Prim.Memory.PrimArray: setMPrimArray :: forall e p m s. (MonadPrim s m, Prim e) => MPrimArray p e s -> Int -> Size -> e -> m ()
- Data.Prim.Memory.PrimArray: shrinkMPrimArray :: forall e p m s. (MonadPrim s m, Prim e) => MPrimArray p e s -> Size -> m ()
- Data.Prim.Memory.PrimArray: sizePrimArray :: forall e p. Prim e => PrimArray p e -> Size
- Data.Prim.Memory.PrimArray: thawPrimArray :: MonadPrim s m => PrimArray p e -> m (MPrimArray p e s)
- Data.Prim.Memory.PrimArray: toBytesPrimArray :: PrimArray p e -> Bytes p
- Data.Prim.Memory.PrimArray: toMBytesMPrimArray :: MPrimArray p e s -> MBytes p s
- Data.Prim.Memory.PrimArray: writeMPrimArray :: (MonadPrim s m, Prim e) => MPrimArray p e s -> Int -> e -> m ()
- Data.Prim.Memory.Text: fromBytesArray :: Bytes p -> Array
- Data.Prim.Memory.Text: fromMBytesMArray :: MBytes p s -> MArray s
- Data.Prim.Memory.Text: toBytesArray :: Array -> Bytes 'Inc
- Data.Prim.Memory.Text: toMBytesMArray :: MArray s -> MBytes 'Inc s
+ Data.Prim.Memory: allocMutMem :: (MemAlloc ma, Prim e, MonadPrim s m) => Count e -> m (ma s)
+ Data.Prim.Memory: allocZeroMutMem :: forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e) => Count e -> m (ma s)
+ Data.Prim.Memory: cloneMutMem :: forall ma m s. (MemAlloc ma, MonadPrim s m) => ma s -> m (ma s)
+ Data.Prim.Memory: compareByteMem :: (MemRead mr1, MemRead mr2) => mr1 -> mr2 -> Ordering
+ Data.Prim.Memory: compareOffMem :: (Prim e, Ord e, MemRead mr1, MemRead mr2) => mr1 -> Off e -> mr2 -> Off e -> Count e -> Ordering
+ Data.Prim.Memory: defaultReallocMutMem :: (Prim e, MemAlloc ma, MonadPrim s m) => ma s -> Count e -> m (ma s)
+ Data.Prim.Memory: eqByteMem :: (MemRead mr1, MemRead mr2) => mr1 -> mr2 -> Bool
+ Data.Prim.Memory: eqByteOffMem :: (MemRead mr1, MemRead mr2) => mr1 -> Off Word8 -> mr2 -> Off Word8 -> Count Word8 -> Bool
+ Data.Prim.Memory: eqOffMem :: (Prim e, Eq e, MemRead mr1, MemRead mr2) => mr1 -> Off e -> mr2 -> Off e -> Count e -> Bool
+ Data.Prim.Memory: freezeCloneMutMem :: forall ma m s. (MemAlloc ma, MonadPrim s m) => ma s -> m (FrozenMem ma)
+ Data.Prim.Memory: freezeCopyMutMem :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => ma s -> Off e -> Count e -> m (FrozenMem ma)
+ Data.Prim.Memory: freezeMutMem :: (MemAlloc ma, MonadPrim s m) => ma s -> m (FrozenMem ma)
+ Data.Prim.Memory: getByteCountMutMem :: (MemAlloc ma, MonadPrim s m) => ma s -> m (Count Word8)
+ Data.Prim.Memory: getCountMutMem :: forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e) => ma s -> m (Count e)
+ Data.Prim.Memory: getCountRemMutMem :: forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e) => ma s -> m (Count e, Count Word8)
+ Data.Prim.Memory: loadListByteOffMutMem :: (MemAlloc ma, MonadPrim s m, Prim e) => [e] -> ma s -> Off Word8 -> m ([e], Count e)
+ Data.Prim.Memory: loadListByteOffMutMemN :: (MemWrite mw, MonadPrim s m, Prim e) => Count e -> [e] -> mw s -> Off Word8 -> m ([e], Count e)
+ Data.Prim.Memory: loadListMutMem :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => [e] -> ma s -> m ([e], Count e)
+ Data.Prim.Memory: loadListMutMemN :: forall e mw m s. (MemWrite mw, MonadPrim s m, Prim e) => Count e -> [e] -> mw s -> m ([e], Count e)
+ Data.Prim.Memory: loadListMutMemN_ :: forall e mw m s. (Prim e, MemWrite mw, MonadPrim s m) => Count e -> [e] -> mw s -> m ()
+ Data.Prim.Memory: loadListMutMem_ :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => [e] -> ma s -> m ()
+ Data.Prim.Memory: loadListOffMutMem :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => [e] -> ma s -> Off e -> m ([e], Count e)
+ Data.Prim.Memory: loadListOffMutMemN :: (MemWrite mw, MonadPrim s m, Prim e) => Count e -> [e] -> mw s -> Off e -> m ([e], Count e)
+ Data.Prim.Memory: modifyFetchNewMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> e) -> m e
+ Data.Prim.Memory: modifyFetchNewMutMemM :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> m e) -> m e
+ Data.Prim.Memory: modifyFetchOldMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> e) -> m e
+ Data.Prim.Memory: modifyFetchOldMutMemM :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> m e) -> m e
+ Data.Prim.Memory: moveByteOffMutMem :: (MemWrite mw, MonadPrim s m, MemWrite mw', Prim e) => mw' s -> Off Word8 -> mw s -> Off Word8 -> Count e -> m ()
+ Data.Prim.Memory: moveByteOffToMBytesMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> MBytes p s -> Off Word8 -> Count e -> m ()
+ Data.Prim.Memory: moveByteOffToPtrMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m ()
+ Data.Prim.Memory: moveMutMem :: (MonadPrim s m, MemWrite mw1, MemWrite mw2, Prim e) => mw1 s -> Off e -> mw2 s -> Off e -> Count e -> m ()
+ Data.Prim.Memory: readByteOffMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> m e
+ Data.Prim.Memory: readOffMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> m e
+ Data.Prim.Memory: reallocMutMem :: (MemAlloc ma, MonadPrim s m, Prim e) => ma s -> Count e -> m (ma s)
+ Data.Prim.Memory: setMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> Count e -> e -> m ()
+ Data.Prim.Memory: withScrubbedMutMem :: forall e ma m a. (MonadUnliftPrim RW m, Prim e, MemAlloc ma, PtrAccess RW (ma RW)) => Count e -> (ma RW -> m a) -> m a
+ Data.Prim.Memory: writeByteOffMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> e -> m ()
+ Data.Prim.Memory: writeOffMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> e -> m ()
+ Data.Prim.Memory.Addr: allocAlignedMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)
+ Data.Prim.Memory.Addr: allocZeroAlignedMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)
+ Data.Prim.Memory.Addr: allocZeroMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)
+ Data.Prim.Memory.Addr: instance (Data.Prim.Class.Prim e, GHC.Classes.Ord e) => GHC.Classes.Ord (Data.Prim.Memory.Addr.Addr e)
+ Data.Prim.Memory.Addr: instance (GHC.Classes.Eq e, Data.Prim.Class.Prim e) => GHC.Classes.Eq (Data.Prim.Memory.Addr.Addr e)
+ Data.Prim.Memory.Addr: modifyFetchNewMAddr :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> a) -> m a
+ Data.Prim.Memory.Addr: modifyFetchNewMAddrM :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m a) -> m a
+ Data.Prim.Memory.Addr: modifyFetchOldMAddr :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> a) -> m a
+ Data.Prim.Memory.Addr: modifyFetchOldMAddrM :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m a) -> m a
+ Data.Prim.Memory.Addr: modifyMAddr :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> (a, b)) -> m b
+ Data.Prim.Memory.Addr: modifyMAddrM :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m (a, b)) -> m b
+ Data.Prim.Memory.Addr: modifyMAddrM_ :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m a) -> m ()
+ Data.Prim.Memory.Addr: modifyMAddr_ :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> a) -> m ()
+ Data.Prim.Memory.Addr: newMAddr :: forall e m s. (MonadPrim s m, Prim e) => e -> m (MAddr e s)
+ Data.Prim.Memory.Addr: plusByteOffAddr :: Addr e -> Off Word8 -> Addr e
+ Data.Prim.Memory.Addr: plusByteOffMAddr :: MAddr e s -> Off Word8 -> MAddr e s
+ Data.Prim.Memory.Addr: swapMAddrs :: (MonadPrim s m, Prim a) => MAddr a s -> MAddr a s -> m (a, a)
+ Data.Prim.Memory.Addr: swapMAddrs_ :: (MonadPrim s m, Prim a) => MAddr a s -> MAddr a s -> m ()
+ Data.Prim.Memory.Bytes: allocZeroAlignedMBytes :: (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Pin s)
+ Data.Prim.Memory.Bytes: allocZeroMBytes :: (MonadPrim s m, Prim e, Typeable p) => Count e -> m (MBytes p s)
+ Data.Prim.Memory.Bytes: allocZeroPinnedMBytes :: (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Pin s)
+ Data.Prim.Memory.Bytes: fromListZeroBytesN_ :: (Prim e, Typeable p) => Count e -> [e] -> Bytes p
+ Data.Prim.Memory.Bytes: fromUArrayBytes :: UArray e -> Bytes 'Inc
+ Data.Prim.Memory.Bytes: fromUMArrayMBytes :: UMArray e s -> MBytes 'Inc s
+ Data.Prim.Memory.Bytes: toUArrayBytes :: Bytes p -> UArray e
+ Data.Prim.Memory.Bytes: toUMArrayMBytes :: MBytes p s -> UMArray e s
+ Data.Prim.Memory.Fold: allMem :: forall e mr. (Prim e, MemRead mr) => (e -> Bool) -> mr -> Bool
+ Data.Prim.Memory.Fold: allOffMem :: forall e mr. (Prim e, MemRead mr) => Off e -> Count e -> (e -> Bool) -> mr -> Bool
+ Data.Prim.Memory.Fold: anyMem :: forall e mr. (Prim e, MemRead mr) => (e -> Bool) -> mr -> Bool
+ Data.Prim.Memory.Fold: anyOffMem :: forall e mr. (Prim e, MemRead mr) => Off e -> Count e -> (e -> Bool) -> mr -> Bool
+ Data.Prim.Memory.Fold: compareMem :: forall e mr. (Prim e, Ord e, MemRead mr) => mr -> mr -> Ordering
+ Data.Prim.Memory.Fold: compareOffMem :: (Prim e, Ord e, MemRead mr1, MemRead mr2) => mr1 -> Off e -> mr2 -> Off e -> Count e -> Ordering
+ Data.Prim.Memory.Fold: eqMem :: forall e mr. (Prim e, Eq e, MemRead mr) => mr -> mr -> Bool
+ Data.Prim.Memory.Fold: eqMutMem :: forall e ma m s. (Prim e, Eq e, MonadPrim s m, MemAlloc ma) => ma s -> ma s -> m Bool
+ Data.Prim.Memory.Fold: eqOffMem :: (Prim e, Eq e, MemRead mr1, MemRead mr2) => mr1 -> Off e -> mr2 -> Off e -> Count e -> Bool
+ Data.Prim.Memory.Fold: eqOffMemBinary :: forall e mr1 mr2. (Prim e, MemRead mr1, MemRead mr2) => mr1 -> Off e -> mr2 -> Off e -> Count e -> Bool
+ Data.Prim.Memory.Fold: eqOffMutMem :: forall e ma1 ma2 m s. (Prim e, Eq e, MonadPrim s m, MemWrite ma1, MemWrite ma2) => ma1 s -> Off e -> ma2 s -> Off e -> Count e -> m Bool
+ Data.Prim.Memory.Fold: foldMapOffMem :: forall e m mr. (Prim e, MemRead mr, Monoid m) => Off e -> Count e -> (e -> m) -> mr -> m
+ Data.Prim.Memory.Fold: foldlLazyMem :: forall e a mr. (Prim e, MemRead mr) => (a -> e -> a) -> a -> mr -> a
+ Data.Prim.Memory.Fold: foldlMem :: forall e a mr. (Prim e, MemRead mr) => (a -> e -> a) -> a -> mr -> a
+ Data.Prim.Memory.Fold: foldrLazyMem :: forall e a mr. (Prim e, MemRead mr) => (e -> a -> a) -> a -> mr -> a
+ Data.Prim.Memory.Fold: foldrMem :: forall e a mr. (Prim e, MemRead mr) => (e -> a -> a) -> a -> mr -> a
+ Data.Prim.Memory.Fold: iallMem :: forall e mr. (Prim e, MemRead mr) => (Off e -> e -> Bool) -> mr -> Bool
+ Data.Prim.Memory.Fold: iallOffMem :: forall e mr. (Prim e, MemRead mr) => Off e -> Count e -> (Off e -> e -> Bool) -> mr -> Bool
+ Data.Prim.Memory.Fold: ianyMem :: forall e mr. (Prim e, MemRead mr) => (Off e -> e -> Bool) -> mr -> Bool
+ Data.Prim.Memory.Fold: ianyOffMem :: forall e mr. (Prim e, MemRead mr) => Off e -> Count e -> (Off e -> e -> Bool) -> mr -> Bool
+ Data.Prim.Memory.Fold: ifoldMapOffMem :: forall e m mr. (Prim e, MemRead mr, Monoid m) => Off e -> Count e -> (Off e -> e -> m) -> mr -> m
+ Data.Prim.Memory.Fold: ifoldlLazyMem :: forall e a mr. (Prim e, MemRead mr) => (a -> Off e -> e -> a) -> a -> mr -> a
+ Data.Prim.Memory.Fold: ifoldlLazyOffMem :: forall e a mr. (Prim e, MemRead mr) => Off e -> Count e -> (a -> Off e -> e -> a) -> a -> mr -> a
+ Data.Prim.Memory.Fold: ifoldlMem :: forall e a mr. (Prim e, MemRead mr) => (a -> Off e -> e -> a) -> a -> mr -> a
+ Data.Prim.Memory.Fold: ifoldlOffMem :: forall e a mr. (Prim e, MemRead mr) => Off e -> Count e -> (a -> Off e -> e -> a) -> a -> mr -> a
+ Data.Prim.Memory.Fold: ifoldrLazyMem :: forall e a mr. (Prim e, MemRead mr) => (Off e -> e -> a -> a) -> a -> mr -> a
+ Data.Prim.Memory.Fold: ifoldrLazyOffMem :: forall e a mr. (Prim e, MemRead mr) => Off e -> Count e -> (Off e -> e -> a -> a) -> a -> mr -> a
+ Data.Prim.Memory.Fold: ifoldrMem :: forall e a mr. (Prim e, MemRead mr) => (Off e -> e -> a -> a) -> a -> mr -> a
+ Data.Prim.Memory.Fold: ifoldrOffMem :: forall e a mr. (Prim e, MemRead mr) => Off e -> Count e -> (Off e -> e -> a -> a) -> a -> mr -> a
+ Data.Prim.Memory.ForeignPtr: instance Data.Prim.Memory.ForeignPtr.PtrAccess GHC.Prim.RealWorld (GHC.ForeignPtr.ForeignPtr a)
+ Data.Prim.Memory.PArray: Inc :: Pinned
+ Data.Prim.Memory.PArray: PArray :: Bytes p -> PArray (p :: Pinned) e
+ Data.Prim.Memory.PArray: PMArray :: MBytes p s -> PMArray (p :: Pinned) e s
+ Data.Prim.Memory.PArray: Pin :: Pinned
+ Data.Prim.Memory.PArray: allocAlignedPMArray :: (MonadPrim s m, Prim e) => Count e -> m (PMArray 'Pin e s)
+ Data.Prim.Memory.PArray: allocPMArray :: forall e p m s. (Typeable p, Prim e, MonadPrim s m) => Size -> m (PMArray p e s)
+ Data.Prim.Memory.PArray: allocPinnedPMArray :: forall e m s. (MonadPrim s m, Prim e) => Size -> m (PMArray 'Pin e s)
+ Data.Prim.Memory.PArray: allocUnpinnedPMArray :: forall e m s. (MonadPrim s m, Prim e) => Size -> m (PMArray 'Inc e s)
+ Data.Prim.Memory.PArray: castPArray :: PArray p e' -> PArray p e
+ Data.Prim.Memory.PArray: castPMArray :: PMArray p e' s -> PMArray p e s
+ Data.Prim.Memory.PArray: copyPArrayToPMArray :: forall e p m s. (MonadPrim s m, Prim e) => PArray p e -> Int -> PMArray p e s -> Int -> Size -> m ()
+ Data.Prim.Memory.PArray: data Pinned
+ Data.Prim.Memory.PArray: freezePMArray :: MonadPrim s m => PMArray p e s -> m (PArray p e)
+ Data.Prim.Memory.PArray: fromBytesPArray :: Bytes p -> PArray p e
+ Data.Prim.Memory.PArray: fromMBytesPMArray :: MBytes p s -> PMArray p e s
+ Data.Prim.Memory.PArray: fromUArrayPArray :: UArray e -> PArray 'Inc e
+ Data.Prim.Memory.PArray: fromUMArrayPMArray :: UMArray e s -> PMArray 'Inc e s
+ Data.Prim.Memory.PArray: getSizePMArray :: forall e p m s. (MonadPrim s m, Prim e) => PMArray p e s -> m Size
+ Data.Prim.Memory.PArray: instance (Data.Prim.Class.Prim e, GHC.Classes.Eq e) => GHC.Classes.Eq (Data.Prim.Memory.PArray.PArray p e)
+ Data.Prim.Memory.PArray: instance (Data.Prim.Class.Prim e, GHC.Classes.Ord e) => GHC.Classes.Ord (Data.Prim.Memory.PArray.PArray p e)
+ Data.Prim.Memory.PArray: instance (Data.Typeable.Internal.Typeable p, Data.Prim.Class.Prim e) => GHC.Exts.IsList (Data.Prim.Memory.PArray.PArray p e)
+ Data.Prim.Memory.PArray: instance (GHC.Show.Show e, Data.Prim.Class.Prim e) => GHC.Show.Show (Data.Prim.Memory.PArray.PArray p e)
+ Data.Prim.Memory.PArray: instance Control.DeepSeq.NFData (Data.Prim.Memory.PArray.PArray p e)
+ Data.Prim.Memory.PArray: instance Control.DeepSeq.NFData (Data.Prim.Memory.PArray.PMArray p e s)
+ Data.Prim.Memory.PArray: instance Data.Prim.Memory.ForeignPtr.PtrAccess s (Data.Prim.Memory.PArray.PArray 'Data.Prim.Memory.Bytes.Internal.Pin e)
+ Data.Prim.Memory.PArray: instance Data.Prim.Memory.ForeignPtr.PtrAccess s (Data.Prim.Memory.PArray.PMArray 'Data.Prim.Memory.Bytes.Internal.Pin e s)
+ Data.Prim.Memory.PArray: instance Data.Prim.Memory.Internal.MemRead (Data.Prim.Memory.PArray.PArray p e)
+ Data.Prim.Memory.PArray: instance Data.Prim.Memory.Internal.MemWrite (Data.Prim.Memory.PArray.PMArray p e)
+ Data.Prim.Memory.PArray: instance Data.Typeable.Internal.Typeable p => Data.Prim.Memory.Internal.MemAlloc (Data.Prim.Memory.PArray.PMArray p e)
+ Data.Prim.Memory.PArray: instance Data.Typeable.Internal.Typeable p => Data.String.IsString (Data.Prim.Memory.PArray.PArray p GHC.Types.Char)
+ Data.Prim.Memory.PArray: instance Data.Typeable.Internal.Typeable p => GHC.Base.Monoid (Data.Prim.Memory.PArray.PArray p e)
+ Data.Prim.Memory.PArray: instance Data.Typeable.Internal.Typeable p => GHC.Base.Semigroup (Data.Prim.Memory.PArray.PArray p e)
+ Data.Prim.Memory.PArray: isPinnedPArray :: PArray p e -> Bool
+ Data.Prim.Memory.PArray: isPinnedPMArray :: PMArray p e s -> Bool
+ Data.Prim.Memory.PArray: movePMArrayToPMArray :: forall e p m s. (MonadPrim s m, Prim e) => PMArray p e s -> Int -> PMArray p e s -> Int -> Size -> m ()
+ Data.Prim.Memory.PArray: newtype PArray (p :: Pinned) e
+ Data.Prim.Memory.PArray: newtype PMArray (p :: Pinned) e s
+ Data.Prim.Memory.PArray: readPMArray :: (MonadPrim s m, Prim e) => PMArray p e s -> Int -> m e
+ Data.Prim.Memory.PArray: reallocPMArray :: forall e p m s. (MonadPrim s m, Typeable p, Prim e) => PMArray p e s -> Size -> m (PMArray p e s)
+ Data.Prim.Memory.PArray: resizePMArray :: forall e p m s. (MonadPrim s m, Prim e) => PMArray p e s -> Size -> m (PMArray 'Inc e s)
+ Data.Prim.Memory.PArray: setPMArray :: forall e p m s. (MonadPrim s m, Prim e) => PMArray p e s -> Int -> Size -> e -> m ()
+ Data.Prim.Memory.PArray: shrinkPMArray :: forall e p m s. (MonadPrim s m, Prim e) => PMArray p e s -> Size -> m ()
+ Data.Prim.Memory.PArray: sizePArray :: forall e p. Prim e => PArray p e -> Size
+ Data.Prim.Memory.PArray: thawPArray :: MonadPrim s m => PArray p e -> m (PMArray p e s)
+ Data.Prim.Memory.PArray: toBytesPArray :: PArray p e -> Bytes p
+ Data.Prim.Memory.PArray: toMBytesPMArray :: PMArray p e s -> MBytes p s
+ Data.Prim.Memory.PArray: toUArrayPArray :: PArray p e -> UArray e
+ Data.Prim.Memory.PArray: toUMArrayPMArray :: PMArray p e s -> UMArray e s
+ Data.Prim.Memory.PArray: writePMArray :: (MonadPrim s m, Prim e) => PMArray p e s -> Int -> e -> m ()
+ Data.Prim.Memory.Text: fromArrayBytes :: Array -> Bytes 'Inc
+ Data.Prim.Memory.Text: fromMArrayMBytes :: MArray s -> MBytes 'Inc s
+ Data.Prim.Memory.Text: toArrayBytes :: Bytes p -> Array
+ Data.Prim.Memory.Text: toMArrayMBytes :: MBytes p s -> MArray s
- Data.Prim.Memory: compareMem :: forall e mr1 mr2. (MemRead mr1, MemRead mr2, Prim e) => mr1 -> Off e -> mr2 -> Off e -> Count e -> Ordering
+ Data.Prim.Memory: compareMem :: forall e mr. (Prim e, Ord e, MemRead mr) => mr -> mr -> Ordering
- Data.Prim.Memory: eqMem :: (MemRead mr1, MemRead mr2) => mr1 -> mr2 -> Bool
+ Data.Prim.Memory: eqMem :: forall e mr. (Prim e, Eq e, MemRead mr) => mr -> mr -> Bool
- Data.Prim.Memory: thawCloneMem :: forall mr ma m s. (MemRead mr, MemAlloc ma, MonadPrim s m) => mr -> m (ma s)
+ Data.Prim.Memory: thawCloneMem :: forall ma m s. (MemAlloc ma, MonadPrim s m) => FrozenMem ma -> m (ma s)
- Data.Prim.Memory: thawCopyMem :: forall e mr ma m s. (Prim e, MemRead mr, MemAlloc ma, MonadPrim s m) => mr -> Off e -> Count e -> m (ma s)
+ Data.Prim.Memory: thawCopyMem :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => FrozenMem ma -> Off e -> Count e -> m (ma s)
- Data.Prim.Memory.Addr: Addr :: Addr# -> {-# UNPACK #-} !Bytes 'Pin -> Addr e
+ Data.Prim.Memory.Addr: Addr :: Addr# -> Bytes 'Pin -> Addr e
- Data.Prim.Memory.Addr: MAddr :: Addr# -> {-# UNPACK #-} !MBytes 'Pin s -> MAddr e s
+ Data.Prim.Memory.Addr: MAddr :: Addr# -> MBytes 'Pin s -> MAddr e s
- Data.Prim.Memory.Addr: [addrBytes] :: Addr e -> {-# UNPACK #-} !Bytes 'Pin
+ Data.Prim.Memory.Addr: [addrBytes] :: Addr e -> Bytes 'Pin
- Data.Prim.Memory.Addr: [mAddrMBytes] :: MAddr e s -> {-# UNPACK #-} !MBytes 'Pin s
+ Data.Prim.Memory.Addr: [mAddrMBytes] :: MAddr e s -> MBytes 'Pin s
- Data.Prim.Memory.Addr: allocMAddr :: (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)
+ Data.Prim.Memory.Addr: allocMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)
- Data.Prim.Memory.Addr: fromBytesAddr :: Bytes 'Pin -> Addr e
+ Data.Prim.Memory.Addr: fromBytesAddr :: Bytes 'Pin -> Addr e
- Data.Prim.Memory.ByteString: fromBuilderBytes :: Builder -> Bytes 'Pin
+ Data.Prim.Memory.ByteString: fromBuilderBytes :: Builder -> Bytes 'Pin
- Data.Prim.Memory.ByteString: fromLazyByteStringBytes :: ByteString -> Bytes 'Pin
+ Data.Prim.Memory.ByteString: fromLazyByteStringBytes :: ByteString -> Bytes 'Pin
- Data.Prim.Memory.ByteString: fromShortByteStringBytes :: ShortByteString -> Bytes 'Inc
+ Data.Prim.Memory.ByteString: fromShortByteStringBytes :: ShortByteString -> Bytes 'Inc
- Data.Prim.Memory.ByteString: toByteStringBytes :: Bytes 'Pin -> ByteString
+ Data.Prim.Memory.ByteString: toByteStringBytes :: Bytes 'Pin -> ByteString
- Data.Prim.Memory.Bytes: allocAlignedMBytes :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Pin s)
+ Data.Prim.Memory.Bytes: allocAlignedMBytes :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Pin s)
- Data.Prim.Memory.Bytes: allocPinnedMBytes :: (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Pin s)
+ Data.Prim.Memory.Bytes: allocPinnedMBytes :: (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Pin s)
- Data.Prim.Memory.Bytes: allocUnpinnedMBytes :: (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Inc s)
+ Data.Prim.Memory.Bytes: allocUnpinnedMBytes :: (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Inc s)
- Data.Prim.Memory.Bytes: ensurePinnedBytes :: Bytes p -> Bytes 'Pin
+ Data.Prim.Memory.Bytes: ensurePinnedBytes :: Bytes p -> Bytes 'Pin
- Data.Prim.Memory.Bytes: ensurePinnedMBytes :: MonadPrim s m => MBytes p s -> m (MBytes 'Pin s)
+ Data.Prim.Memory.Bytes: ensurePinnedMBytes :: MonadPrim s m => MBytes p s -> m (MBytes 'Pin s)
- Data.Prim.Memory.Bytes: fromByteArray# :: ByteArray# -> Bytes 'Inc
+ Data.Prim.Memory.Bytes: fromByteArray# :: ByteArray# -> Bytes 'Inc
- Data.Prim.Memory.Bytes: fromMutableByteArray# :: MutableByteArray# s -> MBytes 'Inc s
+ Data.Prim.Memory.Bytes: fromMutableByteArray# :: MutableByteArray# s -> MBytes 'Inc s
- Data.Prim.Memory.Bytes: isSamePinnedBytes :: Bytes 'Pin -> Bytes 'Pin -> Bool
+ Data.Prim.Memory.Bytes: isSamePinnedBytes :: Bytes 'Pin -> Bytes 'Pin -> Bool
- Data.Prim.Memory.Bytes: relaxPinnedBytes :: Bytes 'Pin -> Bytes p
+ Data.Prim.Memory.Bytes: relaxPinnedBytes :: Bytes 'Pin -> Bytes p
- Data.Prim.Memory.Bytes: relaxPinnedMBytes :: MBytes 'Pin e -> MBytes p e
+ Data.Prim.Memory.Bytes: relaxPinnedMBytes :: MBytes 'Pin e -> MBytes p e
- Data.Prim.Memory.Bytes: resizeMBytes :: (MonadPrim s m, Prim e) => MBytes p s -> Count e -> m (MBytes 'Inc s)
+ Data.Prim.Memory.Bytes: resizeMBytes :: (MonadPrim s m, Prim e) => MBytes p s -> Count e -> m (MBytes 'Inc s)
- Data.Prim.Memory.Bytes: toForeignPtrBytes :: Bytes 'Pin -> ForeignPtr e
+ Data.Prim.Memory.Bytes: toForeignPtrBytes :: Bytes 'Pin -> ForeignPtr e
- Data.Prim.Memory.Bytes: toForeignPtrMBytes :: MBytes 'Pin s -> ForeignPtr e
+ Data.Prim.Memory.Bytes: toForeignPtrMBytes :: MBytes 'Pin s -> ForeignPtr e
- Data.Prim.Memory.Bytes: toInconclusiveBytes :: Bytes p -> Bytes 'Inc
+ Data.Prim.Memory.Bytes: toInconclusiveBytes :: Bytes p -> Bytes 'Inc
- Data.Prim.Memory.Bytes: toInconclusiveMBytes :: MBytes p e -> MBytes 'Inc e
+ Data.Prim.Memory.Bytes: toInconclusiveMBytes :: MBytes p e -> MBytes 'Inc e
- Data.Prim.Memory.Bytes: toPinnedBytes :: Bytes p -> Maybe (Bytes 'Pin)
+ Data.Prim.Memory.Bytes: toPinnedBytes :: Bytes p -> Maybe (Bytes 'Pin)
- Data.Prim.Memory.Bytes: toPinnedMBytes :: MBytes p s -> Maybe (MBytes 'Pin s)
+ Data.Prim.Memory.Bytes: toPinnedMBytes :: MBytes p s -> Maybe (MBytes 'Pin s)
- Data.Prim.Memory.Bytes: toPtrBytes :: Bytes 'Pin -> Ptr e
+ Data.Prim.Memory.Bytes: toPtrBytes :: Bytes 'Pin -> Ptr e
- Data.Prim.Memory.Bytes: toPtrMBytes :: MBytes 'Pin s -> Ptr e
+ Data.Prim.Memory.Bytes: toPtrMBytes :: MBytes 'Pin s -> Ptr e
- Data.Prim.Memory.Bytes: withNoHaltPtrBytes :: MonadUnliftPrim s m => Bytes 'Pin -> (Ptr e -> m b) -> m b
+ Data.Prim.Memory.Bytes: withNoHaltPtrBytes :: MonadUnliftPrim s m => Bytes 'Pin -> (Ptr e -> m b) -> m b
- Data.Prim.Memory.Bytes: withNoHaltPtrMBytes :: MonadUnliftPrim s m => MBytes 'Pin s -> (Ptr e -> m b) -> m b
+ Data.Prim.Memory.Bytes: withNoHaltPtrMBytes :: MonadUnliftPrim s m => MBytes 'Pin s -> (Ptr e -> m b) -> m b
- Data.Prim.Memory.Bytes: withPtrBytes :: MonadPrim s m => Bytes 'Pin -> (Ptr e -> m b) -> m b
+ Data.Prim.Memory.Bytes: withPtrBytes :: MonadPrim s m => Bytes 'Pin -> (Ptr e -> m b) -> m b
- Data.Prim.Memory.Bytes: withPtrMBytes :: MonadPrim s m => MBytes 'Pin s -> (Ptr e -> m b) -> m b
+ Data.Prim.Memory.Bytes: withPtrMBytes :: MonadPrim s m => MBytes 'Pin s -> (Ptr e -> m b) -> m b
- Data.Prim.Memory.ForeignPtr: castForeignPtr :: () => ForeignPtr a -> ForeignPtr b
+ Data.Prim.Memory.ForeignPtr: castForeignPtr :: ForeignPtr a -> ForeignPtr b
- Data.Prim.Memory.ForeignPtr: toForeignPtrBytes :: Bytes 'Pin -> ForeignPtr e
+ Data.Prim.Memory.ForeignPtr: toForeignPtrBytes :: Bytes 'Pin -> ForeignPtr e
- Data.Prim.Memory.ForeignPtr: toForeignPtrMBytes :: MBytes 'Pin s -> ForeignPtr e
+ Data.Prim.Memory.ForeignPtr: toForeignPtrMBytes :: MBytes 'Pin s -> ForeignPtr e
- Data.Prim.Memory.ForeignPtr: unsafeForeignPtrToPtr :: () => ForeignPtr a -> Ptr a
+ Data.Prim.Memory.ForeignPtr: unsafeForeignPtrToPtr :: ForeignPtr a -> Ptr a

Files

CHANGELOG.md view
@@ -1,5 +1,13 @@ # Changelog for primal-memory +## 0.3.0++* Rename many functions that perform mutation. Add `Mut` infix to operations that deal+  with mutable source memory regions.+* Rename `resizeMem` -> `reallocMutMem`+* Export `defaultReallocMutMem`+* Rename `PrimArray` -> `PArray` and `MPrimArray` -> `PMArray`+ ## 0.2.0  * Rename `ByteArray` -> `PrimArray`
bench/Bench.hs view
@@ -1,8 +1,9 @@ {-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-}-+{-# OPTIONS_GHC -fno-warn-orphans #-} module Main (main) where  import GHC.Exts@@ -11,12 +12,16 @@ import Criterion.Main import Data.Prim.Memory.Bytes import Data.Prim.Memory.Ptr-import Control.Prim.Monad import qualified Data.Primitive.Types as BA import qualified Data.Primitive.ByteArray as BA-import qualified Control.Monad.Primitive as BA import Foreign.Storable as S+import Foreign.ForeignPtr+import GHC.ForeignPtr+import Control.DeepSeq +instance NFData (ForeignPtr a) where+  rnf !_ = ()+ main :: IO () main = do   let n = 1000000 :: Count a@@ -102,16 +107,12 @@             ]         , bgroup             "peek"-            [ benchPeek (Proxy :: Proxy Word8) mb1 mba-            , benchPeek (Proxy :: Proxy Word16) mb1 mba-            , benchPeek (Proxy :: Proxy Word32) mb1 mba-            , benchPeek (Proxy :: Proxy Word64) mb1 mba-            , benchPeek (Proxy :: Proxy Char) mb1 mba-            , bgroup-                "Bool"-                [ bench "Bytes" $-                  whnfIO (withPtrMBytes mb1 (readPtr :: Ptr Bool -> IO Bool))-                ]+            [ env mallocPlainForeignPtr (benchPeek (Proxy :: Proxy Word8) mb1)+            , env mallocPlainForeignPtr (benchPeek (Proxy :: Proxy Word16) mb1)+            , env mallocPlainForeignPtr (benchPeek (Proxy :: Proxy Word32) mb1)+            , env mallocPlainForeignPtr (benchPeek (Proxy :: Proxy Word64) mb1)+            , env mallocPlainForeignPtr (benchPeek (Proxy :: Proxy Char) mb1)+            , env mallocPlainForeignPtr (benchPeek (Proxy :: Proxy Bool) mb1)             ]         ]     ]@@ -145,20 +146,16 @@   where i = 100  benchPeek ::-     forall a. (Typeable a, Prim a, BA.Prim a)+     forall a. (Typeable a, Prim a, S.Storable a)   => Proxy a   -> MBytes 'Pin RealWorld-  -> BA.MutableByteArray RealWorld+  -> ForeignPtr a   -> Benchmark-benchPeek px mb mba =+benchPeek px mb fptr =   bgroup     (showsType px "")     [ bench "Bytes" $ whnfIO $ withPtrMBytes mb (readPtr :: Ptr a -> IO a)-    , bench "ByteArray" $-      whnfIO $ do-        let ptr = BA.mutableByteArrayContents mba-        res <- S.peek ptr-        res <$ BA.touch mba+    , bench "ForeignPtr" $ whnfIO $ withForeignPtr fptr S.peek     ]  setBytesBench ::
+ bench/Compare.hs view
@@ -0,0 +1,107 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Main (main) where++import Criterion.Main+import Data.Prim.Memory+import Data.Prim.Memory.Addr+import Data.Prim.Memory.Bytes+import Data.Prim.Memory.ByteString+import Data.Prim.Memory.PArray+import qualified Data.Primitive.ByteArray as BA+import Data.Primitive.PrimArray++main :: IO ()+main = do+  let n = 1000000 :: Count a+      n64 = n :: Count Word64+  -- Ensure that arrays are equal by filling them with zeros+  bEq1 <- freezeMBytes =<< allocZeroAlignedMBytes n64+  bEq2 <- freezeMBytes =<< allocZeroAlignedMBytes n64+  mbaEq1 <- BA.newAlignedPinnedByteArray (unCountBytes (n :: Count Word64)) 8+  mbaEq2 <- BA.newAlignedPinnedByteArray (unCountBytes (n :: Count Word64)) 8+  BA.setByteArray mbaEq1 0 (unCount n64) (0 :: Word64)+  BA.setByteArray mbaEq2 0 (unCount n64) (0 :: Word64)+  baEq1 <- BA.unsafeFreezeByteArray mbaEq1+  baEq2 <- BA.unsafeFreezeByteArray mbaEq2+  let paEq1 = PArray bEq1 :: PArray 'Pin Word64+      paEq2 = PArray bEq2 :: PArray 'Pin Word64+      bsEq1 = convertMem bEq1 :: ByteString+      bsEq2 = convertMem bEq2 :: ByteString+      addrEq1 = fromBytesAddr bEq1 :: Addr Word64+      addrEq2 = fromBytesAddr bEq2 :: Addr Word64+      primEq1 = PrimArray (toByteArray# bEq1) :: PrimArray Word64+      primEq2 = PrimArray (toByteArray# bEq2) :: PrimArray Word64+      pa8Eq1 = PArray bEq1 :: PArray 'Pin Word8+      pa8Eq2 = PArray bEq2 :: PArray 'Pin Word8+      addr8Eq1 = fromBytesAddr bEq1 :: Addr Word8+      addr8Eq2 = fromBytesAddr bEq2 :: Addr Word8+      prim8Eq1 = PrimArray (toByteArray# bEq1) :: PrimArray Word8+      prim8Eq2 = PrimArray (toByteArray# bEq2) :: PrimArray Word8++      addr16Eq1 = fromBytesAddr bEq1 :: Addr Word16+      addr16Eq2 = fromBytesAddr bEq2 :: Addr Word16+      pa16Eq1 = PArray bEq1 :: PArray 'Pin Word16+      pa16Eq2 = PArray bEq2 :: PArray 'Pin Word16+      prim16Eq1 = PrimArray (toByteArray# bEq1) :: PrimArray Word16+      prim16Eq2 = PrimArray (toByteArray# bEq2) :: PrimArray Word16+      addr32Eq1 = fromBytesAddr bEq1 :: Addr Word32+      addr32Eq2 = fromBytesAddr bEq2 :: Addr Word32+      pa32Eq1 = PArray bEq1 :: PArray 'Pin Word32+      pa32Eq2 = PArray bEq2 :: PArray 'Pin Word32+      prim32Eq1 = PrimArray (toByteArray# bEq1) :: PrimArray Word32+      prim32Eq2 = PrimArray (toByteArray# bEq2) :: PrimArray Word32+  defaultMain+    [ bgroup+        "eq"+        [ bgroup+            "Word8"+            [ bench "Bytes" $ whnf (bEq1 ==) bEq2+            , bench "ByteArray" $ whnf (baEq1 ==) baEq2+            , bench "ByteString" $ whnf (bsEq1 ==) bsEq2+            , bench "Addr" $ whnf (addr8Eq1 ==) addr8Eq2+            , bench "PArray" $ whnf (pa8Eq1 ==) pa8Eq2+            , bench "PrimArray" $ whnf (prim8Eq1 ==) prim8Eq2+            ]+        , bgroup+            "Word64"+            [ bench "Addr" $ whnf (addrEq1 ==) addrEq2+            , bench "PArray" $ whnf (paEq1 ==) paEq2+            , bench "PrimArray" $ whnf (primEq1 ==) primEq2+            ]+        ]+    , bgroup+        "compare"+        [ bgroup+            "Word8"+            [ bench "Bytes" $ whnf (compare bEq1) bEq2+            , bench "ByteArray" $ whnf (compare baEq1) baEq2+            , bench "ByteString" $ whnf (compare bsEq1) bsEq2+            , bench "Addr" $ whnf (compare addr8Eq1) addr8Eq2+            , bench "PArray" $ whnf (compare pa8Eq1) pa8Eq2+            , bench "PrimArray" $ whnf (compare prim8Eq1) prim8Eq2+            ]+        , bgroup+            "Word16"+            [ bench "Addr" $ whnf (compare addr16Eq1) addr16Eq2+            , bench "PArray" $ whnf (compare pa16Eq1) pa16Eq2+            , bench "PrimArray" $ whnf (compare prim16Eq1) prim16Eq2+            ]+        , bgroup+            "Word32"+            [ bench "Addr" $ whnf (compare addr32Eq1) addr32Eq2+            , bench "PArray" $ whnf (compare pa32Eq1) pa32Eq2+            , bench "PrimArray" $ whnf (compare prim32Eq1) prim32Eq2+            ]+        , bgroup+            "Word64"+            [ bench "Addr" $ whnf (compare addrEq1) addrEq2+            , bench "PArray" $ whnf (compare paEq1) paEq2+            , bench "PrimArray" $ whnf (compare primEq1) primEq2+            ]+        ]+    ]
bench/Conversion.hs view
@@ -5,15 +5,16 @@  module Main (main) where -import GHC.Exts+import Control.Prim.Eval+import Control.Prim.Monad import Criterion.Main import Data.Prim.Memory.Bytes+import Data.Prim.Memory.ForeignPtr import Data.Prim.Memory.Ptr-import Control.Prim.Monad+import qualified Data.Primitive.ByteArray as BA import qualified Foreign.ForeignPtr as GHC import Foreign.Storable-import Data.Prim.Memory.ForeignPtr-import qualified Data.Primitive.ByteArray as BA+import Foreign.Prim  main :: IO () main = do@@ -28,8 +29,8 @@   mba <- BA.newAlignedPinnedByteArray (unCountBytes (n :: Count Word64)) 8   ba <- BA.unsafeFreezeByteArray mba   -- Ensure that arrays are equal by filling them with zeros-  bEq1 <- freezeMBytes =<< callocAlignedMBytes n64-  bEq2 <- freezeMBytes =<< callocAlignedMBytes n64+  bEq1 <- freezeMBytes =<< allocZeroAlignedMBytes n64+  bEq2 <- freezeMBytes =<< allocZeroAlignedMBytes n64   mbaEq1 <- BA.newAlignedPinnedByteArray (unCountBytes (n :: Count Word64)) 8   mbaEq2 <- BA.newAlignedPinnedByteArray (unCountBytes (n :: Count Word64)) 8   BA.setByteArray mbaEq1 0 (unCount n64) (0 :: Word64)@@ -81,7 +82,7 @@             ]         , bgroup             "fromListN"-            [ bench "Bytes" $ whnf (fromListBytesN_ n :: [Int] -> Bytes 'Inc) xs+            [ bench "Bytes" $ whnf (fromListZeroBytesN_ n :: [Int] -> Bytes 'Inc) xs             , bench "ByteArray" $ whnf (BA.byteArrayFromListN (unCount n)) xs             ]         ]
primal-memory.cabal view
@@ -1,5 +1,5 @@ name:                primal-memory-version:             0.2.0.0+version:             0.3.0.0 synopsis:            Unified interface for memory managemenet. description:         Please see the README on GitHub at <https://github.com/lehins/primal#readme> homepage:            https://github.com/lehins/primal@@ -13,13 +13,15 @@ extra-source-files:  README.md                    , CHANGELOG.md cabal-version:       1.18-tested-with:         GHC == 8.4.3+tested-with:         GHC == 8.0.2+                   , GHC == 8.2.2+                   , GHC == 8.4.3                    , GHC == 8.4.4                    , GHC == 8.6.3                    , GHC == 8.6.4                    , GHC == 8.6.5-                   , GHC == 8.8.1-                   , GHC == 8.8.2+                   , GHC == 8.8.3+                   , GHC == 8.8.4                    , GHC == 8.10.1  library@@ -29,7 +31,8 @@                      , Data.Prim.Memory.ByteString                      , Data.Prim.Memory.Bytes                      , Data.Prim.Memory.ForeignPtr-                     , Data.Prim.Memory.PrimArray+                     , Data.Prim.Memory.Fold+                     , Data.Prim.Memory.PArray                      , Data.Prim.Memory.Ptr                      , Data.Prim.Memory.Text                      , Data.Prim.Memory.Internal@@ -66,7 +69,6 @@   ghc-options:         -Wall                        -threaded                        -O2-                       -with-rtsopts=-N   build-depends:       base                      , criterion                      , primal@@ -83,7 +85,6 @@   ghc-options:         -Wall                        -threaded                        -O2-                       -with-rtsopts=-N   build-depends:       base                      , criterion                      , primal@@ -93,6 +94,22 @@                      , random   default-language:    Haskell2010 +benchmark compare+  type:                exitcode-stdio-1.0+  hs-source-dirs:      bench+  main-is:             Compare.hs+  ghc-options:         -Wall+                       -threaded+                       -O2+  build-depends:       base+                     , criterion+                     , primal+                     , primal-memory+                     , primitive+                     , deepseq+                     , random+  default-language:    Haskell2010+ source-repository head   type:     git-  location: https://github.com/lehins/prim-bytes+  location: https://github.com/lehins/primal
src/Data/Prim/Memory.hs view
@@ -6,6 +6,8 @@ -- Stability   : experimental -- Portability : non-portable --+{-# LANGUAGE BangPatterns #-}+ module Data.Prim.Memory   ( module Data.Prim   , Pinned(..)@@ -35,7 +37,12 @@   , copyByteOffToPtrMem       -- DOC: [x], DOCTEST [ ], TEST: [x]   -- ** Compare   , eqMem                     -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , eqOffMem                  -- DOC: [x], DOCTEST [ ], TEST: [ ]+  , eqByteMem                 -- DOC: [x], DOCTEST [ ], TEST: [ ]+  , eqByteOffMem              -- DOC: [x], DOCTEST [ ], TEST: [ ]   , compareMem                -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , compareOffMem             -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , compareByteMem            -- DOC: [ ], DOCTEST [ ], TEST: [ ]   , compareByteOffMem         -- DOC: [x], DOCTEST [ ], TEST: [ ]   , compareByteOffToPtrMem    -- DOC: [x], DOCTEST [ ], TEST: [x]   , compareByteOffToBytesMem  -- DOC: [x], DOCTEST [ ], TEST: [x]@@ -60,47 +67,51 @@   , MemAlloc(FrozenMem)   , MemState(..)   -- ** Size-  , getCountMem               -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , getCountRemMem            -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , getByteCountMem           -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , getCountMutMem               -- DOC: [x], DOCTEST [x], TEST: [ ]+  , getCountRemMutMem            -- DOC: [x], DOCTEST [x], TEST: [ ]+  , getByteCountMutMem           -- DOC: [x], DOCTEST [x], TEST: [ ]   -- ** Read-  , readOffMem                -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , readByteOffMem            -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , readOffMutMem                -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , readByteOffMutMem            -- DOC: [ ], DOCTEST [ ], TEST: [ ]   -- ** Write-  , writeOffMem               -- DOC: [x], DOCTEST [ ], TEST: [x]-  , writeByteOffMem           -- DOC: [x], DOCTEST [ ], TEST: [x]-  , setMem                    -- DOC: [x], DOCTEST [ ], TEST: [x]-  , modifyFetchOldMem         -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , modifyFetchOldMemM        -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , modifyFetchNewMem         -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , modifyFetchNewMemM        -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , writeOffMutMem               -- DOC: [x], DOCTEST [ ], TEST: [x]+  , writeByteOffMutMem           -- DOC: [x], DOCTEST [ ], TEST: [x]+  , setMutMem                    -- DOC: [x], DOCTEST [ ], TEST: [x]+  , modifyFetchOldMutMem         -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , modifyFetchOldMutMemM        -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , modifyFetchNewMutMem         -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , modifyFetchNewMutMemM        -- DOC: [ ], DOCTEST [ ], TEST: [ ]   -- ** Allocate-  , allocMem                  -- DOC: [x], DOCTEST [ ], TEST: [ ]-  , allocZeroMem              -- DOC: [x], DOCTEST [x], TEST: [ ]-  , thawMem                   -- DOC: [x], DOCTEST [ ], TEST: [ ]-  , thawCloneMem              -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , thawCopyMem               -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , freezeMem                 -- DOC: [x], DOCTEST [ ], TEST: [ ]-  , freezeCloneMem            -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , freezeCopyMem             -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , resizeMem                 -- DOC: [x], DOCTEST [ ], TEST: [ ]-  , withScrubbedMem           -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , allocMutMem                  -- DOC: [x], DOCTEST [ ], TEST: [ ]+  , allocZeroMutMem              -- DOC: [x], DOCTEST [x], TEST: [ ]+  , reallocMutMem                -- DOC: [x], DOCTEST [ ], TEST: [x]+  , withScrubbedMutMem           -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , defaultReallocMutMem         -- DOC: [x], DOCTEST [ ], TEST: [x]+  -- ** Thaw/Freeze+  , thawCloneMem                 -- DOC: [x], DOCTEST [x], TEST: [ ]+  , thawCopyMem                  -- DOC: [x], DOCTEST [x], TEST: [ ]+  , thawMem                      -- DOC: [x], DOCTEST [ ], TEST: [ ]+  , freezeCloneMutMem            -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , freezeCopyMutMem             -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , freezeMutMem                 -- DOC: [x], DOCTEST [ ], TEST: [ ]   -- ** Move-  , moveMem                   -- DOC: [ ], DOCTEST [ ], TEST: [x]-  , moveByteOffMem            -- DOC: [x], DOCTEST [ ], TEST: [ ]-  , moveByteOffToMBytesMem    -- DOC: [x], DOCTEST [ ], TEST: [x]-  , moveByteOffToPtrMem       -- DOC: [x], DOCTEST [ ], TEST: [x]+  , cloneMutMem                  -- DOC: [x], DOCTEST [ ], TEST: [-]+  , moveMutMem                   -- DOC: [ ], DOCTEST [ ], TEST: [x]+  , moveByteOffMutMem            -- DOC: [x], DOCTEST [ ], TEST: [ ]+  , moveByteOffToMBytesMutMem    -- DOC: [x], DOCTEST [ ], TEST: [x]+  , moveByteOffToPtrMutMem       -- DOC: [x], DOCTEST [ ], TEST: [x]   -- ** Load list-  , loadListMem               -- DOC: [x], DOCTEST [x], TEST: [x]-  , loadListMem_              -- DOC: [x], DOCTEST [x], TEST: [ ]-  , loadListMemN              -- DOC: [x], DOCTEST [ ], TEST: [ ]-  , loadListMemN_             -- DOC: [x], DOCTEST [ ], TEST: [ ]+  , loadListMutMem               -- DOC: [x], DOCTEST [x], TEST: [x]+  , loadListMutMem_              -- DOC: [x], DOCTEST [x], TEST: [ ]+  , loadListMutMemN              -- DOC: [x], DOCTEST [ ], TEST: [ ]+  , loadListMutMemN_             -- DOC: [x], DOCTEST [ ], TEST: [ ]   -- *** With offset-  , loadListOffMem            -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , loadListOffMemN           -- DOC: [ ], DOCTEST [ ], TEST: [ ]-  , loadListByteOffMem        -- DOC: [x], DOCTEST [x], TEST: [ ]-  , loadListByteOffMemN       -- DOC: [x], DOCTEST [x], TEST: [ ]+  , loadListOffMutMem            -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , loadListOffMutMemN           -- DOC: [ ], DOCTEST [ ], TEST: [ ]+  , loadListByteOffMutMem        -- DOC: [x], DOCTEST [x], TEST: [ ]+  , loadListByteOffMutMemN       -- DOC: [x], DOCTEST [x], TEST: [ ]   ) where  import Data.Prim import Data.Prim.Memory.Internal+import Data.Prim.Memory.Fold
src/Data/Prim/Memory/Addr.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}@@ -5,6 +6,7 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RoleAnnotations #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UnboxedTuples #-} -- |@@ -24,6 +26,7 @@   , byteCountAddr   , countAddr   , plusOffAddr+  , plusByteOffAddr   , indexAddr   , indexOffAddr   , indexByteOffAddr@@ -39,8 +42,11 @@    -- * Mutable MAddr   , MAddr(..)   , castMAddr+  , newMAddr   , allocMAddr-  , callocMAddr+  , allocAlignedMAddr+  , allocZeroMAddr+  , allocZeroAlignedMAddr   , reallocMAddr   , shrinkMAddr   , shrinkByteCountMAddr@@ -49,6 +55,7 @@   , getByteCountMAddr   , getCountMAddr   , plusOffMAddr+  , plusByteOffMAddr   , readMAddr   , readOffMAddr   , readByteOffMAddr@@ -58,6 +65,18 @@   , copyAddrToMAddr   , moveMAddrToMAddr ++  , modifyMAddr+  , modifyMAddr_+  , modifyFetchOldMAddr+  , modifyFetchNewMAddr+  , modifyMAddrM+  , modifyMAddrM_+  , modifyFetchOldMAddrM+  , modifyFetchNewMAddrM+  , swapMAddrs_+  , swapMAddrs+   , withPtrMAddr   , withAddrMAddr#   , withNoHaltPtrMAddr@@ -124,6 +143,7 @@  import Control.Arrow (first) import Control.DeepSeq+import Control.Prim.Eval import Control.Prim.Monad import Control.Prim.Monad.Unsafe import Data.ByteString.Internal@@ -136,6 +156,7 @@ import Data.Prim.Memory.Bytes import Data.Prim.Memory.Bytes.Internal import Data.Prim.Memory.ByteString+import Data.Prim.Memory.Fold import Data.Prim.Memory.ForeignPtr import Data.Prim.Memory.Internal import Data.Prim.Memory.Ptr@@ -147,22 +168,27 @@ -- | Immutable read-only address data Addr e = Addr   { addrAddr# :: Addr#-  , addrBytes :: {-# UNPACK #-}!(Bytes 'Pin)+  , addrBytes :: Bytes 'Pin   } type role Addr nominal  -- | Mutable address data MAddr e s = MAddr   { mAddrAddr#  :: Addr#-  , mAddrMBytes :: {-# UNPACK #-}!(MBytes 'Pin s)+  , mAddrMBytes :: MBytes 'Pin s   } type role MAddr nominal nominal  +instance (Eq e, Prim e) => Eq (Addr e) where+  (==) = eqMem @e+  {-# INLINE (==) #-} -instance Eq (Addr e) where-  a1 == a2 = isSameAddr a1 a2 || eqMem a1 a2+instance (Prim e, Ord e) => Ord (Addr e) where+  compare = compareMem @e+  {-# INLINE compare #-} + instance (Show e, Prim e) => Show (Addr e) where   show a = show (toListMem a :: [e]) @@ -177,20 +203,28 @@  instance Semigroup.Semigroup (Addr e) where   (<>) = appendMem+  {-# INLINE (<>) #-}   sconcat (x :| xs) = concatMem (x:xs)+  {-# INLINE sconcat #-}   stimes i = cycleMemN (fromIntegral i)+  {-# INLINE stimes #-}  instance Monoid.Monoid (Addr e) where   mappend = appendMem+  {-# INLINE mappend #-}   mconcat = concatMem+  {-# INLINE mconcat #-}   mempty = emptyMem+  {-# INLINE mempty #-}   castAddr :: Addr e -> Addr b castAddr (Addr a b) = Addr a b+{-# INLINE castAddr #-}  castMAddr :: MAddr e s -> MAddr b s castMAddr (MAddr a mb) = MAddr a mb+{-# INLINE castMAddr #-}  castStateMAddr :: MAddr e s' -> MAddr b s castStateMAddr = unsafeCoerce@@ -198,6 +232,9 @@ isSameAddr :: Addr e -> Addr e -> Bool isSameAddr (Addr a1# _) (Addr a2# _) = isTrue# (a1# `eqAddr#` a2#) +isSameMAddr :: MAddr e s -> MAddr e s -> Bool+isSameMAddr (MAddr a1# _) (MAddr a2# _) = isTrue# (a1# `eqAddr#` a2#)+ instance NFData (Addr e) where   rnf (Addr _ _) = () @@ -214,14 +251,29 @@ fromMBytesMAddr mb =   case toPtrMBytes mb of     Ptr addr# -> MAddr addr# mb+{-# INLINE fromMBytesMAddr #-} -allocMAddr :: (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)-allocMAddr c = fromMBytesMAddr <$> allocAlignedMBytes c+newMAddr :: forall e m s. (MonadPrim s m, Prim e) => e -> m (MAddr e s)+newMAddr e = do+  maddr <- fromMBytesMAddr <$> allocPinnedMBytes (1 :: Count e)+  writeMAddr maddr e+  pure $! maddr+{-# INLINE newMAddr #-} -callocMAddr :: (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)-callocMAddr c = fromMBytesMAddr <$> callocAlignedMBytes c+allocMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)+allocMAddr c = fromMBytesMAddr <$> allocPinnedMBytes c +allocZeroMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)+allocZeroMAddr c = fromMBytesMAddr <$> allocZeroPinnedMBytes c ++allocAlignedMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)+allocAlignedMAddr c = fromMBytesMAddr <$> allocAlignedMBytes c++allocZeroAlignedMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s)+allocZeroAlignedMAddr c = fromMBytesMAddr <$> allocZeroAlignedMBytes c++ -- | Shrink mutable address to new specified size in number of elements. The new count -- must be less than or equal to the current as reported by `getCountMAddr`. shrinkMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> Count e -> m ()@@ -253,9 +305,15 @@ plusOffAddr :: Prim e => Addr e -> Off e -> Addr e plusOffAddr (Addr addr# b) off = Addr (addr# `plusAddr#` unOffBytes# off) b +plusByteOffAddr :: Addr e -> Off Word8 -> Addr e+plusByteOffAddr (Addr addr# b) off = Addr (addr# `plusAddr#` unOffBytes# off) b+ plusOffMAddr :: Prim e => MAddr e s -> Off e -> MAddr e s plusOffMAddr (MAddr addr# mb) off = MAddr (addr# `plusAddr#` unOffBytes# off) mb +plusByteOffMAddr :: MAddr e s -> Off Word8 -> MAddr e s+plusByteOffMAddr (MAddr addr# mb) off = MAddr (addr# `plusAddr#` unOffBytes# off) mb+ curOffAddr :: Prim e => Addr e -> Off e curOffAddr a@(Addr addr# b) = (Ptr addr# `minusOffPtr` toPtrBytes b) `offForProxyTypeOf` a @@ -280,9 +338,12 @@  indexAddr :: Prim e => Addr e -> e indexAddr addr = indexOffAddr addr 0+{-# INLINE indexAddr #-}  indexOffAddr :: Prim e => Addr e -> Off e -> e-indexOffAddr addr off = unsafeInlineIO $ readOffAddr addr off+indexOffAddr addr (Off (I# off#)) =+  unsafeInlineIO $ withAddrAddr# addr $ \addr# -> pure $ indexOffAddr# addr# off#+{-# INLINE indexOffAddr #-}  indexByteOffAddr :: Prim e => Addr e -> Off Word8 -> e indexByteOffAddr addr off = unsafeInlineIO $ readByteOffAddr addr off@@ -298,7 +359,7 @@ {-# INLINE withAddrAddr# #-}  withNoHaltPtrAddr :: MonadUnliftPrim s m => Addr e -> (Ptr e -> m b) -> m b-withNoHaltPtrAddr (Addr addr# b) f = withAliveUnliftPrim b $ f (Ptr addr#)+withNoHaltPtrAddr (Addr addr# b) f = keepAlive b $ f (Ptr addr#) {-# INLINE withNoHaltPtrAddr #-}  curOffMAddr :: forall e s . Prim e => MAddr e s -> Off e@@ -362,7 +423,7 @@ {-# INLINE withAddrMAddr# #-}  withNoHaltPtrMAddr :: MonadUnliftPrim s m => MAddr e s -> (Ptr e -> m b) -> m b-withNoHaltPtrMAddr (MAddr addr# mb) f = withAliveUnliftPrim mb $ f (Ptr addr#)+withNoHaltPtrMAddr (MAddr addr# mb) f = keepAlive mb $ f (Ptr addr#) {-# INLINE withNoHaltPtrMAddr #-}  @@ -388,19 +449,21 @@  instance MemAlloc (MAddr e) where   type FrozenMem (MAddr e) = Addr e-  getByteCountMem = getByteCountMAddr-  {-# INLINE getByteCountMem #-}-  allocMem = fmap castMAddr . allocMAddr-  {-# INLINE allocMem #-}+  getByteCountMutMem = getByteCountMAddr+  {-# INLINE getByteCountMutMem #-}+  allocMutMem = fmap castMAddr . allocMAddr+  {-# INLINE allocMutMem #-}   thawMem = thawAddr   {-# INLINE thawMem #-}-  freezeMem = freezeMAddr-  {-# INLINE freezeMem #-}-  resizeMem maddr = fmap castMAddr . reallocMAddr (castMAddr maddr)-  {-# INLINE resizeMem #-}+  freezeMutMem = freezeMAddr+  {-# INLINE freezeMutMem #-}+  reallocMutMem maddr = fmap castMAddr . reallocMAddr (castMAddr maddr)+  {-# INLINE reallocMutMem #-}   instance MemRead (Addr e) where+  isSameMem = isSameAddr+  {-# INLINE isSameMem #-}   byteCountMem = byteCountAddr   {-# INLINE byteCountMem #-}   indexOffMem a i = unsafeInlineIO $ withAddrAddr# a $ \addr# -> readOffPtr (Ptr addr#) i@@ -425,32 +488,34 @@   {-# INLINE compareByteOffMem #-}  instance MemWrite (MAddr e) where-  readOffMem a = readOffMAddr (castMAddr a)-  {-# INLINE readOffMem #-}-  readByteOffMem a = readByteOffMAddr (castMAddr a)-  {-# INLINE readByteOffMem #-}-  writeOffMem a = writeOffMAddr (castMAddr a)-  {-# INLINE writeOffMem #-}-  writeByteOffMem a = writeByteOffMAddr (castMAddr a)-  {-# INLINE writeByteOffMem #-}-  moveByteOffToPtrMem src srcOff dstPtr dstOff c =+  isSameMutMem = isSameMAddr+  {-# INLINE isSameMutMem #-}+  readOffMutMem a = readOffMAddr (castMAddr a)+  {-# INLINE readOffMutMem #-}+  readByteOffMutMem a = readByteOffMAddr (castMAddr a)+  {-# INLINE readByteOffMutMem #-}+  writeOffMutMem a = writeOffMAddr (castMAddr a)+  {-# INLINE writeOffMutMem #-}+  writeByteOffMutMem a = writeByteOffMAddr (castMAddr a)+  {-# INLINE writeByteOffMutMem #-}+  moveByteOffToPtrMutMem src srcOff dstPtr dstOff c =     withAddrMAddr# src $ \ srcAddr# ->       moveByteOffPtrToPtr (Ptr srcAddr#) srcOff dstPtr dstOff c-  {-# INLINE moveByteOffToPtrMem #-}-  moveByteOffToMBytesMem src srcOff dst dstOff c =+  {-# INLINE moveByteOffToPtrMutMem #-}+  moveByteOffToMBytesMutMem src srcOff dst dstOff c =     withAddrMAddr# src $ \ srcAddr# ->       moveByteOffPtrToMBytes (Ptr srcAddr#) srcOff dst dstOff c-  {-# INLINE moveByteOffToMBytesMem #-}+  {-# INLINE moveByteOffToMBytesMutMem #-}   copyByteOffMem src srcOff dst dstOff c =     withAddrMAddr# dst $ \ dstAddr# ->       copyByteOffToPtrMem src srcOff (Ptr dstAddr#) dstOff c   {-# INLINE copyByteOffMem #-}-  moveByteOffMem src srcOff dst dstOff c =+  moveByteOffMutMem src srcOff dst dstOff c =     withAddrMAddr# dst $ \ dstAddr# ->-      moveByteOffToPtrMem src srcOff (Ptr dstAddr#) dstOff c-  {-# INLINE moveByteOffMem #-}-  setMem maddr = setMAddr (castMAddr maddr)-  {-# INLINE setMem #-}+      moveByteOffToPtrMutMem src srcOff (Ptr dstAddr#) dstOff c+  {-# INLINE moveByteOffMutMem #-}+  setMutMem maddr = setMAddr (castMAddr maddr)+  {-# INLINE setMutMem #-}   @@ -464,25 +529,27 @@   readAddr :: (MonadPrim s m, Prim e) => Addr e -> m e-readAddr addr = readOffAddr addr 0+readAddr (Addr addr# b) = do+  a <- prim (readOffAddr# addr# 0#)+  a <$ touch b {-# INLINE readAddr #-}  readOffAddr :: (MonadPrim s m, Prim e) => Addr e -> Off e -> m e readOffAddr (Addr addr# b) (Off (I# off#)) = do-  -- TODO: benchmark and see if `readOffAddr` is faster here-  a <- prim (seq# (indexOffAddr# addr# off#))+  a <- prim (readOffAddr# addr# off#)   a <$ touch b {-# INLINE readOffAddr #-}  readByteOffAddr :: (MonadPrim s m, Prim e) => Addr e -> Off Word8 -> m e readByteOffAddr (Addr addr# b) (Off (I# off#)) = do-  a <- prim (seq# (indexOffAddr# (addr# `plusAddr#` off#) 0#))+  a <- prim (readOffAddr# (addr# `plusAddr#` off#) 0#)   a <$ touch b {-# INLINE readByteOffAddr #-} - readMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> m e-readMAddr maddr = readOffMAddr maddr 0+readMAddr (MAddr addr# mb) = do+  a <- prim (readOffAddr# addr# 0#)+  a <$ touch mb {-# INLINE readMAddr #-}  readOffMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> Off e -> m e@@ -498,17 +565,18 @@ {-# INLINE readByteOffMAddr #-}  writeMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> e -> m ()-writeMAddr maddr = writeOffMAddr maddr 0+writeMAddr (MAddr addr# mb) e =+  prim_ $ \s -> touch# mb (writeOffAddr# addr# 0# e s) {-# INLINE writeMAddr #-}  writeOffMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> Off e -> e -> m ()-writeOffMAddr (MAddr addr# mb) (Off (I# off#)) a =-  prim_ (writeOffAddr# addr# off# a) >> touch mb+writeOffMAddr (MAddr addr# mb) (Off (I# off#)) e =+  prim_ $ \s -> touch# mb (writeOffAddr# addr# off# e s) {-# INLINE writeOffMAddr #-}  writeByteOffMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> Off Word8 -> e -> m () writeByteOffMAddr (MAddr addr# mb) (Off (I# off#)) a =-  prim_ (writeOffAddr# (addr# `plusAddr#` off#) 0# a) >> touch mb+  prim_ $ \s -> touch# mb (writeOffAddr# (addr# `plusAddr#` off#) 0# a s) {-# INLINE writeByteOffMAddr #-}  @@ -532,6 +600,95 @@ setMAddr (MAddr addr# mb) (Off (I# off#)) (Count (I# n#)) a =   prim_ (setOffAddr# addr# off# n# a) >> touch mb {-# INLINE setMAddr #-}++++-- | Apply a pure function to the contents of a mutable variable. Returns the artifact of+-- computation.+--+-- @since 0.2.0+modifyMAddr :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> (a, b)) -> m b+modifyMAddr maddr f = modifyMAddrM maddr (return . f)+{-# INLINE modifyMAddr #-}++-- | Apply a pure function to the contents of a mutable variable.+--+-- @since 0.1.0+modifyMAddr_ :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> a) -> m ()+modifyMAddr_ maddr f = modifyMAddrM_ maddr (return . f)+{-# INLINE modifyMAddr_ #-}+++-- | Apply a pure function to the contents of a mutable variable. Returns the old value.+--+-- @since 2.0.0+modifyFetchOldMAddr :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> a) -> m a+modifyFetchOldMAddr maddr f = modifyFetchOldMAddrM maddr (return . f)+{-# INLINE modifyFetchOldMAddr #-}++-- | Apply a pure function to the contents of a mutable variable. Returns the new value.+--+-- @since 2.0.0+modifyFetchNewMAddr :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> a) -> m a+modifyFetchNewMAddr maddr f = modifyFetchNewMAddrM maddr (return . f)+{-# INLINE modifyFetchNewMAddr #-}+++-- | Apply a monadic action to the contents of a mutable variable. Returns the artifact of+-- computation.+--+-- @since 0.2.0+modifyMAddrM :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m (a, b)) -> m b+modifyMAddrM maddr f = do+  a <- readMAddr maddr+  (a', b) <- f a+  b <$ writeMAddr maddr a'+{-# INLINE modifyMAddrM #-}++-- | Apply a monadic action to the contents of a mutable variable. Returns the old value.+--+-- @since 2.0.0+modifyFetchOldMAddrM :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m a) -> m a+modifyFetchOldMAddrM maddr f = do+  a <- readMAddr maddr+  a <$ (writeMAddr maddr =<< f a)+{-# INLINE modifyFetchOldMAddrM #-}+++-- | Apply a monadic action to the contents of a mutable variable. Returns the new value.+--+-- @since 2.0.0+modifyFetchNewMAddrM :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m a) -> m a+modifyFetchNewMAddrM maddr f = do+  a <- readMAddr maddr+  a' <- f a+  a' <$ writeMAddr maddr a'+{-# INLINE modifyFetchNewMAddrM #-}+++-- | Apply a monadic action to the contents of a mutable variable.+--+-- @since 0.1.0+modifyMAddrM_ :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m a) -> m ()+modifyMAddrM_ maddr f = readMAddr maddr >>= f >>= writeMAddr maddr+{-# INLINE modifyMAddrM_ #-}++-- | Swap contents of two mutable variables. Returns their old values.+--+-- @since 0.1.0+swapMAddrs :: (MonadPrim s m, Prim a) => MAddr a s -> MAddr a s -> m (a, a)+swapMAddrs maddr1 maddr2 = do+  a1 <- readMAddr maddr1+  a2 <- modifyFetchOldMAddr maddr2 (const a1)+  (a1, a2) <$ writeMAddr maddr1 a2+{-# INLINE swapMAddrs #-}++-- | Swap contents of two mutable variables.+--+-- @since 0.1.0+swapMAddrs_ :: (MonadPrim s m, Prim a) => MAddr a s -> MAddr a s -> m ()+swapMAddrs_ maddr1 maddr2 = void $ swapMAddrs maddr1 maddr2+{-# INLINE swapMAddrs_ #-}   
src/Data/Prim/Memory/ByteString.hs view
@@ -40,6 +40,7 @@ import Data.Prim import Foreign.Prim import Control.Prim.Monad+import Control.Prim.Eval import GHC.ForeignPtr import Data.Prim.Memory.Ptr import Data.Prim.Memory.Bytes.Internal@@ -159,5 +160,5 @@ withNoHaltPtrByteString (PS (ForeignPtr addr'# ptrContents) (I# o#) _) f = do   let addr# = addr'# `plusAddr#` o# #endif-  withAliveUnliftPrim ptrContents $ f (Ptr addr#)+  keepAlive ptrContents $ f (Ptr addr#) {-# INLINE withNoHaltPtrByteString #-}
src/Data/Prim/Memory/Bytes.hs view
@@ -16,8 +16,9 @@ -- Portability : non-portable -- module Data.Prim.Memory.Bytes-  ( -- * Mutable-    Bytes+  ( module Data.Prim+    -- * Mutable+  , Bytes   , toByteArray#   , fromByteArray#   , cloneBytes@@ -65,8 +66,9 @@   , allocPinnedMBytes   , allocAlignedMBytes   , allocUnpinnedMBytes-  , callocMBytes-  , callocAlignedMBytes+  , allocZeroMBytes+  , allocZeroPinnedMBytes+  , allocZeroAlignedMBytes   , shrinkMBytes   , resizeMBytes   , reallocMBytes@@ -103,9 +105,13 @@   , toForeignPtrBytes   , toForeignPtrMBytes   -- * Conversion+  , toUArrayBytes+  , fromUArrayBytes+  , toUMArrayMBytes+  , fromUMArrayMBytes   , fromListBytes   , fromListBytesN-  , fromListBytesN_+  , fromListZeroBytesN_   , appendBytes   , concatBytes   , toListBytes@@ -146,7 +152,6 @@   , prefetchMBytes2   , prefetchBytes3   , prefetchMBytes3-  , module Data.Prim   -- * Helpers   ) where @@ -158,31 +163,8 @@ import Data.Prim.Memory.Internal import Foreign.Prim --- | Wrap `ByteArray#` into `Bytes`-toByteArray# :: Bytes p -> ByteArray#-toByteArray# (Bytes b#) = b#---- | Unwrap `Bytes` to get the underlying `ByteArray#`.-fromByteArray# :: ByteArray# -> Bytes 'Inc-fromByteArray# = Bytes---- | Wrap `MutableByteArray#` into `MBytes`-toMutableByteArray# :: MBytes p s -> MutableByteArray# s-toMutableByteArray# (MBytes mb#) = mb#---- | Unwrap `MBytes` to get the underlying `MutableByteArray#`.-fromMutableByteArray# :: MutableByteArray# s -> MBytes 'Inc s-fromMutableByteArray# = MBytes------ | Check if two mutable bytes pointers refer to the same memory-isSameMBytes :: MBytes p1 s -> MBytes p2 s -> Bool-isSameMBytes (MBytes mb1#) (MBytes mb2#) = isTrue# (sameMutableByteArray# mb1# mb2#)-{-# INLINE isSameMBytes #-}- eqBytes :: Bytes p1 -> Bytes p2 -> Bool-eqBytes b1 b2 = isSameBytes b1 b2 || eqMem b1 b2+eqBytes b1 b2 = isSameBytes b1 b2 || eqByteMem b1 b2 {-# INLINE eqBytes #-}  ---- Pure@@ -282,9 +264,9 @@ createBytesST_ n f =  runST $ createBytes_ n f {-# INLINE createBytesST_ #-} -callocMBytes :: (MonadPrim s m, Prim e, Typeable p) => Count e -> m (MBytes p s)-callocMBytes n = allocMBytes n >>= \mb -> mb <$ setMBytes mb 0 (toByteCount n) 0-{-# INLINE callocMBytes #-}+allocZeroMBytes :: (MonadPrim s m, Prim e, Typeable p) => Count e -> m (MBytes p s)+allocZeroMBytes n = allocMBytes n >>= \mb -> mb <$ setMBytes mb 0 (toByteCount n) 0+{-# INLINE allocZeroMBytes #-}   @@ -361,20 +343,22 @@ toListSlackBytes = toListSlackMem {-# INLINE toListSlackBytes #-} --- | Same as `loadListMem`+-- | Same as `loadListMutMem` loadListMBytes :: (Prim e, Typeable p, MonadPrim s m) => [e] -> MBytes p s -> m ([e], Count e)-loadListMBytes = loadListMem+loadListMBytes = loadListMutMem {-# INLINE loadListMBytes #-} --- | Same as `loadListMem_`+-- | Same as `loadListMutMem_` loadListMBytes_ :: (Prim e, Typeable p, MonadPrim s m) => [e] -> MBytes p s -> m ()-loadListMBytes_ = loadListMem_+loadListMBytes_ = loadListMutMem_ {-# INLINE loadListMBytes_ #-}  -- | Same as `fromListZeroMemN_`-fromListBytesN_ :: (Prim e, Typeable p) => Count e -> [e] -> Bytes p-fromListBytesN_ = fromListZeroMemN_-{-# INLINE fromListBytesN_ #-}+--+-- @since 0.3.0+fromListZeroBytesN_ :: (Prim e, Typeable p) => Count e -> [e] -> Bytes p+fromListZeroBytesN_ = fromListZeroMemN_+{-# INLINE fromListZeroBytesN_ #-}  -- | Exactly like `fromListMemN`, but restricted to `Bytes`. fromListBytesN ::@@ -449,7 +433,8 @@   -> e -- ^ Expected old value   -> e -- ^ New value   -> m e-casMBytes (MBytes mba#) (Off (I# i#)) expected new = prim $ casMutableByteArray# mba# i# expected new+casMBytes (MBytes mba#) (Off (I# i#)) expected new =+  prim $ casMutableByteArray# mba# i# expected new {-# INLINE casMBytes #-}  
src/Data/Prim/Memory/Bytes/Internal.hs view
@@ -21,8 +21,13 @@   ( Bytes(..)   , MBytes(..)   , Pinned(..)+  , toByteArray#+  , fromByteArray#+  , toMutableByteArray#+  , fromMutableByteArray#   , isSameBytes   , isSamePinnedBytes+  , isSameMBytes   , isPinnedBytes   , isPinnedMBytes   , castStateMBytes@@ -36,7 +41,8 @@   , allocPinnedMBytes   , allocAlignedMBytes   , allocUnpinnedMBytes-  , callocAlignedMBytes+  , allocZeroPinnedMBytes+  , allocZeroAlignedMBytes   , reallocMBytes   , freezeMBytes   , thawBytes@@ -56,6 +62,10 @@   , readByteOffMBytes   , writeOffMBytes   , writeByteOffMBytes+  , toUArrayBytes+  , fromUArrayBytes+  , toUMArrayMBytes+  , fromUMArrayMBytes   , toPtrBytes   , toPtrMBytes   , withPtrBytes@@ -72,7 +82,9 @@ import Control.DeepSeq import Control.Prim.Monad import Control.Prim.Monad.Unsafe+import Control.Prim.Eval import Data.Prim+import Data.Prim.Array import Data.Prim.Class import Data.Typeable import Foreign.Prim@@ -132,7 +144,33 @@   rnf (MBytes _) = ()  +-- | Unwrap `Bytes` to get the underlying `ByteArray#`.+--+-- @since 0.1.0+toByteArray# :: Bytes p -> ByteArray#+toByteArray# (Bytes b#) = b# +-- | Wrap `ByteArray#` into `Bytes`+--+-- @since 0.1.0+fromByteArray# :: ByteArray# -> Bytes 'Inc+fromByteArray# = Bytes++-- | Unwrap `MBytes` to get the underlying `MutableByteArray#`.+--+-- @since 0.1.0+toMutableByteArray# :: MBytes p s -> MutableByteArray# s+toMutableByteArray# (MBytes mb#) = mb#++-- | Wrap `MutableByteArray#` into `MBytes`+--+-- @since 0.1.0+fromMutableByteArray# :: MutableByteArray# s -> MBytes 'Inc s+fromMutableByteArray# = MBytes++++ ---- Pure  compareByteOffBytes :: Prim e => Bytes p1 -> Off Word8 -> Bytes p2 -> Off Word8 -> Count e -> Ordering@@ -200,14 +238,24 @@       (# s', ba# #) -> (# s', MBytes ba# #) {-# INLINE allocAlignedMBytes #-} -callocAlignedMBytes ::++-- @since 0.3.0+allocZeroPinnedMBytes ::      (MonadPrim s m, Prim e)   => Count e -- ^ Size in number of bytes   -> m (MBytes 'Pin s)-callocAlignedMBytes n = allocAlignedMBytes n >>= \mb -> mb <$ setMBytes mb 0 (toByteCount n) 0-{-# INLINE callocAlignedMBytes #-}+allocZeroPinnedMBytes n = allocPinnedMBytes n >>= \mb -> mb <$ setMBytes mb 0 (toByteCount n) 0+{-# INLINE allocZeroPinnedMBytes #-} +-- @since 0.3.0+allocZeroAlignedMBytes ::+     (MonadPrim s m, Prim e)+  => Count e -- ^ Size in number of bytes+  -> m (MBytes 'Pin s)+allocZeroAlignedMBytes n = allocAlignedMBytes n >>= \mb -> mb <$ setMBytes mb 0 (toByteCount n) 0+{-# INLINE allocZeroAlignedMBytes #-} + getByteCountMBytes :: MonadPrim s m => MBytes p s -> m (Count Word8) getByteCountMBytes (MBytes mba#) =   prim $ \s ->@@ -362,6 +410,36 @@ {-# INLINE setMBytes #-}  +-- | /O(1)/ - Cast an unboxed array into `Bytes`+--+-- @since 0.3.0+fromUArrayBytes :: UArray e -> Bytes 'Inc+fromUArrayBytes (UArray ba#) = fromByteArray# ba#+{-# INLINE fromUArrayBytes #-}++-- | /O(1)/ - Cast `Bytes` into an unboxed array+--+-- @since 0.3.0+toUArrayBytes :: Bytes p -> UArray e+toUArrayBytes b = UArray (toByteArray# b)+{-# INLINE toUArrayBytes #-}++-- | /O(1)/ - Cast a mutable unboxed array into `MBytes`+--+-- @since 0.3.0+fromUMArrayMBytes :: UMArray e s -> MBytes 'Inc s+fromUMArrayMBytes (UMArray a#) = fromMutableByteArray# a#+{-# INLINE fromUMArrayMBytes #-}++-- | /O(1)/ - Cast `MBytes` into a mutable unboxed array+--+-- @since 0.3.0+toUMArrayMBytes :: MBytes p s -> UMArray e s+toUMArrayMBytes mb = UMArray (toMutableByteArray# mb)+{-# INLINE toUMArrayMBytes #-}+++ toPtrBytes :: Bytes 'Pin -> Ptr e toPtrBytes (Bytes ba#) = Ptr (byteArrayContents# ba#) {-# INLINE toPtrBytes #-}@@ -380,7 +458,7 @@  -- | Same as `withPtrBytes`, but is suitable for actions that don't terminate withNoHaltPtrBytes :: MonadUnliftPrim s m => Bytes 'Pin -> (Ptr e -> m b) -> m b-withNoHaltPtrBytes b f = withAliveUnliftPrim b $ f (toPtrBytes b)+withNoHaltPtrBytes b f = keepAlive b $ f (toPtrBytes b) {-# INLINE withNoHaltPtrBytes #-}  withPtrMBytes :: MonadPrim s m => MBytes 'Pin s -> (Ptr e -> m b) -> m b@@ -390,7 +468,7 @@ {-# INLINE withPtrMBytes #-}  withNoHaltPtrMBytes :: MonadUnliftPrim s m => MBytes 'Pin s -> (Ptr e -> m b) -> m b-withNoHaltPtrMBytes mb f = withAliveUnliftPrim mb $ f (toPtrMBytes mb)+withNoHaltPtrMBytes mb f = keepAlive mb $ f (toPtrMBytes mb) {-# INLINE withNoHaltPtrMBytes #-}  toForeignPtrBytes :: Bytes 'Pin -> ForeignPtr e@@ -464,6 +542,13 @@ isSamePinnedBytes pb1 pb2 = toPtrBytes pb1 == toPtrBytes pb2 {-# INLINE isSamePinnedBytes #-} ++-- | Check if two mutable bytes pointers refer to the same memory+--+-- @since 0.1.0+isSameMBytes :: MBytes p1 s -> MBytes p2 s -> Bool+isSameMBytes (MBytes mb1#) (MBytes mb2#) = isTrue# (sameMutableByteArray# mb1# mb2#)+{-# INLINE isSameMBytes #-}   byteStringConvertError :: String -> a
+ src/Data/Prim/Memory/Fold.hs view
@@ -0,0 +1,512 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE ScopedTypeVariables #-}+-- |+-- Module      : Data.Prim.Memory.Fold+-- Copyright   : (c) Alexey Kuleshevich 2020+-- License     : BSD3+-- Maintainer  : Alexey Kuleshevich <alexey@kuleshevi.ch>+-- Stability   : experimental+-- Portability : non-portable+--+module Data.Prim.Memory.Fold where++import Data.Prim+import Data.Prim.Memory.Internal+++foldlMem ::+     forall e a mr. (Prim e, MemRead mr)+  => (a -> e -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+foldlMem f = ifoldlMem (\a _ -> f a)+{-# INLINE foldlMem #-}+++ifoldlMem ::+     forall e a mr. (Prim e, MemRead mr)+  => (a -> Off e -> e -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+ifoldlMem f initAcc mem = ifoldlOffMem 0 (countMem mem :: Count e) f initAcc mem+{-# INLINE ifoldlMem #-}++ifoldlOffMem ::+     forall e a mr. (Prim e, MemRead mr)+  => Off e+  -- ^ Initial offset to start at+  -> Count e+  -- ^ Total number of elements to iterate through+  -> (a -> Off e -> e -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+ifoldlOffMem off count f initAcc mem = loop initAcc off+  where+    k = countToOff count + off+    loop !acc i+      | i >= k = acc+      | otherwise = loop (f acc i (indexOffMem mem i)) (i + 1)+{-# INLINE ifoldlOffMem #-}+++++foldlLazyMem ::+     forall e a mr. (Prim e, MemRead mr)+  => (a -> e -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+foldlLazyMem f = ifoldlLazyMem (\a _ -> f a)+{-# INLINE foldlLazyMem #-}++ifoldlLazyMem ::+     forall e a mr. (Prim e, MemRead mr)+  => (a -> Off e -> e -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+ifoldlLazyMem f initAcc mem = ifoldlLazyOffMem 0 (countMem mem :: Count e) f initAcc mem+{-# INLINE ifoldlLazyMem #-}++ifoldlLazyOffMem ::+     forall e a mr. (Prim e, MemRead mr)+  => Off e+  -- ^ Initial offset to start at+  -> Count e+  -- ^ Total number of elements to iterate through+  -> (a -> Off e -> e -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+ifoldlLazyOffMem off count f initAcc mem = loop initAcc off+  where+    k = countToOff count + off+    loop acc i+      | i >= k = acc+      | otherwise = loop (f acc i (indexOffMem mem i)) (i + 1)+{-# INLINE ifoldlLazyOffMem #-}+++++foldrMem ::+     forall e a mr. (Prim e, MemRead mr)+  => (e -> a -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+foldrMem f = ifoldrMem (const f)+{-# INLINE foldrMem #-}++ifoldrMem ::+     forall e a mr. (Prim e, MemRead mr)+  => (Off e -> e -> a -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+ifoldrMem f initAcc mem = ifoldrOffMem 0 (countMem mem :: Count e) f initAcc mem+{-# INLINE ifoldrMem #-}++ifoldrOffMem ::+     forall e a mr. (Prim e, MemRead mr)+  => Off e+  -- ^ Initial offset to start at+  -> Count e+  -- ^ Total number of elements to iterate through+  -> (Off e -> e -> a -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+ifoldrOffMem off count f initAcc mem = loop initAcc off+  where+    k = countToOff count + off+    loop !acc i+      | i >= k = acc+      | otherwise = f i (indexOffMem mem i) (loop acc (i + 1))+{-# INLINE ifoldrOffMem #-}+++-- | Right fold with a lazy accumulator+--+-- @since 0.3.0+foldrLazyMem ::+     forall e a mr. (Prim e, MemRead mr)+  => (e -> a -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+foldrLazyMem f = ifoldrLazyMem (const f)+{-# INLINE foldrLazyMem #-}++-- | Right fold with a lazy accumulator using an offset aware function+--+-- @since 0.3.0+ifoldrLazyMem ::+     forall e a mr. (Prim e, MemRead mr)+  => (Off e -> e -> a -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+ifoldrLazyMem f initAcc mem =+  ifoldrLazyOffMem 0 (countMem mem :: Count e) f initAcc mem+{-# INLINE ifoldrLazyMem #-}+++ifoldrLazyOffMem ::+     forall e a mr. (Prim e, MemRead mr)+  => Off e+  -- ^ Initial offset to start at+  -> Count e+  -- ^ Total number of elements to iterate through+  -> (Off e -> e -> a -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+ifoldrLazyOffMem off count f initAcc mem = loop initAcc off+  where+    k = countToOff count + off+    loop acc i+      | i >= k = acc+      | otherwise = f i (indexOffMem mem i) (loop acc (i + 1))+{-# INLINE ifoldrLazyOffMem #-}+++++foldMapOffMem ::+     forall e m mr. (Prim e, MemRead mr, Monoid m)+  => Off e+  -> Count e+  -> (e -> m)+  -> mr+  -> m+foldMapOffMem off count f = ifoldrLazyOffMem off count (\_ e acc -> f e `mappend` acc) mempty+{-# INLINE foldMapOffMem #-}++ifoldMapOffMem ::+     forall e m mr. (Prim e, MemRead mr, Monoid m)+  => Off e+  -> Count e+  -> (Off e -> e -> m)+  -> mr+  -> m+ifoldMapOffMem off count f =+  ifoldrLazyOffMem off count (\i e acc -> f i e `mappend` acc) mempty+{-# INLINE ifoldMapOffMem #-}++++anyOffMem ::+     forall e mr. (Prim e, MemRead mr)+  => Off e+  -> Count e+  -> (e -> Bool)+  -> mr+  -> Bool+anyOffMem off count p = getAny #. foldMapOffMem off count (Any #. p)+{-# INLINE anyOffMem #-}++ianyOffMem ::+     forall e mr. (Prim e, MemRead mr)+  => Off e+  -> Count e+  -> (Off e -> e -> Bool)+  -> mr+  -> Bool+ianyOffMem off count p = getAny #. ifoldMapOffMem off count (\i -> Any #. p i)+{-# INLINE ianyOffMem #-}+++anyMem :: forall e mr . (Prim e, MemRead mr) => (e -> Bool) -> mr -> Bool+anyMem p xs = anyOffMem 0 (countMem xs :: Count e) p xs+{-# INLINE anyMem #-}++ianyMem :: forall e mr . (Prim e, MemRead mr) => (Off e -> e -> Bool) -> mr -> Bool+ianyMem p xs = ianyOffMem 0 (countMem xs :: Count e) p xs+{-# INLINE ianyMem #-}++allOffMem ::+     forall e mr. (Prim e, MemRead mr)+  => Off e+  -> Count e+  -> (e -> Bool)+  -> mr+  -> Bool+allOffMem off count p = getAll #. foldMapOffMem off count (All #. p)+{-# INLINE allOffMem #-}++iallOffMem ::+     forall e mr. (Prim e, MemRead mr)+  => Off e+  -> Count e+  -> (Off e -> e -> Bool)+  -> mr+  -> Bool+iallOffMem off count p = getAll #. ifoldMapOffMem off count (\i -> All #. p i)+{-# INLINE iallOffMem #-}+++allMem :: forall e mr . (Prim e, MemRead mr) => (e -> Bool) -> mr -> Bool+allMem p xs = allOffMem 0 (countMem xs :: Count e) p xs+{-# INLINE allMem #-}++iallMem :: forall e mr . (Prim e, MemRead mr) => (Off e -> e -> Bool) -> mr -> Bool+iallMem p xs = iallOffMem 0 (countMem xs :: Count e) p xs+{-# INLINE iallMem #-}++++---------+++++-- Dangerous: ignores the slack+eqMem :: forall e mr . (Prim e, Eq e, MemRead mr) => mr -> mr -> Bool+eqMem m1 m2+  | isSameMem m1 m2 = True+  | otherwise = n == countMem m2 && eqOffMem m1 0 m2 0 n+  where+    n = countMem m1 :: Count e+{-# INLINE eqMem #-}++++-- | Check two regions of memory for equality using the `Eq` instance. It will return+-- `True` whenever both regions hold exactly the same elements and `False` as soon as the+-- first pair of mismatched elements is discovered in the two regions. It is safe for both+-- regions to refer to the same part of memory.+--+-- [Unsafe] When any precondition for either of the offsets @memOff1@, @memOff2@ or the+-- element count @memCount@ is violated the result is either unpredictable output or+-- failure with a segfault.+--+-- @since 0.3.0+eqOffMem ::+     (Prim e, Eq e, MemRead mr1, MemRead mr2)+  => mr1 -- ^ /memRead1/ - First region of memory+  -> Off e+  -- ^ /memOff1/ - Offset for @memRead1@ in number of elements+  --+  -- /__Precondition:__/+  --+  -- > 0 <= memOff1+  -> mr2 -- ^ /memRead2/ - Second region of memory+  -> Off e+  -- ^ /memOff2/ - Offset for @memRead1@ in number of elements+  --+  -- /__Precondition:__/+  --+  -- > 0 <= memOff2+  -> Count e+  -- ^ /memCount/ - Number of elements of type __@e@__ to compare+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- > offToCount memOff1 + memCount < countMem memRead1+  --+  -- > offToCount memOff2 + memCount < countMem memRead2+  -> Bool+eqOffMem m1 off1 m2 off2 count = loop off1+  where+    doff = off2 - off1+    k = countToOff count + off1+    loop !i+      | i < k = indexOffMem m1 i == indexOffMem m2 (i + doff) && loop (i + 1)+      | otherwise = True+{-# INLINE[1] eqOffMem #-}++eqOffMemBinary ::+     forall e mr1 mr2. (Prim e, MemRead mr1, MemRead mr2)+  => mr1+  -> Off e+  -> mr2+  -> Off e+  -> Count e+  -> Bool+eqOffMemBinary m1 off1 m2 off2 count =+  eqByteOffMem m1 (toByteOff off1) m2 (toByteOff off2) (toByteCount count)+{-# INLINE eqOffMemBinary #-}++{-# RULES+"eqOffMem/Char" forall mr1 (off1 :: Off Char) . eqOffMem mr1 off1 = eqOffMemBinary mr1 off1+"eqOffMem/Word" forall mr1 (off1 :: Off Word) . eqOffMem mr1 off1 = eqOffMemBinary mr1 off1+"eqOffMem/Word8" eqOffMem = eqByteOffMem+"eqOffMem/Word16" forall mr1 (off1 :: Off Word16) . eqOffMem mr1 off1 = eqOffMemBinary mr1 off1+"eqOffMem/Word32" forall mr1 (off1 :: Off Word32) . eqOffMem mr1 off1 = eqOffMemBinary mr1 off1+"eqOffMem/Word64" forall mr1 (off1 :: Off Word64) . eqOffMem mr1 off1 = eqOffMemBinary mr1 off1+"eqOffMem/Int" forall mr1 (off1 :: Off Int) . eqOffMem mr1 off1 = eqOffMemBinary mr1 off1+"eqOffMem/Int8" forall mr1 (off1 :: Off Int8) . eqOffMem mr1 off1 = eqOffMemBinary mr1 off1+"eqOffMem/Int16" forall mr1 (off1 :: Off Int16) . eqOffMem mr1 off1 = eqOffMemBinary mr1 off1+"eqOffMem/Int32" forall mr1 (off1 :: Off Int32) . eqOffMem mr1 off1 = eqOffMemBinary mr1 off1+"eqOffMem/Int64" forall mr1 (off1 :: Off Int64) . eqOffMem mr1 off1 = eqOffMemBinary mr1 off1+#-}++eqOffMutMem ::+     forall e ma1 ma2 m s. (Prim e, Eq e, MonadPrim s m, MemWrite ma1, MemWrite ma2)+  => ma1 s+  -> Off e+  -> ma2 s+  -> Off e+  -> Count e+  -> m Bool+eqOffMutMem mm1 off1 mm2 off2 count = loop off1+  where+    doff = off2 - off1+    k = countToOff count + off1+    loop !i+      | i < k = do+        e1 <- readOffMutMem mm1 i+        e2 <- readOffMutMem mm2 (i + doff)+        if e1 == e2+          then loop (i + 1)+          else pure False+      | otherwise = pure True+{-# INLINE eqOffMutMem #-}+++-- | Compare two mutable memory regions for element equality. Regions themselves are not+-- modified, as such it is semantically similar to `eqMem` which works on immutable+-- regions.+eqMutMem ::+     forall e ma m s. (Prim e, Eq e, MonadPrim s m, MemAlloc ma)+  => ma s+  -> ma s+  -> m Bool+eqMutMem mm1 mm2+  | isSameMutMem mm1 mm2 = pure True+  | otherwise = do+    n1 <- getCountMutMem mm1+    n2 <- getCountMutMem mm2+    if n1 /= n2+      then pure False+      else eqOffMutMem mm1 0 mm2 0 (n1 :: Count e)+{-# INLINE eqMutMem #-}++++-- | Compare two regions using the `Ord` instance. It will return `EQ` whenever both+-- regions hold exactly the same elements and `LT` or `GT` as soon as the first discovered+-- element that is less than or greater than respectfully in the first region when+-- compared to the second one. It is safe for both regions to refer to the same part of+-- memory.+--+-- @since 0.3.0+compareMem ::+     forall e mr. (Prim e, Ord e, MemRead mr)+  => mr -- ^ /memRead1/ - First region of memory+  -> mr -- ^ /memRead2/ - Second region of memory+  -> Ordering+compareMem m1 m2+  | isSameMem m1 m2 = EQ+  | otherwise = compareOffMem m1 0 m2 0 (min n1 n2) <> compare n1 n2+  where+    n1 = countMem m1 :: Count e+    n2 = countMem m2 :: Count e+{-# INLINE compareMem #-}++-- | Compare two regions using the `Ord` instance. It will return `EQ` whenever both+-- regions hold exactly the same elements and `LT` or `GT` as soon as the first discovered+-- element that is less than or greater than respectfully in the first region when+-- compared to the second one. It is safe for both regions to refer to the same part of+-- memory.+--+-- [Unsafe] When any precondition for either of the offsets @memOff1@, @memOff2@ or the+-- element count @memCount@ is violated the result is either unpredictable output or+-- failure with a segfault.+--+-- @since 0.3.0+compareOffMem ::+     (Prim e, Ord e, MemRead mr1, MemRead mr2)+  => mr1 -- ^ /memRead1/ - First region of memory+  -> Off e+  -- ^ /memOff1/ - Offset for @memRead1@ in number of elements+  --+  -- /__Precondition:__/+  --+  -- > 0 <= memOff1+  -> mr2 -- ^ /memRead2/ - Second region of memory+  -> Off e+  -- ^ /memOff2/ - Offset for @memRead1@ in number of elements+  --+  -- /__Precondition:__/+  --+  -- > 0 <= memOff2+  -> Count e+  -- ^ /memCount/ - Number of elements of type __@e@__ to compare+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- > offToCount memOff1 + memCount < countMem memRead1+  --+  -- > offToCount memOff2 + memCount < countMem memRead2+  -> Ordering+compareOffMem m1 off1 m2 off2 count = loop off1+  where+    doff = off2 - off1+    k = countToOff count + off1+    kRem = countToOff count `rem` 4+    k4 = k - kRem+    -- Some loop unrolling to get an extra 25% kick for smaller types+    loop !i+      | i < k4 =+        let !i' = i + 1+            !i'' = i + 2+            !i''' = i + 3+         in compare (indexOffMem m1 i) (indexOffMem m2 (i + doff)) <>+            compare (indexOffMem m1 i') (indexOffMem m2 (i' + doff)) <>+            compare (indexOffMem m1 i'') (indexOffMem m2 (i'' + doff)) <>+            compare (indexOffMem m1 i''') (indexOffMem m2 (i''' + doff)) <>+            loop (i + 4)+      | i < k = compare (indexOffMem m1 i) (indexOffMem m2 (i + doff)) <> loop (i + 1)+      | otherwise = EQ+{-# INLINE [1] compareOffMem #-}++{-# RULES+"compareOffMem/Word8" compareOffMem = compareByteOffMem+#-}
src/Data/Prim/Memory/ForeignPtr.hs view
@@ -61,6 +61,7 @@   ) where  import Control.Prim.Monad+import Control.Prim.Eval import Data.Prim import Data.Prim.Class import Data.Prim.Memory.Bytes.Internal (Bytes, MBytes(..), Pinned(..),@@ -96,7 +97,7 @@   withNoHaltPtrAccess p action = toForeignPtr p >>= (`withNoHaltForeignPtr` action)   {-# INLINE withNoHaltPtrAccess #-} -instance PtrAccess s (ForeignPtr a) where+instance PtrAccess RealWorld (ForeignPtr a) where   toForeignPtr = pure . coerce   {-# INLINE toForeignPtr #-} @@ -135,6 +136,7 @@   {-# INLINE withNoHaltPtrAccess #-}  + -- | Apply an action to the raw pointer. It is unsafe to return the actual pointer back from -- the action because memory itself might get garbage collected or cleaned up by -- finalizers.@@ -156,7 +158,7 @@ withNoHaltForeignPtr ::      MonadUnliftPrim s m => ForeignPtr e -> (Ptr e -> m b) -> m b withNoHaltForeignPtr (ForeignPtr addr# ptrContents) f =-  withAliveUnliftPrim ptrContents $ f (Ptr addr#)+  keepAlive ptrContents $ f (Ptr addr#) {-# INLINE withNoHaltForeignPtr #-}  -- | Lifted version of `GHC.touchForeignPtr`.@@ -272,13 +274,13 @@ -- | Unlifted version of `GHC.newConcForeignPtr` newConcForeignPtr :: MonadUnliftPrim RW m => Ptr e -> m () -> m (ForeignPtr e) newConcForeignPtr ptr fin =-  withRunInPrimBase $ \run -> liftPrimBase (GHC.newConcForeignPtr ptr (run fin))+  withRunInIO $ \run -> liftPrimBase (GHC.newConcForeignPtr ptr (run fin))   -- | Unlifted version of `GHC.addForeignPtrConcFinalizer` addForeignPtrConcFinalizer :: MonadUnliftPrim RW m => ForeignPtr a -> m () -> m () addForeignPtrConcFinalizer fp fin =-  withRunInPrimBase $ \run -> liftPrimBase (GHC.addForeignPtrConcFinalizer fp (run fin))+  withRunInIO $ \run -> liftPrimBase (GHC.addForeignPtrConcFinalizer fp (run fin))  -- | Lifted version of `GHC.finalizeForeignPtr`. finalizeForeignPtr :: MonadPrim RW m => ForeignPtr e -> m ()
src/Data/Prim/Memory/Internal.hs view
@@ -23,2335 +23,2794 @@   , module Data.Prim.Memory.Bytes.Internal   ) where -import Control.Exception-import Control.Monad.ST-import Control.Prim.Monad-import Control.Prim.Monad.Unsafe-import qualified Data.ByteString as BS-import Data.Foldable as Foldable-import Data.Kind-import Data.List as List-import Data.List.NonEmpty (NonEmpty(..))-import qualified Data.Monoid as Monoid-import Data.Prim-import Data.Prim.Memory.Bytes.Internal-import Data.Prim.Memory.ByteString-import Data.Prim.Memory.ForeignPtr-import Data.Prim.Memory.Ptr-import qualified Data.Semigroup as Semigroup-import qualified Data.Prim.Memory.Text as T-import Foreign.Prim-import Numeric (showHex)---- | Type class that can be implemented for an immutable data type that provides--- read-only direct access to memory-class MemRead mr where--  -- | Number of bytes allocated by the data type available for reading.-  ---  -- ====__Example__-  ---  -- >>> :set -XDataKinds-  -- >>> import Data.Prim.Memory-  -- >>> byteCountMem (fromByteListMem [1,2,3] :: Bytes 'Inc)-  -- Count {unCount = 3}-  ---  -- @since 0.1.0-  byteCountMem :: mr -> Count Word8--  -- | Read an element with an offset in number of elements, rather than bytes as is the-  -- case with `indexByteOffMem`.-  ---  -- [Unsafe] Bounds are not checked. When precondition for @off@ argument is violated the-  -- result is either unpredictable output or failure with a segfault.-  ---  -- @since 0.1.0-  indexOffMem :: Prim e-    => mr -- ^ /memRead/ - Memory to read an element from-    -> Off e-    -- ^ /off/ - Offset in number of elements from the beginning of @memRead@-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= off-    ---    -- > unOffBytes off <= unCount (byteCountMem memRead - byteCountType @e)-    ---    -> e-  indexOffMem mr off = indexByteOffMem mr (toByteOff off)-  {-# INLINE indexOffMem #-}--  -- | Read an element with an offset in number of bytes. Bounds are not checked.-  ---  -- [Unsafe] When precondition for @off@ argument is violated the result is either-  -- unpredictable output or failure with a segfault.-  ---  -- @since 0.1.0-  indexByteOffMem :: Prim e-    => mr -- ^ /memRead/ - Memory to read an element from-    -> Off Word8-    -- ^ /off/ - Offset in number of elements from the beginning of @memRead@-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= unOff off-    ---    -- > unOff off <= unCount (byteCountMem memRead - byteCountType @e)-    ---    -> e--  -- | Copy contiguous chunk of memory from the read only memory into the target mutable-  -- `MBytes`. Source and target /must not/ refer to the same memory region, otherwise-  -- that would imply that the source is not immutable which would be a violation of some-  -- other invariant elsewhere in the code.-  ---  -- [Unsafe] When a precondition for either of the offsets @memSourceOff@, @memTargetOff@-  -- or the element count @memCount@ is violated the result is either unpredictable output or-  -- failure with a segfault.-  ---  -- @since 0.1.0-  copyByteOffToMBytesMem ::-       (MonadPrim s m, Prim e)-    => mr -- ^ /memSourceRead/ - Source from where to copy-    -> Off Word8-    -- ^ /memSourceOff/ - Offset into source memory in number of bytes-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memSourceOff-    ---    -- > unOff memSourceOff <= unCount (byteCountMem memSourceRead - byteCountType @e)-    -> MBytes p s -- ^ /memTargetWrite/ - Target mutable memory-    -> Off Word8-    -- ^ /memTargetOff/ -  Offset into target memory in number of bytes-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memTargetOff-    ---    -- > unOff memTargetOff <= unCount (byteCountMem memTargetWrite - byteCountType @e)-    -> Count e-    -- ^ /memCount/ - Number of elements of type @e@ to copy-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- > unCountBytes memCount + unOff memSourceOff <= unCount (byteCountMem memSourceRead - byteCountType @e)-    ---    -- > unCountBytes memCount + unOff memTargetOff <= unCount (byteCountMem memTargetRead - byteCountType @e)-    -> m ()--  -- | Copy contiguous chunk of memory from the read only memory into the target mutable-  -- `Ptr`. Source and target /must not/ refer to the same memory region, otherwise that-  -- would imply that the source is not immutable which would be a violation of some other-  -- invariant elsewhere in the code.-  ---  -- [Unsafe] When any precondition for one of the offsets @memSourceOff@, @memTargetOff@-  -- or the element count @memCount@ is violated a call to this function can result in:-  -- copy of data that doesn't belong to @memSourceRead@, heap corruption or failure with-  -- a segfault.-  ---  ---  -- @since 0.1.0-  copyByteOffToPtrMem ::-       (MonadPrim s m, Prim e)-    => mr -- ^ /memSourceRead/ - Source from where to copy-    -> Off Word8-    -- ^ /memSourceOff/ - Offset into source memory in number of bytes-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memSourceOff-    ---    -- > unOff memSourceOff <= unCount (byteCountMem memSourceRead - byteCountType @e)-    -> Ptr e-    -- ^ /memTargetWrite/ - Pointer to the target mutable memory-    ---    -- /__Preconditions:__/-    ---    -- Once the pointer is advanced by @memTargetOff@ the next @unCountBytes memCount@ bytes must-    -- still belong to the same region of memory @memTargetWrite@-    -> Off Word8-    -- ^ /memTargetOff/ - Number of bytes to advance the pointer @memTargetWrite@ forward-    ---    -- /__Precondition:__/-    ---    -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same-    -- memory region @memTargetWrite@-    -> Count e-    -- ^ /memCount/ - Number of elements of type @e@ to copy-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- > unCountBytes memCount + unOff memSourceOff <= unCount (byteCountMem memSourceRead - byteCountType @e)-    -> m ()--  -- | Same as `compareByteOffMem`, but compare the read-only-  -- memory region to a region addressed by a `Ptr` inside of a `MonadPrim`.-  ---  -- [Unsafe] When any precondition for either of the offsets @memOff1@, @memOff2@, the-  -- pointer @memRead2@ or the element count @memCount@ is violated the result is either-  -- unpredictable output or failure with a segfault.-  ---  -- @since 0.1.0-  compareByteOffToPtrMem ::-       (MonadPrim s m, Prim e)-    => mr -- ^ /memRead1/ - First memory region-    -> Off Word8-    -- ^ /memOff1/ - Offset for @memRead1@ in number of bytes-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memOff1-    ---    -- > unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)-    -> Ptr e-    -- ^ /memRead2/- Second memory region that can be accessed by a pointer-    ---    -- /__Preconditions__/-    ---    -- Once the pointer is advanced by @memOff2@ the next @unCountBytes memCount@ bytes must-    -- still belong to the same region of memory @memRead2@-    -> Off Word8-    -- ^ /memOff2/ - Number of bytes to advance the pointer @memRead2@ forward-    ---    -- /__Precondition:__/-    ---    -- Once the pointer is advanced by @memOff2@ it must still refer to the same memory-    -- region @memRead2@-    -> Count e -- ^ /memCount/ - Number of elements of type @e@ to compare as binary-    -- ^ /memCount/ - Number of elements of type @e@ to compare as binary-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- > unCountBytes memCount + unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)-    -> m Ordering--  -- | Same as `compareByteOffMem`, but compare the read-only memory region to `Bytes`.-  ---  -- [Unsafe] When any precondition for either of the offsets @memOff1@, @memOff2@ or the-  -- element count @memCount@ is violated the result is either unpredictable output or-  -- failure with a segfault.-  ---  -- @since 0.1.0-  compareByteOffToBytesMem ::-       Prim e-    => mr -- ^ /memRead1/ - First memory region-    -> Off Word8-    -- ^ /memOff1/ - Offset for @memRead1@ in number of bytes-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memOff1-    ---    -- > unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)-    -> Bytes p -- ^ /memRead2/- Second memory region that is backed by `Bytes`-    -> Off Word8-    -- ^ /memOff2/ - Offset for @memRead2@ in number of bytes-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memOff2-    ---    -- > unOff memOff2 <= unCount (byteCountMem memRead2 - byteCountType @e)-    -> Count e-    -- ^ /memCount/ - Number of elements of type @e@ to compare as binary-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- > unCountBytes memCount + unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)-    ---    -- > unCountBytes memCount + unOff memOff2 <= unCount (byteCountMem memRead2 - byteCountType @e)-    -> Ordering--  -- | Compare two read-only regions of memory byte-by-byte. The very first mismatched-  -- byte will cause this function to produce `LT` if the byte in @memRead1@ is smaller-  -- than the one in @memRead2@ and `GT` if it is bigger. It is not a requirement to-  -- short-circuit on the first mismatch, but it is a good optimization to have for-  -- non-sensitive data. Memory regions that store security critical data may choose to-  -- implement this function to work in constant time.-  ---  -- This function is usually implemented by either one of `compareByteOffToPtrMem` or-  -- `compareByteOffToBytesMem`, depending on the nature of @mr@ type. However it differs-  -- from the aforementioned functions with a fact that it is pure non-monadic-  -- computation.-  ---  -- [Unsafe] When any precondition for either of the offsets @memOff1@, @memOff2@ or the-  -- element count @memCount@ is violated the result is either unpredictable output or-  -- failure with a segfault.-  ---  -- @since 0.1.0-  compareByteOffMem ::-       (MemRead mr', Prim e)-    => mr' -- ^ /memRead1/ - First memory region-    -> Off Word8-    -- ^ /memOff1/ - Offset for @memRead1@ in number of bytes-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memOff1-    ---    -- > unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)-    -> mr -- ^ /memRead2/ - Second memory region-    -> Off Word8-    -- ^ /memOff2/ - Offset for @memRead2@ in number of bytes-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memOff2-    ---    -- > unOff memOff2 <= unCount (byteCountMem memRead2 - byteCountType @e)-    -> Count e-    -- ^ /memCount/ - Number of elements of type @e@ to compare as binary-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- > unCountBytes memCount + unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)-    ---    -- > unCountBytes memCount + unOff memOff2 <= unCount (byteCountMem memRead2 - byteCountType @e)-    -> Ordering---- | Type class that can be implemented for a mutable data type that provides direct read--- and write access to memory-class MemWrite mw where-  -- | Read an element with an offset in number of elements, rather than bytes as it is-  -- the case with `readByteOffMem`.-  ---  -- [Unsafe] Bounds are not checked. When precondition for @off@ argument is violated the-  -- result is either unpredictable output or failure with a segfault.-  ---  -- @since 0.1.0-  readOffMem :: (MonadPrim s m, Prim e)-    => mw s -- ^ /memRead/ - Memory region to read an element from-    -> Off e-    -- ^ /off/ - Offset in number of elements from the beginning of @memRead@-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= off-    ---    -- With offset applied it should still refer to the same memory region. For types that-    -- also implement `MemAlloc` this can be described as:-    ---    -- > count <- getByteCountMem memRead-    -- > unOff (toByteOff off) <= unCount (count - byteCountType @e)-    ---    -> m e-  readOffMem mw off = readByteOffMem mw (toByteOff off)-  {-# INLINE readOffMem #-}--  -- | Read an element with an offset in number of bytes.-  ---  -- [Unsafe] Bounds are not checked. When precondition for @off@ argument is violated the-  -- result is either unpredictable output or failure with a segfault.-  ---  -- @since 0.1.0-  readByteOffMem :: (MonadPrim s m, Prim e)-    => mw s -- ^ /memRead/ - Memory region to read an element from-    -> Off Word8-    -- ^ /off/ - Offset in number of elements from the beginning of @memRead@-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= off-    ---    -- With offset applied it should still refer to the same memory region. For types that-    -- also implement `MemAlloc` this can be described as:-    ---    -- > count <- getByteCountMem memRead-    -- > unOff (toByteOff off) <= unCount (count - byteCountType @e)-    ---    -> m e--  -- | Write an element with an offset in number of elements, rather than bytes as it is-  -- the case with `writeByteOffMem`.-  ---  -- [Unsafe] Bounds are not checked. When precondition for @off@ argument is violated the-  -- outcome is either heap corruption or failure with a segfault.-  ---  -- @since 0.1.0-  writeOffMem :: (MonadPrim s m, Prim e)-    => mw s -- ^ /memWrite/ - Memory region to write an element into-    -> Off e-    -- ^ /off/ - Offset in number of elements from the beginning of @memWrite@-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= off-    ---    -- With offset applied it should still refer to the same memory region. For types that-    -- also implement `MemAlloc` this can be described as:-    ---    -- > count <- getByteCountMem memWrite-    -- > unOff (toByteOff off) <= unCount (count - byteCountType @e)-    ---    -> e -- ^ /elt/ - Element to write-    -> m ()-  writeOffMem mw off = writeByteOffMem mw (toByteOff off)-  {-# INLINE writeOffMem #-}--  -- | Write an element with an offset in number of bytes.-  ---  -- [Unsafe] Bounds are not checked. When precondition for @off@ argument is violated the-  -- outcome is either heap corruption or failure with a segfault.-  ---  -- @since 0.1.0-  writeByteOffMem :: (MonadPrim s m, Prim e)-    => mw s -- ^ /memWrite/ - Memory region to write an element into-    -> Off Word8-    -- ^ /off/ - Offset in number of elements from the beginning of @memWrite@-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= off-    ---    -- With offset applied it should still refer to the same memory region. For types that-    -- also implement `MemAlloc` this can be described as:-    ---    -- > count <- getByteCountMem memWrite-    -- > unOff (toByteOff off) <= unCount (count - byteCountType @e)-    ---    -> e -> m ()--  -- | Copy contiguous chunk of memory from the source mutable memory into the target-  -- mutable `MBytes`. Source and target /may/ refer to overlapping memory regions.-  ---  -- [Unsafe] When any precondition for one of the offsets @memSourceOff@, @memTargetOff@-  -- or the element count @memCount@ is violated a call to this function can result in:-  -- copy of data that doesn't belong to @memSource@, heap corruption or failure with-  -- a segfault.-  ---  -- @since 0.1.0-  moveByteOffToMBytesMem ::-    (MonadPrim s m, Prim e)-    => mw s -- ^ /memSource/ - Source memory from where to copy-    -> Off Word8-    -- ^ /memSourceOff/ - Offset in number of bytes into source memory-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memSourceOff-    ---    -- With offset applied it should still refer to the same memory region. For types that-    -- also implement `MemAlloc` this can be described as:-    ---    -- > sourceByteCount <- getByteCountMem memSource-    -- > unOff (toByteOff memSourceOff) <= unCount (sourceByteCount - byteCountType @e)-    -> MBytes p s -- ^ /memTarget/ - Target memory into where to copy-    -> Off Word8-    -- ^ /memTargetOff/ - Offset in number of bytes into target memory where writing will start-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memTargetOff-    ---    -- With offset applied it should still refer to the same memory region. For types that-    -- also implement `MemAlloc` this can be described as:-    ---    -- > targetByteCount <- getByteCountMem memTarget-    -- > unOffBytes memTargetOff <= unCount (targetByteCount - byteCountType @e)-    -> Count e-    -- ^ /memCount/ - Number of elements of type @e@ to copy-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- Both source and target memory regions must have enough memory to perform a copy-    -- of @memCount@ elements starting at their respective offsets. For types that also-    -- implement `MemAlloc` this can be described as:-    ---    -- > sourceByteCount <- getByteCountMem memSource-    -- > unOff memSourceOff + unCountBytes memCount <= unCount (sourceByteCount - byteCountType @e)-    ---    -- > targetByteCount <- getByteCountMem memTarget-    -- > unOff memTargetOff + unCountBytes memCount <= unCount (targetByteCount - byteCountType @e)-    -> m ()--  -- | Copy contiguous chunk of memory from the source mutable memory into the target-  -- `Ptr`. Source and target /may/ refer to overlapping memory regions.-  ---  -- [Unsafe] When any precondition for one of the offsets @memSourceOff@ or-  -- @memTargetOff@, a target pointer @memTarget@ or the element count @memCount@ is-  -- violated a call to this function can result in: copy of data that doesn't belong to-  -- @memSource@, heap corruption or failure with a segfault.-  ---  -- @since 0.1.0-  moveByteOffToPtrMem ::-    (MonadPrim s m, Prim e)-    => mw s -- ^ /memSource/ - Source memory from where to copy-    -> Off Word8-    -- ^ /memSourceOff/ - Offset in number of bytes into source memory-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memSourceOff-    ---    -- With offset applied it should still refer to the same memory region. For types that-    -- also implement `MemAlloc` this can be described as:-    ---    -- > sourceByteCount <- getByteCountMem memSource-    -- > unOff (toByteOff memSourceOff) <= unCount (sourceByteCount - byteCountType @e)-    -> Ptr e-    -- ^ /memTarget/ - Target memory into where to copy-    ---    -- /__Precondition:__/-    ---    -- Once the pointer is advanced by @memTargetOff@ the next @unCountBytes memCount@ bytes must-    -- still belong to the same region of memory @memTargetWrite@-    -> Off Word8-    -- ^ /memTargetOff/ - Offset in number of bytes into target memory where writing will start-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memTargetOff-    ---    -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same-    -- memory region @memTarget@-    -> Count e-    -- ^ /memCount/ - Number of elements of type @e@ to copy-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- Both source and target memory regions must have enough memory to perform a copy-    -- of @memCount@ elements starting at their respective offsets. For /memSource/ that also-    -- implements `MemAlloc` this can be described as:-    ---    -- > sourceByteCount <- getByteCountMem memSource-    -- > unOff memSourceOff + unCountBytes memCount <= unCount (sourceByteCount - byteCountType @e)-    -> m ()--  -- | Copy contiguous chunk of memory from the read only memory region into the target-  -- mutable memory region. Source and target /must not/ refer to the same memory region,-  -- otherwise that would imply that the source is not immutable which would be a-  -- violation of some other invariant elsewhere in the code.-  ---  -- [Unsafe] When any precondition for one of the offsets @memSourceOff@, @memTargetOff@-  -- or the element count @memCount@ is violated a call to this function can result in:-  -- copy of data that doesn't belong to @memSourceRead@, heap corruption or failure with-  -- a segfault.-  ---  -- @since 0.1.0-  copyByteOffMem :: (MonadPrim s m, MemRead mr, Prim e)-    => mr -- ^ /memSourceRead/ - Read-only source memory region from where to copy-    -> Off Word8-    -- ^ /memSourceOff/ - Offset into source memory in number of bytes-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memSourceOff-    ---    -- > unOff memSourceOff <= unCount (byteCountMem memSourceRead - byteCountType @e)-    -> mw s -- ^ /memTargetWrite/ - Target mutable memory-    -> Off Word8-    -- ^ /memTargetOff/ -  Offset into target memory in number of bytes-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memTargetOff-    ---    -- With offset applied it should still refer to the same memory region. For types that-    -- also implement `MemAlloc` this can be described as:-    ---    -- > targetByteCount <- getByteCountMem memTargetWrite-    -- > unOffBytes memTargetOff <= unCount (targetByteCount - byteCountType @e)-    -> Count e-    -- ^ /memCount/ - Number of elements of type @e@ to copy-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- Both source and target memory regions must have enough memory to perform a copy-    -- of @memCount@ elements starting at their respective offsets. For @memSourceRead@:-    ---    -- > unOff memSourceOff + unCountBytes memCount <= unCount (byteCountMem memSourceRead - byteCountType @e)-    ---    -- and for @memTargetWrite@ that also implements `MemAlloc` this can be described as:-    ---    -- > targetByteCount <- getByteCountMem memTargetWrite-    -- > unOff memTargetOff + unCountBytes memCount <= unCount (targetByteCount - byteCountType @e)-    -> m ()--  -- | Copy contiguous chunk of memory from a mutable memory region into the target-  -- mutable memory region. Source and target /may/ refer to the same memory region.-  ---  -- [Unsafe] When any precondition for one of the offsets @memSourceOff@, @memTargetOff@-  -- or the element count @memCount@ is violated a call to this function can result in:-  -- copy of data that doesn't belong to @memSourceRead@, heap corruption or failure with-  -- a segfault.-  ---  -- @since 0.1.0-  moveByteOffMem :: (MonadPrim s m, MemWrite mw', Prim e)-    => mw' s -- ^ /memSource/ - Source memory from where to copy-    -> Off Word8-    -- ^ /memSourceOff/ - Offset in number of bytes into source memory-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memSourceOff-    ---    -- With offset applied it should still refer to the same memory region. For types that-    -- also implement `MemAlloc` this can be described as:-    ---    -- > sourceByteCount <- getByteCountMem memSource-    -- > unOffBytes memSourceOff <= unCount (sourceByteCount - byteCountType @e)-    -> mw s -- ^ /memTarget/ - Target memory into where to copy-    -> Off Word8-    -- ^ /memTargetOff/ -  Offset into target memory in number of bytes-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memTargetOff-    ---    -- With offset applied it should still refer to the same memory region. For types that-    -- also implement `MemAlloc` this can be described as:-    ---    -- > targetByteCount <- getByteCountMem memTarget-    -- > unOffBytes (toByteOff memTargetOff) <= unCount (targetByteCount - byteCountType @e)-    -> Count e-    -- ^ /memCount/ - Number of elements of type @e@ to copy-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- Both source and target memory regions must have enough memory to perform a copy-    -- of @memCount@ elements starting at their respective offsets. For types that also-    -- implement `MemAlloc` this can be described as:-    ---    -- > sourceByteCount <- getByteCountMem memSource-    -- > unOff memSourceOff + unCountBytes memCount <= unCount (sourceByteCount - byteCountType @e)-    ---    -- > targetByteCount <- getByteCountMem memTarget-    -- > unOff memTargetOff + unCountBytes memCount <= unCount (targetByteCount - byteCountType @e)-    -> m ()--  -- TODO: Potential feature for the future implementation. Will require extra function in `Prim`.-  --setByteOffMem :: (MonadPrim s m, Prim e) => w s -> Off Word8 -> Count e -> e -> m ()--  -- | Write the same value @memCount@ times into each cell of @memTarget@ starting at an-  -- offset @memTargetOff@.-  ---  -- [Unsafe] Bounds are not checked. When precondition for @memTargetOff@ argument is-  -- violated the outcome is either heap corruption or failure with a segfault.-  ---  -- @since 0.1.0-  setMem-    :: (MonadPrim s m, Prim e)-    => mw s -- ^ /memTarget/ - Target memory into where to write the element-    -> Off e-    -- ^ /memTargetOff/ - Offset into target memory in number of elements at which element-    -- setting should start.-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memTargetOff-    ---    -- With offset applied it should still refer to the same memory region. For types that-    -- also implement `MemAlloc` this can be described as:-    ---    -- > targetByteCount <- getByteCountMem memTarget-    -- > unOffBytes memTargetOff <= unCount (targetByteCount - byteCountType @e)-    -> Count e-    -- ^ /memCount/ - Number of times the element @elt@ should be written-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- Target memory region should have enough memory to perform a set operation of the-    -- supplied element @memCount@ number of times starting at the supplied offset. For-    -- types that also implement `MemAlloc` this can be described as:-    ---    -- > targetByteCount <- getByteCountMem memTarget-    -- > unCountBytes memCount + unOff memTargetOff <= unCount (targetByteCount - byteCountType @e)-    -> e-    -- ^ /elt/ - Element to write into memory cells. This function is strict with-    -- respect to element, which means that the even @memCount = 0@ it might be still-    -- fully evaluated.-    -> m ()---- | Generalized memory allocation and pure/mutable state conversion.-class (MemRead (FrozenMem ma), MemWrite ma) => MemAlloc ma where-  -- | Memory region in the immutable state. Types for frozen and thawed states of-  -- memory region are in one-to-one correspondence, therefore @ma <-> FrozeMem ma@ will-  -- always uniquely identify each other, which is an extremely useful property when it-  -- comes to type inference.-  type FrozenMem ma = (fm :: Type) | fm -> ma--  -- | Extract from the mutable memory region information about how many bytes it can hold.-  ---  -- @since 0.1.0-  getByteCountMem :: MonadPrim s m => ma s -> m (Count Word8)--  -- | Allocate a mutable memory region for specified number of elements. Memory is not-  -- reset and will likely hold some garbage data, therefore prefer to use `allocZeroMem`,-  -- unless it is guaranteed that all of allocated memory will be overwritten.-  ---  -- [Unsafe] When precondition for @memCount@ argument is violated the outcome is-  -- upredictable. One possible outcome is termination with-  -- `Control.Exception.HeapOverflow` async exception. In a pure setting, such as when-  -- executed within `runST`, if memory is not fully overwritten it can result in-  -- violation of referential transparency, because content of newly allocated-  -- region is non-determinstic.-  ---  -- @since 0.1.0-  allocMem :: (Prim e, MonadPrim s m)-    => Count e-    -- ^ /memCount/ - Number of elements to allocate.-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- Possibility of overflow:-    ---    -- > unCount memCount <= fromByteCount @e (Count maxBound)-    ---    -- When converted to bytes the value should be less then available physical memory-    -> m (ma s)--  -- | Convert the state of an immutable memory region to the mutable one. This is a no-  -- copy operation, as such it is fast, but dangerous. See `thawCopyMem` for a safe alternative.-  ---  -- [Unsafe] It makes it possible to break referential transparency, because any-  -- subsequent destructive operation to the mutable region of memory will also be-  -- reflected in the frozen immutable type as well.-  ---  -- @since 0.1.0-  thawMem :: MonadPrim s m => FrozenMem ma -> m (ma s)--  -- | Convert the state of a mutable memory region to the immutable one. This is a no-  -- copy operation, as such it is fast, but dangerous. See `freezeCopyMem` for a safe alternative.-  ---  -- [Unsafe] It makes it possible to break referential transparency, because any-  -- subsequent destructive operation to the mutable region of memory will also be-  -- reflected in the frozen immutable type as well.-  ---  -- @since 0.1.0-  freezeMem :: MonadPrim s m => ma s -> m (FrozenMem ma)--  -- | Either grow or shrink currently allocated mutable region of memory. For some-  -- implementations it might be possible to change the size of the allocated region-  -- in-place, i.e. without copy. However in all implementations there is a good chance-  -- that the memory region has to be allocated anew, in which case all of the contents-  -- up to the minimum of new and old sizes will get copied over. After the resize-  -- operation is complete the supplied @memSource@ region must not be used-  -- anymore. Moreover, no reference to the old one should be kept in order to allow-  -- garbage collection of the original in case a new one had to be allocated.-  ---  -- [Unsafe] Undefined behavior when @memSource@ is used afterwards. The same unsafety-  -- notice from `allocMem` with regards to @memCount@ is applcable here as well.-  ---  -- @since 0.1.0-  resizeMem :: (MonadPrim s m, Prim e)-    => ma s-    -- ^ /memSource/ - Source memory region to resize-    -> Count e-    -- ^ /memCount/ - Number of elements for the reallocated memory region-    ---    -- /__Preconditions:__/-    ---    -- > 0 <= memCount-    ---    -- Should be less then available physical memory-    -> m (ma s)-  resizeMem = defaultResizeMem-  {-# INLINE resizeMem #-}---instance MemRead ByteString where-  byteCountMem = Count . BS.length-  {-# INLINE byteCountMem #-}-  indexOffMem bs i = unsafeInlineIO $ withPtrAccess bs (`readOffPtr` i)-  {-# INLINE indexOffMem #-}-  indexByteOffMem bs i = unsafeInlineIO $ withPtrAccess bs (`readByteOffPtr` i)-  {-# INLINE indexByteOffMem #-}-  copyByteOffToMBytesMem bs srcOff mb dstOff c =-    withPtrAccess bs $ \srcPtr -> copyByteOffPtrToMBytes srcPtr srcOff mb dstOff c-  {-# INLINE copyByteOffToMBytesMem #-}-  copyByteOffToPtrMem bs srcOff dstPtr dstOff c =-    withPtrAccess bs $ \srcPtr -> copyByteOffPtrToPtr srcPtr srcOff dstPtr dstOff c-  {-# INLINE copyByteOffToPtrMem #-}-  compareByteOffToPtrMem bs off1 ptr2 off2 c =-    withPtrAccess bs $ \ptr1 -> pure $! compareByteOffPtrToPtr ptr1 off1 ptr2 off2 c-  {-# INLINE compareByteOffToPtrMem #-}-  compareByteOffToBytesMem bs off1 bytes off2 c =-    unsafeInlineIO $ withPtrAccess bs $ \ptr1 ->-      pure $! compareByteOffPtrToBytes ptr1 off1 bytes off2 c-  {-# INLINE compareByteOffToBytesMem #-}-  compareByteOffMem mem1 off1 bs off2 c =-    unsafeInlineIO $ withPtrAccess bs $ \ptr2 -> compareByteOffToPtrMem mem1 off1 ptr2 off2 c-  {-# INLINE compareByteOffMem #-}---instance MemAlloc MByteString where-  type FrozenMem MByteString = ByteString-  getByteCountMem (MByteString bs) = pure $! Count (BS.length bs)-  {-# INLINE getByteCountMem #-}-  allocMem c = do-    let cb = toByteCount c-    fp <- mallocByteCountPlainForeignPtr cb-    pure $ MByteString (PS fp 0 (coerce cb))-  {-# INLINE allocMem #-}-  thawMem bs = pure $ MByteString bs-  {-# INLINE thawMem #-}-  freezeMem (MByteString bs) = pure bs-  {-# INLINE freezeMem #-}-  resizeMem bsm@(MByteString (PS fp o n)) newc-    | newn > n = defaultResizeMem bsm newc-    | otherwise = pure $ MByteString (PS fp o newn)-    where -- constant time slice if we need to reduce the size-      Count newn = toByteCount newc-  {-# INLINE resizeMem #-}--instance MemWrite MByteString where-  readOffMem (MByteString mbs) i = withPtrAccess mbs (`readOffPtr` i)-  {-# INLINE readOffMem #-}-  readByteOffMem (MByteString mbs) i = withPtrAccess mbs (`readByteOffPtr` i)-  {-# INLINE readByteOffMem #-}-  writeOffMem (MByteString mbs) i a = withPtrAccess mbs $ \ptr -> writeOffPtr ptr i a-  {-# INLINE writeOffMem #-}-  writeByteOffMem (MByteString mbs) i a = withPtrAccess mbs $ \ptr -> writeByteOffPtr ptr i a-  {-# INLINE writeByteOffMem #-}-  moveByteOffToPtrMem (MByteString fsrc) srcOff dstPtr dstOff c =-    withPtrAccess fsrc $ \srcPtr -> moveByteOffPtrToPtr srcPtr srcOff dstPtr dstOff c-  {-# INLINE moveByteOffToPtrMem #-}-  moveByteOffToMBytesMem (MByteString fsrc) srcOff dst dstOff c =-    withPtrAccess fsrc $ \srcPtr -> moveByteOffPtrToMBytes srcPtr srcOff dst dstOff c-  {-# INLINE moveByteOffToMBytesMem #-}-  copyByteOffMem src srcOff (MByteString fdst) dstOff c =-    withPtrAccess fdst $ \dstPtr -> copyByteOffToPtrMem src srcOff dstPtr dstOff c-  {-# INLINE copyByteOffMem #-}-  moveByteOffMem src srcOff (MByteString fdst) dstOff c =-    withPtrAccess fdst $ \dstPtr -> moveByteOffToPtrMem src srcOff dstPtr dstOff c-  {-# INLINE moveByteOffMem #-}-  setMem (MByteString mbs) off c a = withPtrAccess mbs $ \ptr -> setOffPtr ptr off c a-  {-# INLINE setMem #-}--instance MemRead T.Array where-  byteCountMem = byteCountMem . T.toBytesArray-  {-# INLINE byteCountMem #-}-  indexOffMem a = indexOffMem (T.toBytesArray a)-  {-# INLINE indexOffMem #-}-  indexByteOffMem a = indexByteOffMem (T.toBytesArray a)-  {-# INLINE indexByteOffMem #-}-  copyByteOffToMBytesMem a = copyByteOffToMBytesMem (T.toBytesArray a)-  {-# INLINE copyByteOffToMBytesMem #-}-  copyByteOffToPtrMem a = copyByteOffToPtrMem (T.toBytesArray a)-  {-# INLINE copyByteOffToPtrMem #-}-  compareByteOffToPtrMem a = compareByteOffToPtrMem (T.toBytesArray a)-  {-# INLINE compareByteOffToPtrMem #-}-  compareByteOffToBytesMem a = compareByteOffToBytesMem (T.toBytesArray a)-  {-# INLINE compareByteOffToBytesMem #-}-  compareByteOffMem mem off1 a = compareByteOffMem mem off1 (T.toBytesArray a)-  {-# INLINE compareByteOffMem #-}--instance MemAlloc T.MArray where-  type FrozenMem T.MArray = T.Array-  getByteCountMem = getByteCountMBytes . T.toMBytesMArray-  {-# INLINE getByteCountMem #-}-  allocMem = fmap T.fromMBytesMArray . allocUnpinnedMBytes-  {-# INLINE allocMem #-}-  thawMem = fmap T.fromMBytesMArray . thawBytes . T.toBytesArray-  {-# INLINE thawMem #-}-  freezeMem = fmap T.fromBytesArray . freezeMBytes . T.toMBytesMArray-  {-# INLINE freezeMem #-}-  resizeMem m = fmap T.fromMBytesMArray . reallocMBytes (T.toMBytesMArray m)-  {-# INLINE resizeMem #-}--instance MemWrite T.MArray where-  readOffMem m = readOffMBytes (T.toMBytesMArray m)-  {-# INLINE readOffMem #-}-  readByteOffMem m = readByteOffMBytes (T.toMBytesMArray m)-  {-# INLINE readByteOffMem #-}-  writeOffMem m = writeOffMBytes (T.toMBytesMArray m)-  {-# INLINE writeOffMem #-}-  writeByteOffMem m = writeByteOffMBytes (T.toMBytesMArray m)-  {-# INLINE writeByteOffMem #-}-  moveByteOffToPtrMem m = moveByteOffMBytesToPtr (T.toMBytesMArray m)-  {-# INLINE moveByteOffToPtrMem #-}-  moveByteOffToMBytesMem m = moveByteOffMBytesToMBytes (T.toMBytesMArray m)-  {-# INLINE moveByteOffToMBytesMem #-}-  moveByteOffMem src srcOff m = moveByteOffToMBytesMem src srcOff (T.toMBytesMArray m)-  {-# INLINE moveByteOffMem #-}-  copyByteOffMem src srcOff m = copyByteOffToMBytesMem src srcOff (T.toMBytesMArray m)-  {-# INLINE copyByteOffMem #-}-  setMem m = setMBytes (T.toMBytesMArray m)-  {-# INLINE setMem #-}--instance MemRead T.Text where-  byteCountMem (T.Text _ _ n) = toByteCount (Count n :: Count Word16)-  {-# INLINE byteCountMem #-}-  indexByteOffMem (T.Text a o _) i = indexByteOffMem a (toByteOff (Off o :: Off Word16) + i)-  {-# INLINE indexByteOffMem #-}-  copyByteOffToMBytesMem (T.Text a o _) i =-    copyByteOffToMBytesMem a (toByteOff (Off o :: Off Word16) + i)-  {-# INLINE copyByteOffToMBytesMem #-}-  copyByteOffToPtrMem (T.Text a o _) i =-    copyByteOffToPtrMem a (toByteOff (Off o :: Off Word16) + i)-  {-# INLINE copyByteOffToPtrMem #-}-  compareByteOffToPtrMem (T.Text a o _) off =-    compareByteOffToPtrMem a (toByteOff (Off o :: Off Word16) + off)-  {-# INLINE compareByteOffToPtrMem #-}-  compareByteOffToBytesMem (T.Text a o _) off =-    compareByteOffToBytesMem a (toByteOff (Off o :: Off Word16) + off)-  {-# INLINE compareByteOffToBytesMem #-}-  compareByteOffMem mem off1 (T.Text a o _) off2 =-    compareByteOffMem mem off1 a (toByteOff (Off o :: Off Word16) + off2)-  {-# INLINE compareByteOffMem #-}---instance MemRead ShortByteString where-  byteCountMem = byteCountMem . fromShortByteStringBytes-  {-# INLINE byteCountMem #-}-  indexOffMem sbs = indexOffMem (fromShortByteStringBytes sbs)-  {-# INLINE indexOffMem #-}-  indexByteOffMem sbs = indexByteOffMem (fromShortByteStringBytes sbs)-  {-# INLINE indexByteOffMem #-}-  copyByteOffToMBytesMem sbs = copyByteOffToMBytesMem (fromShortByteStringBytes sbs)-  {-# INLINE copyByteOffToMBytesMem #-}-  copyByteOffToPtrMem sbs = copyByteOffToPtrMem (fromShortByteStringBytes sbs)-  {-# INLINE copyByteOffToPtrMem #-}-  compareByteOffToPtrMem sbs = compareByteOffToPtrMem (fromShortByteStringBytes sbs)-  {-# INLINE compareByteOffToPtrMem #-}-  compareByteOffToBytesMem sbs = compareByteOffToBytesMem (fromShortByteStringBytes sbs)-  {-# INLINE compareByteOffToBytesMem #-}-  compareByteOffMem mem off1 sbs = compareByteOffMem mem off1 (fromShortByteStringBytes sbs)-  {-# INLINE compareByteOffMem #-}---- | A wrapper that adds a phantom state token. It can be used with types that either--- doesn't have such state token or are designed to work in `IO` and therefore restricted--- to `RW`. Using this wrapper is very much unsafe, so make sure you know what you are--- doing.-newtype MemState a s = MemState { unMemState :: a }--instance MemWrite (MemState (ForeignPtr a)) where-  readOffMem (MemState fptr) i = withForeignPtr fptr $ \ptr -> readOffPtr (castPtr ptr) i-  {-# INLINE readOffMem #-}-  readByteOffMem (MemState fptr) i =-    withForeignPtr fptr $ \ptr -> readByteOffPtr (castPtr ptr) i-  {-# INLINE readByteOffMem #-}-  writeOffMem (MemState fptr) i a = withForeignPtr fptr $ \ptr -> writeOffPtr (castPtr ptr) i a-  {-# INLINE writeOffMem #-}-  writeByteOffMem (MemState fptr) i a =-    withForeignPtr fptr $ \ptr -> writeByteOffPtr (castPtr ptr) i a-  {-# INLINE writeByteOffMem #-}-  moveByteOffToPtrMem (MemState fsrc) srcOff dstPtr dstOff c =-    withForeignPtr fsrc $ \srcPtr -> moveByteOffPtrToPtr (castPtr srcPtr) srcOff dstPtr dstOff c-  {-# INLINE moveByteOffToPtrMem #-}-  moveByteOffToMBytesMem (MemState fsrc) srcOff dst dstOff c =-    withForeignPtr fsrc $ \srcPtr -> moveByteOffPtrToMBytes (castPtr srcPtr) srcOff dst dstOff c-  {-# INLINE moveByteOffToMBytesMem #-}-  copyByteOffMem src srcOff (MemState fdst) dstOff c =-    withForeignPtr fdst $ \dstPtr ->-       copyByteOffToPtrMem src srcOff (castPtr dstPtr) dstOff c-  {-# INLINE copyByteOffMem #-}-  moveByteOffMem src srcOff (MemState fdst) dstOff c =-    withForeignPtr fdst $ \dstPtr ->-       moveByteOffToPtrMem src srcOff (castPtr dstPtr) dstOff c-  {-# INLINE moveByteOffMem #-}-  setMem (MemState fptr) off c a = withForeignPtr fptr $ \ptr -> setOffPtr (castPtr ptr) off c a-  {-# INLINE setMem #-}--modifyFetchOldMem ::-     (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> e) -> m e-modifyFetchOldMem mem o f = modifyFetchOldMemM mem o (pure . f)-{-# INLINE modifyFetchOldMem #-}---modifyFetchNewMem ::-     (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> e) -> m e-modifyFetchNewMem mem o f = modifyFetchNewMemM mem o (pure . f)-{-# INLINE modifyFetchNewMem #-}---modifyFetchOldMemM ::-     (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> m e) -> m e-modifyFetchOldMemM mem o f = do-  a <- readOffMem mem o-  a <$ (writeOffMem mem o =<< f a)-{-# INLINE modifyFetchOldMemM #-}---modifyFetchNewMemM ::-     (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> m e) -> m e-modifyFetchNewMemM mem o f = do-  a <- readOffMem mem o-  a' <- f a-  a' <$ writeOffMem mem o a'-{-# INLINE modifyFetchNewMemM #-}---defaultResizeMem ::-     (Prim e, MemAlloc ma, MonadPrim s m) => ma s -> Count e -> m (ma s)-defaultResizeMem mem c = do-  let newByteCount = toByteCount c-  oldByteCount <- getByteCountMem mem-  if oldByteCount == newByteCount-    then pure mem-    else do-      newMem <- allocMem newByteCount-      oldMem <- freezeMem mem-      newMem <$ copyMem oldMem 0 newMem 0 oldByteCount-{-# INLINE defaultResizeMem #-}----- | Place @n@ copies of supplied region of memory one after another in a newly allocated--- contiguous chunk of memory. Similar to `stimes`, but the source memory @memRead@ does--- not have to match the type of `FrozenMem` ma.------ ====__Example__------ >>> :set -XTypeApplications--- >>> :set -XDataKinds--- >>> import Data.Prim.Memory--- >>> let b = fromListMem @Word8 @(MBytes 'Inc) [0xde, 0xad, 0xbe, 0xef]--- >>> cycleMemN @(MBytes 'Inc) 2 b--- [0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef]------ @since 0.1.0-cycleMemN ::-     forall ma mr. (MemAlloc ma, MemRead mr)-  => Int-  -> mr-  -> FrozenMem ma-cycleMemN n r-  | n <= 0 = emptyMem-  | otherwise =-    runST $ do-      let bc@(Count chunk) = byteCountMem r-          c@(Count c8) = Count n * bc-      mem <- allocMem c-      let go i = when (i < c8) $ copyByteOffMem r 0 mem (Off i) bc >> go (i + chunk)-      go 0-      freezeMem mem-{-# INLINE cycleMemN #-}----- | Construct an immutable memory region that can't hold any data. Same as @`mempty` ::--- `FrozenMem` ma@------ ====__Example__------ >>> :set -XTypeApplications--- >>> :set -XDataKinds--- >>> import Data.Prim.Memory--- >>> toListMem (emptyMem @(MBytes 'Inc)) :: [Int]--- []------ @since 0.1.0-emptyMem ::-     forall ma. MemAlloc ma-  => FrozenMem ma-emptyMem = createMemST_ (0 :: Count Word8) (\_ -> pure ())-{-# INLINE emptyMem #-}---- | Allocate a region of immutable memory that holds a single element.------ ====__Example__------ >>> :set -XTypeApplications--- >>> :set -XDataKinds--- >>> import Data.Prim.Memory--- >>> toListMem (singletonMem @Word16 @(MBytes 'Inc) 0xffff) :: [Word8]--- [255,255]------ @since 0.1.0-singletonMem ::-     forall e ma. (MemAlloc ma, Prim e)-  => e -- ^ The single element that will be stored in the newly allocated region of memory-  -> FrozenMem ma-singletonMem a = createMemST_ (1 :: Count e) $ \mem -> writeOffMem mem 0 a-{-# INLINE singletonMem #-}---- | Same as `allocMem`, but also use `setMem` to reset all of newly allocated memory to--- zeros.------ [Unsafe] When precondition for @memCount@ argument is violated the outcome is--- upredictable. One possible outcome is termination with `Control.Exception.HeapOverflow`--- async exception.------ ====__Example__------ >>> :set -XTypeApplications--- >>> :set -XDataKinds--- >>> import Data.Prim.Memory--- >>> mb <- allocZeroMem @Int @(MBytes 'Inc) 10--- >>> b <- freezeMem mb--- >>> toListMem b :: [Int]--- [0,0,0,0,0,0,0,0,0,0]------ @since 0.1.0-allocZeroMem ::-     forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e)-  => Count e-  -- ^ /memCount/ - Number of elements to allocate.-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memCount-  ---  -- Converted to bytes should be less then available physical memory-  -> m (ma s)-allocZeroMem n = do-  m <- allocMem n-  m <$ setMem m 0 (toByteCount n) (0 :: Word8)-{-# INLINE allocZeroMem #-}---createMemST ::-     forall e b ma. (MemAlloc ma, Prim e)-  => Count e-  -> (forall s. ma s -> ST s b)-  -> (b, FrozenMem ma)-createMemST n f = runST $ allocMem n >>= \m -> (,) <$> f m <*> freezeMem m-{-# INLINE createMemST #-}--createMemST_ :: (MemAlloc ma, Prim e)-  => Count e-  -> (forall s . ma s -> ST s b)-  -- ^ /fillAction/ -- Action that will be used to modify contents of newly allocated-  -- memory.-  ---  -- /__Required invariant:__/-  ---  -- It is important that this action overwrites all of newly allocated memory.-  -> FrozenMem ma-createMemST_ n f = runST (allocMem n >>= \m -> f m >> freezeMem m)-{-# INLINE createMemST_ #-}--createZeroMemST ::-     forall e ma b. (MemAlloc ma, Prim e)-  => Count e-  -> (forall s. ma s -> ST s b)-  -> (b, FrozenMem ma)-createZeroMemST n f = runST $ allocZeroMem n >>= \m -> (,) <$> f m <*> freezeMem m-{-# INLINE createZeroMemST #-}---- | Same as `createMemST_`, except it ensures that the memory gets reset with zeros prior--- to applying the @ST@ filling action @fillAction@.------ [Unsafe] Same reasons as `allocZeroMem`: violation of precondition for @memCount@ may--- result in undefined behavior or `Control.Exception.HeapOverflow` async exception.------ ====__Example__------ Note that this example will work correctly only on little-endian machines:------ >>> :set -XTypeApplications--- >>> import Data.Prim--- >>> import Control.Monad--- >>> let ibs = zip [0, 4 ..] [0x48,0x61,0x73,0x6b,0x65,0x6c,0x6c] :: [(Off Word8, Word8)]--- >>> let c = Count (length ibs) :: Count Char--- >>> let bc = createZeroMemST_ @_ @(MBytes 'Inc) c $ \m -> forM_ ibs $ \(i, b) -> writeByteOffMem m i b--- >>> toListMem bc :: String--- "Haskell"------ @since 0.1.0-createZeroMemST_ ::-     forall e ma b. (MemAlloc ma, Prim e)-  => Count e-  -- ^ /memCount/ - Size of the newly allocated memory region in number of elements of-  -- type @e@-  ---  -- /__Precoditions:__/-  ---  -- Size should be non-negative, but smaller than amount of available memory. Note that the-  -- second condition simply describes overflow.-  ---  -- > 0 <= memCount-  ---  -- Possibility of overflow:-  ---  -- > unCount memCount <= fromByteCount @e (Count maxBound)-  -> (forall s. ma s -> ST s b)-  -- ^ /fillAction/ -- Action that will be used to modify contents of newly allocated-  -- memory. It is not required to overwrite the full region, since it was reset to zeros-  -- right after allocation.-  -> FrozenMem ma-createZeroMemST_ n f = runST (allocZeroMem n >>= \m -> f m >> freezeMem m)-{-# INLINE createZeroMemST_ #-}---- | Copy all of the data from the source into a newly allocate memory region of identical--- size.------ ====__Examples__------ >>> :set -XDataKinds--- >>> import Data.Prim.Memory--- >>> let xs = fromByteListMem @(MBytes 'Pin) [0..15] :: Bytes 'Pin--- >>> let ys = cloneMem xs--- >>> let report bEq pEq = print $ "Bytes equal: " ++ show bEq ++ ", their pointers equal: " ++ show pEq--- >>> withPtrBytes xs $ \ xsPtr -> withPtrBytes ys $ \ ysPtr -> report (xs == ys) (xsPtr == ysPtr)--- "Bytes equal: True, their pointers equal: False"------ @since 0.2.0-cloneMem ::-     forall ma. MemAlloc ma-  => FrozenMem ma -- ^ /memSource/ - immutable source memory.-  -> FrozenMem ma-cloneMem fm =-  runST $ do-    let n = byteCountMem fm-    mm <- allocMem n-    copyMem fm 0 mm 0 n-    freezeMem mm-{-# INLINE cloneMem #-}---- | Similar to `copyByteOffMem`, but supply offsets in number of elements instead of--- bytes. Copy contiguous chunk of memory from the read only memory region into the target--- mutable memory region. Source and target /must not/ refer to the same memory region,--- otherwise that would imply that the source is not immutable which would be a violation--- of some other invariant elsewhere in the code.------ [Unsafe] When any precondition for one of the offsets @memSourceOff@, @memTargetOff@--- or the element count @memCount@ is violated a call to this function can result in:--- copy of data that doesn't belong to @memSourceRead@, heap corruption or failure with--- a segfault.------ @since 0.1.0-copyMem ::-     (MonadPrim s m, MemRead mr, MemWrite mw, Prim e)-  => mr -- ^ /memSourceRead/ - Read-only source memory region from where to copy-  -> Off e-  -- ^ /memSourceOff/ - Offset into source memory in number of elements of type @e@-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memSourceOff-  ---  -- > unOff memSourceOff < unCount (countMem memSourceRead)-  -> mw s -- ^ /memTargetWrite/ - Target mutable memory-  -> Off e-  -- ^ /memTargetOff/ -  Offset into target memory in number of elements-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memTargetOff-  ---  -- With offset applied it should still refer to the same memory region. For types that-  -- also implement `MemAlloc` this can be described as:-  ---  -- > targetCount <- getCountMem memTargetWrite-  -- > unOff memTargetOff < unCount targetCount-  -> Count e-  -- ^ /memCount/ - Number of elements of type @e@ to copy-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memCount-  ---  -- Both source and target memory regions must have enough memory to perform a copy-  -- of @memCount@ elements starting at their respective offsets. For @memSourceRead@:-  ---  -- > unOff memSourceOff + unCount memCount < unCount (countMem memSourceRead)-  ---  -- and for @memTargetWrite@ that also implements `MemAlloc` this can be described as:-  ---  -- > targetCount <- getCountMem memTargetWrite-  -- > unOff memTargetOff + unCount memCount < unCount targetCount-  -> m ()-copyMem src srcOff dst dstOff = copyByteOffMem src (toByteOff srcOff) dst (toByteOff dstOff)-{-# INLINE copyMem #-}---moveMem ::-     (MonadPrim s m, MemWrite mw1, MemWrite mw2, Prim e)-  => mw1 s -- ^ Source memory region-  -> Off e -- ^ Offset into the source in number of elements-  -> mw2 s -- ^ Destination memory region-  -> Off e -- ^ Offset into destination in number of elements-  -> Count e -- ^ Number of elements to copy over-  -> m ()-moveMem src srcOff dst dstOff = moveByteOffMem src (toByteOff srcOff) dst (toByteOff dstOff)-{-# INLINE moveMem #-}---appendMem ::-     forall mr1 mr2 ma. (MemRead mr1, MemRead mr2, MemAlloc ma)-  => mr1-  -> mr2-  -> FrozenMem ma-appendMem r1 r2 =-  createMemST_ (n1 + n2) $ \mem -> do-    copyMem r1 0 mem 0 n1-    copyMem r2 (coerce n1) mem (coerce n1) n2-  where-    n1 = byteCountMem r1-    n2 = byteCountMem r2-{-# INLINABLE appendMem #-}--concatMem ::-     forall mr ma. (MemRead mr, MemAlloc ma)-  => [mr]-  -> FrozenMem ma-concatMem xs = do-  let c = Foldable.foldl' (\ !acc b -> acc + byteCountMem b) 0 xs-  createMemST_ c $ \mb -> do-    let load i b = do-          let cb@(Count n) = byteCountMem b :: Count Word8-          (i + Off n) <$ copyMem b 0 mb i cb-    foldM_ load 0 xs-{-# INLINABLE concatMem #-}---thawCopyMem ::-     forall e mr ma m s. (Prim e, MemRead mr, MemAlloc ma, MonadPrim s m)-  => mr-  -> Off e-  -> Count e-  -> m (ma s)-thawCopyMem a off c = do-  mem <- allocMem c-  mem <$ copyMem a off mem 0 c-{-# INLINE thawCopyMem #-}--freezeCopyMem ::-     forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m)-  => ma s-  -> Off e-  -> Count e-  -> m (FrozenMem ma)-freezeCopyMem mem off c = freezeMem mem >>= \r -> thawCopyMem r off c >>= freezeMem-{-# INLINE freezeCopyMem #-}---thawCloneMem ::-     forall mr ma m s. (MemRead mr, MemAlloc ma, MonadPrim s m)-  => mr-  -> m (ma s)-thawCloneMem a = thawCopyMem a 0 (byteCountMem a)-{-# INLINE thawCloneMem #-}--freezeCloneMem ::-     forall ma m s. (MemAlloc ma, MonadPrim s m)-  => ma s-  -> m (FrozenMem ma)-freezeCloneMem = freezeMem >=> thawCloneMem >=> freezeMem-{-# INLINE freezeCloneMem #-}---- | /O(n)/ - Convert a read-only memory region into a newly allocated other type of--- memory region------ >>> import Data.ByteString (pack)--- >>> bs = pack [0x10 .. 0x20]--- >>> bs--- "\DLE\DC1\DC2\DC3\DC4\NAK\SYN\ETB\CAN\EM\SUB\ESC\FS\GS\RS\US "--- >>> convertMem bs :: Bytes 'Inc--- [0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20]------ @since 0.1.0-convertMem :: (MemRead mr, MemAlloc ma) => mr -> FrozenMem ma-convertMem a = runST $ thawCloneMem a >>= freezeMem-{-# INLINE convertMem #-}---- | Figure out how many elements fits into the immutable region of memory. It is--- possible that there is a remainder of bytes left, see `countRemMem` for getting that--- too.------ ====__Examples__------ >>> b = fromListMem [0 .. 5 :: Word8] :: Bytes 'Pin--- >>> b--- [0x00,0x01,0x02,0x03,0x04,0x05]--- >>> countMem b :: Count Word16--- Count {unCount = 3}--- >>> countMem b :: Count Word32--- Count {unCount = 1}------ @since 0.1.0-countMem ::-     forall e mr. (MemRead mr, Prim e)-  => mr-  -> Count e-countMem = fromByteCount . byteCountMem-{-# INLINE countMem #-}---- | Compute how many elements and a byte size remainder that can fit into the region of memory.------ ====__Examples__------ >>> b = fromListMem [0 .. 5 :: Word8] :: Bytes 'Pin--- >>> b--- [0x00,0x01,0x02,0x03,0x04,0x05]--- >>> countRemMem @Word16 b--- (Count {unCount = 3},Count {unCount = 0})--- >>> countRemMem @Word32 b--- (Count {unCount = 1},Count {unCount = 2})------ @since 0.1.0-countRemMem :: forall e mr. (MemRead mr, Prim e) => mr -> (Count e, Count Word8)-countRemMem = fromByteCountRem . byteCountMem-{-# INLINE countRemMem #-}--getCountMem :: forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e) => ma s -> m (Count e)-getCountMem = fmap (fromByteCount . coerce) . getByteCountMem-{-# INLINE getCountMem #-}---getCountRemMem ::-     forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e)-  => ma s-  -> m (Count e, Count Word8)-getCountRemMem = fmap (fromByteCountRem . coerce) . getByteCountMem-{-# INLINE getCountRemMem #-}---clone ::-     forall ma m s. (MemAlloc ma, MonadPrim s m)-  => ma s-  -> m (ma s)-clone mb = do-  n <- getByteCountMem mb-  mb' <- allocMem n-  mb' <$ moveMem mb 0 mb' 0 n-{-# INLINE clone #-}---- | Compare two memory regions byte-by-byte. `False` is returned immediately when sizes--- reported by `byteCountMem` do not match. Computation may be short-circuited on the--- first mismatch, but it is `MemRead` implementation specific.------ @since 0.1.0-eqMem :: (MemRead mr1, MemRead mr2) => mr1 -> mr2 -> Bool-eqMem b1 b2 = n == byteCountMem b2 && compareByteOffMem b1 0 b2 0 n == EQ-  where-    n = byteCountMem b1-{-# INLINE eqMem #-}---- | Compare two regions of memory byte-by-byte. It will return `EQ` whenever both regions--- are exactly the same and `LT` or `GT` as soon as the first byte is reached that is less--- than or greater than respectfully in the first region when compared to the second--- one. It is safe for both regions to refer to the same part of memory, since this is a--- pure function and both regions of memory are read-only.-compareMem ::-     forall e mr1 mr2. (MemRead mr1, MemRead mr2, Prim e)-  => mr1 -- ^ First region of memory-  -> Off e -- ^ Offset in number of elements into the first region-  -> mr2 -- ^ Second region of memory-  -> Off e -- ^ Offset in number of elements into the second region-  -> Count e -- ^ Number of elements to compare-  -> Ordering-compareMem r1 off1 r2 off2 = compareByteOffMem r1 (toByteOff off1) r2 (toByteOff off2)-{-# INLINE compareMem #-}---- =============== ----- List conversion ----- =============== -------------------- To List -------------------- | Convert an immutable memory region to a list. Whenever memory byte count is not--- exactly divisible by the size of the element there will be some slack left unaccounted--- for. In order to get a hold of this slack use `toListSlackMem` instead.------ ====__Examples__------ >>> import Data.Prim.Memory--- >>> import Numeric (showHex)--- >>> let b = fromByteListMem [0x48,0x61,0x73,0x6b,0x65,0x6c,0x6c] :: Bytes 'Inc--- >>> toListMem b :: [Int8]--- [72,97,115,107,101,108,108]--- >>> let xs = toListMem b :: [Word32]--- >>> xs--- [1802723656]--- >>> showHex (head xs) ""--- "6b736148"------ @since 0.1.0-toListMem :: forall e mr. (MemRead mr, Prim e) => mr -> [e]-toListMem ba = build (\ c n -> foldrCountMem (countMem ba) c n ba)-{-# INLINE toListMem #-}-{-# SPECIALIZE toListMem :: Prim e => Bytes p -> [e] #-}---- | Same as `toListMem`, except when there is some slack towards the end of the memory--- region that didn't fit into a list it will be returned as a list of bytes.------ ====__Examples__------ >>> import Data.Word--- >>> :set -XDataKinds--- >>> a = fromListMem [0 .. 10 :: Word8] :: Bytes 'Pin--- >>> a--- [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a]--- >>> toListSlackMem a :: ([Word8], [Word8])--- ([0,1,2,3,4,5,6,7,8,9,10],[])--- >>> toListSlackMem a :: ([Word16], [Word8])--- ([256,770,1284,1798,2312],[10])--- >>> toListSlackMem a :: ([Word32], [Word8])--- ([50462976,117835012],[8,9,10])--- >>> toListSlackMem a :: ([Word64], [Word8])--- ([506097522914230528],[8,9,10])------ @since 0.1.0-toListSlackMem ::-     forall e mr. (MemRead mr, Prim e)-  => mr-  -> ([e], [Word8])-toListSlackMem mem =-  (build (\c n -> foldrCountMem k c n mem), getSlack (k8 + r8) [])-  where-    (k, Count r8) = countRemMem mem-    Count k8 = toByteCount k-    getSlack i !acc-      | i == k8 = acc-      | otherwise =-        let i' = i - 1-         in getSlack i' (indexByteOffMem mem (Off i') : acc)-{-# INLINABLE toListSlackMem #-}---- | Right fold that is useful for converting to a list while tapping into list fusion.------ [Unsafe] Supplying Count larger than memory holds will result in reading out of bounds--- and a potential segfault.------ @since 0.1.0-foldrCountMem :: forall e b mr. (MemRead mr, Prim e) => Count e -> (e -> b -> b) -> b -> mr -> b-foldrCountMem (Count k) c nil bs = go 0-  where-    go i-      | i == k = nil-      | otherwise =-        let !v = indexOffMem bs (Off i)-         in v `c` go (i + 1)-{-# INLINE[0] foldrCountMem #-}-------------------- From List ---------------------- Pure immutable conversion ------ | Just like `fromListMemN`, except it ensures safety by using the length of the--- list for allocation. Because it has to figure out the length of the list first it--- will be just a little bit slower, but that much safer.------ ====__Examples__------ >>> import Data.Prim.Memory--- >>> :set -XDataKinds--- >>> fromListMem "Hi" :: Bytes 'Inc--- [0x48,0x00,0x00,0x00,0x69,0x00,0x00,0x00]------ @since 0.1.0-fromListMem ::-     forall e ma. (Prim e, MemAlloc ma)-  => [e]-  -> FrozenMem ma-fromListMem xs =-  let count = coerce (length xs) `countForProxyTypeOf` xs-   in createMemST_ count (loadListMemN_ count xs)-{-# INLINE fromListMem #-}----- | Same as `fromListMem` but restricted to a list of `Word8`. Load a list of bytes into--- a newly allocated memory region. Equivalent to `Data.ByteString.pack` for--- `Data.ByteString.ByteString`------ ====__Examples__------ >>> fromByteListMem [0..10] :: Bytes 'Pin--- [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a]------ @since 0.1.0-fromByteListMem ::-     forall ma. MemAlloc ma-  => [Word8]-  -> FrozenMem ma-fromByteListMem = fromListMem-{-# INLINE fromByteListMem #-}----- | Similarly to `fromListMem` load a list into a newly allocated memory region, but--- unlike the aforementioned function it also accepts a hint of how many elements is--- expected to be in the list. Because the number of expected an actual elements might--- not match we return not only the frozen memory region, but also:------ * either a list with leftover elements from the input @list@, if it did not fully fit---   into the allocated region. An empty list would indicate that it did fit exactly.------     @---     unCount memCount <= length list---     @------ * or an exact count of how many elements have been loaded when there was no---   enough elements in the list--------- In the latter case a zero value would indicate that the list did fit into the newly--- allocated memory region exactly, which is perfectly fine. But a positive value would--- mean that the tail of the memory region is still unset and might contain garbage--- data. Make sure to overwrite the surplus memory yourself or use the safe version--- `fromListZeroMemN` that fills the surplus with zeros.------ [Unsafe] Whenever @memCount@ precodition is violated, because on each call with the--- same input it can produce different output therefore it will break referential--- transparency.------ ====__Examples__------ >>> :set -XTypeApplications--- >>> fromListMemN @Char @(MBytes 'Inc) 3 "Hello"--- (Left "lo",[0x48,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00])--- >>> fromListMemN @Char @(MBytes 'Inc) 2 "Hi"--- (Left "",[0x48,0x00,0x00,0x00,0x69,0x00,0x00,0x00])--- >>> fst $ fromListMemN @Char @(MBytes 'Inc) 5 "Hi"--- Right (Count {unCount = 2})------ @since 0.2.0-fromListMemN ::-     forall e ma. (Prim e, MemAlloc ma)-  => Count e-  -- ^ /memCount/ - Expected number of elements in the list, which exactly how much-  -- memory will be allocated.-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memCount-  -- > unCount memCount <= length list-  -> [e]-  -- ^ /list/ - A list of elements to load into the newly allocated memory region.-  -> (Either [e] (Count e), FrozenMem ma)-fromListMemN count xs =-  createMemST count $ \mm -> do-    (ys, loadedCount) <- loadListOffMemN count xs mm 0-    pure $-      if loadedCount /= count && null ys-        then Right loadedCount-        else Left ys-{-# INLINE fromListMemN #-}----- | Just like `fromListMemN`, except it ensures safety by filling tail with zeros,--- whenever the list is not long enough.------ ====__Examples__------ >>> import Data.Prim.Memory--- >>> :set -XTypeApplications--- >>> fromListZeroMemN @Char @(MBytes 'Inc) 3 "Hi"--- (Right (Count {unCount = 2}),[0x48,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x00,0x00,0x00,0x00])------ @since 0.2.0-fromListZeroMemN ::-     forall e ma. (Prim e, MemAlloc ma)-  => Count e -- ^ /memCount/ - Number of elements to load from the list.-  -> [e]-  -> (Either [e] (Count e), FrozenMem ma)-fromListZeroMemN count xs =-  createMemST (max 0 count) $ \mm -> do-    (ys, loadedCount) <- loadListOffMemN count xs mm 0-    let loadedByteCount = toByteCount loadedCount-        surplusByteCount = toByteCount count - loadedByteCount-    when (surplusByteCount > 0) $ setMem mm (countToOff loadedByteCount) surplusByteCount 0-    pure $-      if loadedCount /= count && null ys-        then Right loadedCount-        else Left ys-{-# INLINE fromListZeroMemN #-}---- | Same as `fromListZeroMemN`, but ignore the extra information about how the loading went.------ ====__Examples__------ >>> import Data.Prim.Memory--- >>> fromListZeroMemN_ 3 "Hi" :: Bytes 'Inc--- [0x48,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x00,0x00,0x00,0x00]------ @since 0.2.0-fromListZeroMemN_ ::-     forall e ma. (Prim e, MemAlloc ma)-  => Count e-  -> [e]-  -> FrozenMem ma-fromListZeroMemN_ !n = snd . fromListZeroMemN n-{-# INLINE fromListZeroMemN_ #-}------ Mutable loading -----loadListByteOffHelper ::-     (MemWrite mw, MonadPrim s m, Prim e)-  => [e]-  -> mw s-  -> Off Word8 -- ^ Offset-  -> Off Word8 -- ^ Upper bound-  -> Off Word8 -- ^ Element size-  -> m ([e], Count e)-loadListByteOffHelper ys mw byteOff k step =-  let go []       i = pure ([], toLoadedCount i)-      go a@(x:xs) i-        | i < k = writeByteOffMem mw i x >> go xs (i + step)-        | otherwise = pure (a, toLoadedCount i)-      toLoadedCount i = fromByteCount (offToCount (i - byteOff))-   in go ys byteOff-{-# INLINE loadListByteOffHelper #-}----- | Load elements from the supplied list into a mutable memory region. Loading will--- start at the supplied offset in number of bytes and will stop when either supplied--- @elemCount@ number is reached or there are no more elements left in the list to--- load. This action returns a list of elements that did not get loaded and the count of--- how many elements did get loaded.------ [Unsafe] When any precondition for either the offset @memTargetOff@ or the element--- count @memCount@ is violated then a call to this function can result in heap corruption--- or failure with a segfault.------ ====__Examples__------ For example load the @"Hell"@ somewhere in the middle of `MBytes`:------ >>> ma <- allocZeroMem (6 :: Count Char) :: IO (MBytes 'Inc RW)--- >>> loadListByteOffMemN 4 "Hello!" ma (toByteOff (1 :: Off Char))--- ("o!",Count {unCount = 4})--- >>> freezeMem ma--- [0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00]------ Or something more usful like loading prefixes from nested lists:------ >>> import Control.Monad--- >>> foldM_ (\o xs -> (+ o) . countToByteOff . snd <$> loadListByteOffMemN 4 xs ma o) 2 [[x..] | x <- [1..5] :: [Word8]]--- >>> freezeMem ma--- [0x00,0x00,0x01,0x02,0x03,0x04,0x02,0x03,0x04,0x05,0x03,0x04,0x05,0x06,0x04,0x05,0x06,0x07,0x05,0x06,0x07,0x08,0x00,0x00]------ @since 0.2.0-loadListByteOffMemN ::-     (MemWrite mw, MonadPrim s m, Prim e)-  => Count e-  -- ^ /elemCount/ - Maximum number of elements to load from list into the memory region-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memCount-  ---  -- Target memory region must have enough memory to perform loading of @elemCount@-  -- elements starting at the @memTargetOff@ offset. For types that also implement-  -- `MemAlloc` this can be described as:-  ---  -- > targetByteCount <- getByteCountMem memTarget-  -- > unOff memTargetOff + unCountBytes elemCount <= unCount (targetByteCount - byteCountType @e)-  -> [e] -- ^ /listSource/ - List with elements that should be loaded-  -> mw s -- ^ /memTarget/ - Memory region where to load the elements into-  -> Off Word8-  -- ^ /memTargetOff/ - Offset in number of bytes into target memory where writing will start-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memTargetOff-  ---  -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same memory-  -- region @memTarget@. For types that also implement `MemAlloc` this can be described-  -- as:-  ---  -- > targetByteCount <- getByteCountMem memTarget-  -- > unOff memTargetOff <= unCount (targetByteCount - byteCountType @e)-  -> m ([e], Count e)-  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.-loadListByteOffMemN count ys mw byteOff = loadListByteOffHelper ys mw byteOff k step-  where-    k = byteOff + countToOff (toByteCount count)-    step = countToOff $ byteCountProxy ys-{-# INLINABLE loadListByteOffMemN #-}---- | Same as `loadListByteOffMemN`, but infer the count from number of bytes that is--- available in the target memory region.------ [Unsafe] When a precondition for the element count @memCount@ is violated then a call--- to this function can result in heap corruption or failure with a segfault.------ ====__Examples__------ >>> :set -XDataKinds--- >>> import Data.Prim.Memory--- >>> ma <- allocZeroMem (5 :: Count Char) :: IO (MBytes 'Inc RW)--- >>> freezeMem ma--- [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]--- >>> loadListByteOffMem "Hello World" ma 0--- (" World",Count {unCount = 5})--- >>> freezeMem ma--- [0x48,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6f,0x00,0x00,0x00]--- >>> loadListByteOffMem ([0xff,0xff,0xff] :: [Word8]) ma 1--- ([],Count {unCount = 3})--- >>> freezeMem ma--- [0x48,0xff,0xff,0xff,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6f,0x00,0x00,0x00]------ @since 0.2.0-loadListByteOffMem ::-     (MemAlloc ma, MonadPrim s m, Prim e)-  => [e] -- ^ /listSource/ - List with elements that should be loaded-  -> ma s -- ^ /memTarget/ - Memory region where to load the elements into-  -> Off Word8-  -- ^ /memTargetOff/ - Offset in number of bytes into target memory where writing will start-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memTargetOff-  ---  -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same memory-  -- region @memTarget@. For types that also implement `MemAlloc` this can be described-  -- as:-  ---  -- > targetByteCount <- getByteCountMem memTarget-  -- > unOff memTargetOff <= unCount (targetByteCount - byteCountType @e)-  -> m ([e], Count e)-  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.-loadListByteOffMem ys ma byteOff = do-  bCount <- getByteCountMem ma-  let k = countToOff bCount - byteOff-      step = countToOff $ byteCountProxy ys-  loadListByteOffHelper ys ma byteOff k step-{-# INLINABLE loadListByteOffMem #-}---- | Same as `loadListByteOffMemN`, but works with offset in number of elements instead of--- bytes.------ [Unsafe] When preconditions for either the offset @memTargetOff@ or the element count--- @memCount@ is violated then a call to this function can result in heap corruption or--- failure with a segfault.------ @since 0.2.0-loadListOffMemN ::-     (MemWrite mw, MonadPrim s m, Prim e)-  => Count e-  -- ^ /elemCount/ - Maximum number of elements to load from list into the memory region-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memCount-  ---  -- Target memory region must have enough memory to perform loading of @elemCount@-  -- elements starting at the @memTargetOff@ offset. For types that also implement-  -- `MemAlloc` this can be described as:-  ---  -- > targetCount <- getCountMem memTarget-  -- > unOff memTargetOff + unCount elemCount < unCount targetCount-  -> [e] -- ^ /listSource/ - List with elements that should be loaded-  -> mw s -- ^ /memTarget/ - Memory region where to load the elements into-  -> Off e-  -- ^ /memTargetOff/ - Offset in number of elements into target memory where writing will start-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memTargetOff-  ---  -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same memory-  -- region @memTarget@. For types that also implement `MemAlloc` this can be described-  -- as:-  ---  -- > targetCount <- getByteCountMem memTarget-  -- > unOff memTargetOff < unCount targetCount-  -> m ([e], Count e)-  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.-loadListOffMemN count ys mw off =-  let go []       i = pure ([], toLoadedCount i)-      go a@(x:xs) i-        | i < k = writeOffMem mw i x >> go xs (i + 1)-        | otherwise = pure (a, toLoadedCount i)-      k = off + countToOff count-      toLoadedCount i = offToCount (i - off)-  in go ys off-{-# INLINABLE loadListOffMemN #-}----- | Same as `loadListOffMemN`, but start loading at @0@ offset.------ [Unsafe] When any precondition for the element count @memCount@ is violated then a call to--- this function can result in heap corruption or failure with a segfault.------ @since 0.2.0-loadListMemN ::-     forall e mw m s. (MemWrite mw, MonadPrim s m, Prim e)-  => Count e-  -- ^ /elemCount/ - Maximum number of elements to load from list into the memory region-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memCount-  ---  -- Target memory region must have enough memory to perform loading of @elemCount@-  -- elements. For types that also implement `MemAlloc` this can be described as:-  ---  -- > targetCount <- getCountMem memTarget-  -- > elemCount <= targetCount-  -> [e] -- ^ /listSource/ - List with elements that should be loaded-  -> mw s -- ^ /memTarget/ - Memory region where to load the elements into-  -> m ([e], Count e)-  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.-loadListMemN count xs mw = loadListOffMemN count xs mw 0-{-# INLINABLE loadListMemN #-}------ | Same as `loadListMemN`, but ignores the result.------ [Unsafe] When any precondition for the element count @memCount@ is violated then a call--- to this function can result in heap corruption or failure with a segfault.------ @since 0.2.0-loadListMemN_ ::-     forall e mw m s. (Prim e, MemWrite mw, MonadPrim s m)-  => Count e-  -- ^ /elemCount/ - Maximum number of elements to load from list into the memory region-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memCount-  ---  -- Target memory region must have enough memory to perform loading of @elemCount@-  -- elements. For types that also implement `MemAlloc` this can be described as:-  ---  -- > targetCount <- getCountMem memTarget-  -- > elemCount <= targetCount-  -> [e] -- ^ /listSource/ - List with elements that should be loaded-  -> mw s -- ^ /memTarget/ - Memory region where to load the elements into-  -> m ()-loadListMemN_ (Count n) ys mb =-  let go []     _ = pure ()-      go (x:xs) i = when (i < n) $ writeOffMem mb (Off i) x >> go xs (i + 1)-   in go ys 0-{-# INLINABLE loadListMemN_ #-}------- | Same as `loadListOffMemN`, but infer the count from number of bytes that is available--- in the target memory region.------ [Unsafe] When a precondition for the element count @memCount@ is violated then a call--- to this function can result in heap corruption or failure with a segfault.------ @since 0.2.0-loadListOffMem ::-     forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m)-  => [e] -- ^ /listSource/ - List with elements that should be loaded-  -> ma s -- ^ /memTarget/ - Memory region where to load the elements into-  -> Off e-  -- ^ /memTargetOff/ - Offset in number of elements into target memory where writing will-  -- start-  ---  -- /__Preconditions:__/-  ---  -- > 0 <= memTargetOff-  ---  -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same memory-  -- region @memTarget@. For types that also implement `MemAlloc` this can be described-  -- as:-  ---  -- > targetCount <- getCountMem memTarget-  -- > unOff memTargetOff < unCount targetCount-  -> m ([e], Count e)-  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.-loadListOffMem ys ma off = getCountMem ma >>= \c -> loadListOffMemN (c - offToCount off) ys ma off-{-# INLINE loadListOffMem #-}----- | Same as `loadListMemN`, but tries to fit as many elements as possible into the mutable--- memory region starting at the beginning. This operation is always safe.------ ====__Examples__------ >>> import Data.Prim.Memory--- >>> ma <- allocMem (5 :: Count Char) :: IO (MBytes 'Inc RW)--- >>> loadListMem "HelloWorld" ma--- ("World",Count {unCount = 5})--- >>> freezeMem ma--- [0x48,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6f,0x00,0x00,0x00]--- >>> loadListMem (replicate 6 (0xff :: Word8)) ma--- ([],Count {unCount = 6})--- >>> freezeMem ma--- [0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6f,0x00,0x00,0x00]------ @since 0.2.0-loadListMem ::-     forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m)-  => [e] -- ^ /listSource/ - List with elements to load-  -> ma s -- ^ /memTarget/ - Mutable region where to load elements from the list-  -> m ([e], Count e)-  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.-loadListMem ys ma = getCountMem ma >>= \c -> loadListOffMemN (c `countForProxyTypeOf` ys) ys ma 0-{-# INLINE loadListMem #-}---- | Same as `loadListMem`, but ignores the result. Equivalence as property:------ prop> let c = fromInteger (abs i) :: Count Int in (createZeroMemST_ c (loadListMem_ (xs :: [Int])) :: Bytes 'Inc) == createZeroMemST_ c (void . loadListMem xs)------ @since 0.2.0-loadListMem_ ::-     forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m)-  => [e] -- ^ /listSource/ - List with elements to load-  -> ma s -- ^ /memTarget/ - Mutable region where to load elements from the list-  -> m ()-loadListMem_ ys mb = getCountMem mb >>= \c -> loadListMemN_ (c `countForProxyTypeOf` ys) ys mb-{-# INLINE loadListMem_ #-}----- | Convert a memory region to a list of bytes. Equivalent to `Data.ByteString.unpack`--- for `Data.ByteString.ByteString`------ ====__Example__------ >>> toByteListMem (fromByteListMem [0..10] :: Bytes 'Pin)--- [0,1,2,3,4,5,6,7,8,9,10]------ @since 0.1.0-toByteListMem ::-     forall ma. MemAlloc ma-  => FrozenMem ma-  -> [Word8]-toByteListMem = toListMem-{-# INLINE toByteListMem #-}---- mapMem ::---      forall e e' mr ma. (MemRead mr, MemAlloc ma, Prim e, Prim e')---   => (e -> e')---   -> mr---   -> (FrozenMem ma, [Word8])--- mapMem f = undefined---mapByteMem ::-     forall e mr ma. (MemRead mr, MemAlloc ma, Prim e)-  => (Word8 -> e)-  -> mr-  -> FrozenMem ma-mapByteMem f = imapByteOffMem (const f)---- Map an index aware function over memory region------ >>> import Data.Prim.Memory--- >>> a = fromListMem [1 .. 10 :: Word8] :: Bytes 'Inc--- >>> a--- [0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a]--- >>> imapByteOffMem (\i e -> (fromIntegral i :: Int8, e + 0xf0)) a :: Bytes 'Pin--- [0x00,0xf1,0x01,0xf2,0x02,0xf3,0x03,0xf4,0x04,0xf5,0x05,0xf6,0x06,0xf7,0x07,0xf8,0x08,0xf9,0x09,0xfa]------ @since 0.1.0-imapByteOffMem ::-     (MemRead mr, MemAlloc ma, Prim e) => (Off Word8 -> Word8 -> e) -> mr -> FrozenMem ma-imapByteOffMem f r = runST $ mapByteOffMemM (\i -> pure . f i) r---- @since 0.1.0-mapByteMemM ::-     (MemRead mr, MemAlloc ma, MonadPrim s m, Prim e)-  => (Word8 -> m e)-  -> mr-  -> m (FrozenMem ma)-mapByteMemM f = mapByteOffMemM (const f)----- @since 0.1.0-mapByteOffMemM ::-     forall e mr ma m s. (MemRead mr, MemAlloc ma, MonadPrim s m, Prim e)-  => (Off Word8 -> Word8 -> m e)-  -> mr-  -> m (FrozenMem ma)-mapByteOffMemM f r = do-  let bc@(Count n) = byteCountMem r-      c = Count n `countForProxyTypeOf` f 0 0-  mem <- allocMem c-  _ <- forByteOffMemM_ r 0 bc f-  -- let go i =-  --       when (i < n) $ do-  --         f i (indexByteOffMem r (Off i)) >>=-  --           writeOffMem mem (offAsProxy c (Off i))-  --         go (i + 1)-  -- go 0-  freezeMem mem----- | Iterate over a region of memory-forByteOffMemM_ ::-     (MemRead mr, MonadPrim s m, Prim e)-  => mr-  -> Off Word8-  -> Count e-  -> (Off Word8 -> e -> m b)-  -> m (Off Word8)-forByteOffMemM_ r (Off byteOff) c f =-  let n = coerce (toByteCount c) + byteOff-      Count k = byteCountProxy c-      go i-        | i < n = f (Off i) (indexByteOffMem r (Off i)) >> go (i + k)-        | otherwise = pure $ Off i-   in go byteOff--loopShortM :: Monad m => Int -> (Int -> a -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a-loopShortM !startAt condition increment !initAcc f = go startAt initAcc-  where-    go !step !acc-      | condition step acc = f step acc >>= go (increment step)-      | otherwise = pure acc-{-# INLINE loopShortM #-}--loopShortM' :: Monad m => Int -> (Int -> a -> m Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a-loopShortM' !startAt condition increment !initAcc f = go startAt initAcc-  where-    go !step !acc =-      condition step acc >>= \cont ->-        if cont-          then f step acc >>= go (increment step)-          else pure acc-{-# INLINE loopShortM' #-}---- -- | Iterate over a region of memory--- loopMemM_ ::---      (MemRead mr, MonadPrim s m, Prim e)---   => r---   -> Off Word8---   -> Count e---   -> (Count Word8 -> a -> Bool)---   -> (Off Word8 -> e -> m b)---   -> m (Off Word8)--- foldlByteOffMemM_ r (Off byteOff) c f =---   loopShortM byteOff (\i -> f (coerce i))---   let n = coerce (toByteCount c) + byteOff---       Count k = byteCountProxy c---       go i---         | i < n = f (Off i) (indexByteOffMem r (Off i)) >> go (i + k)---         | otherwise = pure $ Off i---    in go byteOff---data MemView a = MemView-  { mvOffset :: {-# UNPACK #-} !(Off Word8)-  , mvCount  :: {-# UNPACK #-} !(Count Word8)-  , mvMem    :: !a-  }--data MMemView a s = MMemView-  { mmvOffset :: {-# UNPACK #-} !(Off Word8)-  , mmvCount  :: {-# UNPACK #-} !(Count Word8)-  , mmvMem    :: !(a s)-  }--izipWithByteOffMemM_ ::-     (MemRead mr1, MemRead mr2, MonadPrim s m, Prim e)-  => mr1-  -> Off Word8-  -> mr2-  -> Off Word8-  -> Count e-  -> (Off Word8 -> e -> Off Word8 -> e -> m b)-  -> m (Off Word8)-izipWithByteOffMemM_ r1 (Off byteOff1) r2 off2 c f =-  let n = coerce (toByteCount c) + byteOff1-      Count k = byteCountProxy c-      go i-        | i < n =-          let o1 = Off i-              o2 = Off i + off2-           in f o1 (indexByteOffMem r1 o1) o2 (indexByteOffMem r2 o2) >>-              go (i + k)-        | otherwise = pure $ Off i-   in go byteOff1---izipWithOffMemM_ ::-     (MemRead mr1, MemRead mr2, MonadPrim s m, Prim e1, Prim e2)-  => mr1-  -> Off e1-  -> mr2-  -> Off e2-  -> Int-  -> (Off e1 -> e1 -> Off e2 -> e2 -> m b)-  -> m ()-izipWithOffMemM_ r1 off1 r2 off2 nc f =-  let n = nc + coerce off1-      go o1@(Off i) o2 =-        when (i < n) $-        f o1 (indexOffMem r1 o1) o2 (indexOffMem r2 o2) >> go (o1 + 1) (o2 + 1)-   in go off1 off2----- class Mut f => MFunctor f where---   mmap :: (Elt f a, Elt f b, MonadPrim s m) => (a -> b) -> f a s -> m (f b s)---- class Mut f => MTraverse f where---   mmapM :: (Elt f a, Elt f b, MonadPrim s m) => (a -> m b) -> f a s -> m (f b s)---- class MFunctor f => MApplicative f where---   pureMut :: (Elt f a, MonadPrim s m) => a -> m (f a s)---   liftMut ::---     (Elt f a, Elt f b, Elt f c, MonadPrim s m) => (a -> b -> m c) -> f a s -> f b s -> m (f c s)---- class MApplicative f => MMonad f where---   bindMut ::---     (Elt f a, Elt f b, MonadPrim s m) => f a s -> (a -> m b) -> f b s -> m (f c s)---- instance MFunctor MAddr where---   mmap f maddr = do---     Count n <- getCountMAddr maddr---     maddr' <- allocMAddr (Count n)---     let go i =---           when (i < n) $ do---             writeOffMAddr maddr' (Off i) . f =<< readOffMAddr maddr (Off i)---             go (i + 1)---     maddr' <$ go 0---- instance MTraverse MAddr where---   mmapM f maddr = do---     Count n <- getCountMAddr maddr---     maddr' <- allocMAddr (Count n)---     let go i =---           when (i < n) $ do---             writeOffMAddr maddr' (Off i) =<< f =<< readOffMAddr maddr (Off i)---             go (i + 1)---     maddr' <$ go 0--------------------------- Bytes instances --------------------------instance MemRead (Bytes p) where-  byteCountMem = byteCountBytes-  {-# INLINE byteCountMem #-}-  indexOffMem = indexOffBytes-  {-# INLINE indexOffMem #-}-  indexByteOffMem = indexByteOffBytes-  {-# INLINE indexByteOffMem #-}-  copyByteOffToMBytesMem = copyByteOffBytesToMBytes-  {-# INLINE copyByteOffToMBytesMem #-}-  copyByteOffToPtrMem = copyByteOffBytesToPtr-  {-# INLINE copyByteOffToPtrMem #-}-  compareByteOffToPtrMem bytes1 off1 ptr2 off2 c =-    pure $! compareByteOffBytesToPtr bytes1 off1 ptr2 off2 c-  {-# INLINE compareByteOffToPtrMem #-}-  compareByteOffToBytesMem bytes1 off1 bytes2 off2 c =-    compareByteOffBytes bytes1 off1 bytes2 off2 c-  {-# INLINE compareByteOffToBytesMem #-}-  compareByteOffMem mem1 off1 bs off2 c =-    compareByteOffToBytesMem mem1 off1 bs off2 c-  {-# INLINE compareByteOffMem #-}--instance Typeable p => MemAlloc (MBytes p) where-  type FrozenMem (MBytes p) = Bytes p-  getByteCountMem = getByteCountMBytes-  {-# INLINE getByteCountMem #-}-  allocMem = allocMBytes-  {-# INLINE allocMem #-}-  thawMem = thawBytes-  {-# INLINE thawMem #-}-  freezeMem = freezeMBytes-  {-# INLINE freezeMem #-}-  resizeMem = reallocMBytes-  {-# INLINE resizeMem #-}--instance MemWrite (MBytes p) where-  readOffMem = readOffMBytes-  {-# INLINE readOffMem #-}-  readByteOffMem = readByteOffMBytes-  {-# INLINE readByteOffMem #-}-  writeOffMem = writeOffMBytes-  {-# INLINE writeOffMem #-}-  writeByteOffMem = writeByteOffMBytes-  {-# INLINE writeByteOffMem #-}-  moveByteOffToPtrMem = moveByteOffMBytesToPtr-  {-# INLINE moveByteOffToPtrMem #-}-  moveByteOffToMBytesMem = moveByteOffMBytesToMBytes-  {-# INLINE moveByteOffToMBytesMem #-}-  moveByteOffMem = moveByteOffToMBytesMem-  {-# INLINE moveByteOffMem #-}-  copyByteOffMem = copyByteOffToMBytesMem-  {-# INLINE copyByteOffMem #-}-  setMem = setMBytes-  {-# INLINE setMem #-}---instance Show (Bytes p) where-  show b =-    Foldable.foldr' ($) "]" $-    ('[' :) : List.intersperse (',' :) (map (("0x" ++) .) (showsHexMem b))--instance Typeable p => IsList (Bytes p) where-  type Item (Bytes p) = Word8-  fromList = fromListMem-  {-# INLINE fromList #-}-  fromListN n = fromListZeroMemN_ (Count n)-  {-# INLINE fromListN #-}-  toList = toListMem-  {-# INLINE toList #-}--instance Eq (Bytes p) where-  b1 == b2 = isSameBytes b1 b2 || eqMem b1 b2-  {-# INLINE (==) #-}--instance Ord (Bytes p) where-  compare b1 b2 =-    compare n (byteCountBytes b2) <> compareByteOffBytes b1 0 b2 0 n-    where-      n = byteCountBytes b1-  {-# INLINE compare #-}--instance Typeable p => Semigroup.Semigroup (Bytes p) where-  (<>) = appendMem-  {-# INLINE (<>) #-}-  sconcat (x :| xs) = concatMem (x:xs)-  {-# INLINE sconcat #-}-  stimes i = cycleMemN (fromIntegral i)-  {-# INLINE stimes #-}--instance Typeable p => Monoid.Monoid (Bytes p) where-  mappend = appendMem-  {-# INLINE mappend #-}-  mconcat = concatMem-  {-# INLINE mconcat #-}-  mempty = emptyMem-  {-# INLINE mempty #-}----- | A list of `ShowS` which covert bytes to base16 encoded strings. Each element of the list--- is a function that will convert one byte.------ ====__Example__------ >>> :set -XDataKinds--- >>> import Data.Prim.Memory--- >>> concatMap ($ " ") $ showsHexMem (fromListMem [1 :: Int16 .. 15] :: Bytes 'Inc)--- "01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 0a 00 0b 00 0c 00 0d 00 0e 00 0f 00 "------ @since 0.1.0-showsHexMem :: MemRead mr => mr -> [ShowS]-showsHexMem b = map toHex (toListMem b :: [Word8])-  where-    toHex b8 =-      (if b8 <= 0x0f-         then ('0' :)-         else id) .-      showHex b8---- | Ensure that memory is filled with zeros before and after it gets used. `PtrAccess` is--- not used directly, but istead is used to guarantee that the memory is pinned and its--- contents do get moved around by the garbage collector.------ @since 0.2.0-withScrubbedMem ::-     forall e ma m a.-     (MonadUnliftPrim RW m, Prim e, MemAlloc ma, PtrAccess RW (ma RW))-  => Count e-  -> (ma RW -> m a)-  -> m a-withScrubbedMem c f = do-  mem <- allocZeroMem c-  let _fptr = toForeignPtr mem :: IO (ForeignPtr e) -- Force the `PtrAccess` constraint.-  f mem `finallyPrim` setMem mem 0 (toByteCount c) 0-  where-    finallyPrim m1 m2 = withRunInPrimBase $ \run -> finally (run m1) (run m2)-{-# INLINE withScrubbedMem #-}+import Control.Prim.Exception+import Control.Prim.Monad.Unsafe+import qualified Data.ByteString as BS+import Data.Foldable as Foldable+import Data.Kind+import Data.List as List+import Data.List.NonEmpty (NonEmpty(..))+import qualified Data.Monoid as Monoid+import Data.Prim+import Data.Prim.Array+import Data.Prim.Memory.Bytes.Internal+import Data.Prim.Memory.ByteString+import Data.Prim.Memory.ForeignPtr+import Data.Prim.Memory.Ptr+import qualified Data.Prim.Memory.Text as T+import qualified Data.Semigroup as Semigroup+import Foreign.Prim+import Numeric (showHex)++-- | Type class that can be implemented for an immutable data type that provides+-- read-only direct access to memory+class MemRead mr where++  -- | Check if two read only regions refer to the exact same region of memory+  --+  -- @since 0.3.0+  isSameMem :: mr -> mr -> Bool++  -- | Number of bytes allocated by the data type available for reading.+  --+  -- ====__Example__+  --+  -- >>> :set -XDataKinds+  -- >>> import Data.Prim.Memory+  -- >>> byteCountMem (fromByteListMem [1,2,3] :: Bytes 'Inc)+  -- Count {unCount = 3}+  --+  -- @since 0.1.0+  byteCountMem :: mr -> Count Word8++  -- | Read an element with an offset in number of elements, rather than bytes as is the+  -- case with `indexByteOffMem`.+  --+  -- [Unsafe] Bounds are not checked. When precondition for @off@ argument is violated the+  -- result is either unpredictable output or failure with a segfault.+  --+  -- @since 0.1.0+  indexOffMem :: Prim e+    => mr -- ^ /memRead/ - Memory to read an element from+    -> Off e+    -- ^ /off/ - Offset in number of elements from the beginning of @memRead@+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= off+    --+    -- > unOffBytes off <= unCount (byteCountMem memRead - byteCountType @e)+    --+    -> e+  indexOffMem mr off = indexByteOffMem mr (toByteOff off)+  {-# INLINE indexOffMem #-}++  -- | Read an element with an offset in number of bytes. Bounds are not checked.+  --+  -- [Unsafe] When precondition for @off@ argument is violated the result is either+  -- unpredictable output or failure with a segfault.+  --+  -- @since 0.1.0+  indexByteOffMem :: Prim e+    => mr -- ^ /memRead/ - Memory to read an element from+    -> Off Word8+    -- ^ /off/ - Offset in number of elements from the beginning of @memRead@+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= unOff off+    --+    -- > unOff off <= unCount (byteCountMem memRead - byteCountType @e)+    --+    -> e++  -- | Copy contiguous chunk of memory from the read only memory into the target mutable+  -- `MBytes`. Source and target /must not/ refer to the same memory region, otherwise+  -- that would imply that the source is not immutable which would be a violation of some+  -- other invariant elsewhere in the code.+  --+  -- [Unsafe] When a precondition for either of the offsets @memSourceOff@, @memTargetOff@+  -- or the element count @memCount@ is violated the result is either unpredictable output or+  -- failure with a segfault.+  --+  -- @since 0.1.0+  copyByteOffToMBytesMem ::+       (MonadPrim s m, Prim e)+    => mr -- ^ /memSourceRead/ - Source from where to copy+    -> Off Word8+    -- ^ /memSourceOff/ - Offset into source memory in number of bytes+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memSourceOff+    --+    -- > unOff memSourceOff <= unCount (byteCountMem memSourceRead - byteCountType @e)+    -> MBytes p s -- ^ /memTargetWrite/ - Target mutable memory+    -> Off Word8+    -- ^ /memTargetOff/ -  Offset into target memory in number of bytes+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memTargetOff+    --+    -- > unOff memTargetOff <= unCount (byteCountMem memTargetWrite - byteCountType @e)+    -> Count e+    -- ^ /memCount/ - Number of elements of type __@e@__ to copy+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- > unCountBytes memCount + unOff memSourceOff <= unCount (byteCountMem memSourceRead - byteCountType @e)+    --+    -- > unCountBytes memCount + unOff memTargetOff <= unCount (byteCountMem memTargetRead - byteCountType @e)+    -> m ()++  -- | Copy contiguous chunk of memory from the read only memory into the target mutable+  -- `Ptr`. Source and target /must not/ refer to the same memory region, otherwise that+  -- would imply that the source is not immutable which would be a violation of some other+  -- invariant elsewhere in the code.+  --+  -- [Unsafe] When any precondition for one of the offsets @memSourceOff@, @memTargetOff@+  -- or the element count @memCount@ is violated a call to this function can result in:+  -- copy of data that doesn't belong to @memSourceRead@, heap corruption or failure with+  -- a segfault.+  --+  --+  -- @since 0.1.0+  copyByteOffToPtrMem ::+       (MonadPrim s m, Prim e)+    => mr -- ^ /memSourceRead/ - Source from where to copy+    -> Off Word8+    -- ^ /memSourceOff/ - Offset into source memory in number of bytes+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memSourceOff+    --+    -- > unOff memSourceOff <= unCount (byteCountMem memSourceRead - byteCountType @e)+    -> Ptr e+    -- ^ /memTargetWrite/ - Pointer to the target mutable memory+    --+    -- /__Preconditions:__/+    --+    -- Once the pointer is advanced by @memTargetOff@ the next @unCountBytes memCount@ bytes must+    -- still belong to the same region of memory @memTargetWrite@+    -> Off Word8+    -- ^ /memTargetOff/ - Number of bytes to advance the pointer @memTargetWrite@ forward+    --+    -- /__Precondition:__/+    --+    -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same+    -- memory region @memTargetWrite@+    -> Count e+    -- ^ /memCount/ - Number of elements of type __@e@__ to copy+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- > unCountBytes memCount + unOff memSourceOff <= unCount (byteCountMem memSourceRead - byteCountType @e)+    -> m ()++  -- | Same as `compareByteOffMem`, but compare the read-only+  -- memory region to a region addressed by a `Ptr` inside of a `MonadPrim`.+  --+  -- [Unsafe] When any precondition for either of the offsets @memOff1@, @memOff2@, the+  -- pointer @memRead2@ or the element count @memCount@ is violated the result is either+  -- unpredictable output or failure with a segfault.+  --+  -- @since 0.1.0+  compareByteOffToPtrMem ::+       (MonadPrim s m, Prim e)+    => mr -- ^ /memRead1/ - First memory region+    -> Off Word8+    -- ^ /memOff1/ - Offset for @memRead1@ in number of bytes+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memOff1+    --+    -- > unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)+    -> Ptr e+    -- ^ /memRead2/- Second memory region that can be accessed by a pointer+    --+    -- /__Preconditions__/+    --+    -- Once the pointer is advanced by @memOff2@ the next @unCountBytes memCount@ bytes must+    -- still belong to the same region of memory @memRead2@+    -> Off Word8+    -- ^ /memOff2/ - Number of bytes to advance the pointer @memRead2@ forward+    --+    -- /__Precondition:__/+    --+    -- Once the pointer is advanced by @memOff2@ it must still refer to the same memory+    -- region @memRead2@+    -> Count e -- ^ /memCount/ - Number of elements of type __@e@__ to compare as binary+    -- ^ /memCount/ - Number of elements of type __@e@__ to compare as binary+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- > unCountBytes memCount + unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)+    -> m Ordering++  -- | Same as `compareByteOffMem`, but compare the read-only memory region to `Bytes`.+  --+  -- [Unsafe] When any precondition for either of the offsets @memOff1@, @memOff2@ or the+  -- element count @memCount@ is violated the result is either unpredictable output or+  -- failure with a segfault.+  --+  -- @since 0.1.0+  compareByteOffToBytesMem ::+       Prim e+    => mr -- ^ /memRead1/ - First memory region+    -> Off Word8+    -- ^ /memOff1/ - Offset for @memRead1@ in number of bytes+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memOff1+    --+    -- > unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)+    -> Bytes p -- ^ /memRead2/- Second memory region that is backed by `Bytes`+    -> Off Word8+    -- ^ /memOff2/ - Offset for @memRead2@ in number of bytes+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memOff2+    --+    -- > unOff memOff2 <= unCount (byteCountMem memRead2 - byteCountType @e)+    -> Count e+    -- ^ /memCount/ - Number of elements of type __@e@__ to compare as binary+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- > unCountBytes memCount + unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)+    --+    -- > unCountBytes memCount + unOff memOff2 <= unCount (byteCountMem memRead2 - byteCountType @e)+    -> Ordering++  -- | Compare two read-only regions of memory byte-by-byte. The very first mismatched+  -- byte will cause this function to produce `LT` if the byte in @memRead1@ is smaller+  -- than the one in @memRead2@ and `GT` if it is bigger. It is not a requirement to+  -- short-circuit on the first mismatch, but it is a good optimization to have for+  -- non-sensitive data. Memory regions that store security critical data may choose to+  -- implement this function to work in constant time.+  --+  -- This function is usually implemented by either one of `compareByteOffToPtrMem` or+  -- `compareByteOffToBytesMem`, depending on the nature of @mr@ type. However it differs+  -- from the aforementioned functions with a fact that it is pure non-monadic+  -- computation.+  --+  -- [Unsafe] When any precondition for either of the offsets @memOff1@, @memOff2@ or the+  -- element count @memCount@ is violated the result is either unpredictable output or+  -- failure with a segfault.+  --+  -- @since 0.1.0+  compareByteOffMem ::+       (MemRead mr', Prim e)+    => mr' -- ^ /memRead1/ - First memory region+    -> Off Word8+    -- ^ /memOff1/ - Offset for @memRead1@ in number of bytes+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memOff1+    --+    -- > unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)+    -> mr -- ^ /memRead2/ - Second memory region+    -> Off Word8+    -- ^ /memOff2/ - Offset for @memRead2@ in number of bytes+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memOff2+    --+    -- > unOff memOff2 <= unCount (byteCountMem memRead2 - byteCountType @e)+    -> Count e+    -- ^ /memCount/ - Number of elements of type __@e@__ to compare as binary+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- > unCountBytes memCount + unOff memOff1 <= unCount (byteCountMem memRead1 - byteCountType @e)+    --+    -- > unCountBytes memCount + unOff memOff2 <= unCount (byteCountMem memRead2 - byteCountType @e)+    -> Ordering++-- | Type class that can be implemented for a mutable data type that provides direct read+-- and write access to memory+class MemWrite mw where++  -- | Check if two mutable regions refer to the exact same region of memory+  --+  -- @since 0.3.0+  isSameMutMem :: mw s -> mw s -> Bool++  -- | Read an element with an offset in number of elements, rather than bytes as it is+  -- the case with `readByteOffMutMem`.+  --+  -- [Unsafe] Bounds are not checked. When precondition for @off@ argument is violated the+  -- result is either unpredictable output or failure with a segfault.+  --+  -- @since 0.3.0+  readOffMutMem :: (MonadPrim s m, Prim e)+    => mw s -- ^ /memRead/ - Memory region to read an element from+    -> Off e+    -- ^ /off/ - Offset in number of elements from the beginning of @memRead@+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= off+    --+    -- With offset applied it should still refer to the same memory region. For types that+    -- also implement `MemAlloc` this can be described as:+    --+    -- > count <- getByteCountMutMem memRead+    -- > unOff (toByteOff off) <= unCount (count - byteCountType @e)+    --+    -> m e+  readOffMutMem mw off = readByteOffMutMem mw (toByteOff off)+  {-# INLINE readOffMutMem #-}++  -- | Read an element with an offset in number of bytes.+  --+  -- [Unsafe] Bounds are not checked. When precondition for @off@ argument is violated the+  -- result is either unpredictable output or failure with a segfault.+  --+  -- @since 0.3.0+  readByteOffMutMem :: (MonadPrim s m, Prim e)+    => mw s -- ^ /memRead/ - Memory region to read an element from+    -> Off Word8+    -- ^ /off/ - Offset in number of elements from the beginning of @memRead@+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= off+    --+    -- With offset applied it should still refer to the same memory region. For types that+    -- also implement `MemAlloc` this can be described as:+    --+    -- > count <- getByteCountMutMem memRead+    -- > unOff (toByteOff off) <= unCount (count - byteCountType @e)+    --+    -> m e++  -- | Write an element with an offset in number of elements, rather than bytes as it is+  -- the case with `writeByteOffMutMem`.+  --+  -- [Unsafe] Bounds are not checked. When precondition for @off@ argument is violated the+  -- outcome is either heap corruption or failure with a segfault.+  --+  -- @since 0.3.0+  writeOffMutMem :: (MonadPrim s m, Prim e)+    => mw s -- ^ /memWrite/ - Memory region to write an element into+    -> Off e+    -- ^ /off/ - Offset in number of elements from the beginning of @memWrite@+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= off+    --+    -- With offset applied it should still refer to the same memory region. For types that+    -- also implement `MemAlloc` this can be described as:+    --+    -- > count <- getByteCountMutMem memWrite+    -- > unOff (toByteOff off) <= unCount (count - byteCountType @e)+    --+    -> e -- ^ /elt/ - Element to write+    -> m ()+  writeOffMutMem mw off = writeByteOffMutMem mw (toByteOff off)+  {-# INLINE writeOffMutMem #-}++  -- | Write an element with an offset in number of bytes.+  --+  -- [Unsafe] Bounds are not checked. When precondition for @off@ argument is violated the+  -- outcome is either heap corruption or failure with a segfault.+  --+  -- @since 0.3.0+  writeByteOffMutMem :: (MonadPrim s m, Prim e)+    => mw s -- ^ /memWrite/ - Memory region to write an element into+    -> Off Word8+    -- ^ /off/ - Offset in number of elements from the beginning of @memWrite@+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= off+    --+    -- With offset applied it should still refer to the same memory region. For types that+    -- also implement `MemAlloc` this can be described as:+    --+    -- > count <- getByteCountMutMem memWrite+    -- > unOff (toByteOff off) <= unCount (count - byteCountType @e)+    --+    -> e -> m ()++  -- | Copy contiguous chunk of memory from the source mutable memory into the target+  -- mutable `MBytes`. Source and target /may/ refer to overlapping memory regions.+  --+  -- [Unsafe] When any precondition for one of the offsets @memSourceOff@, @memTargetOff@+  -- or the element count @memCount@ is violated a call to this function can result in:+  -- copy of data that doesn't belong to @memSource@, heap corruption or failure with+  -- a segfault.+  --+  -- @since 0.3.0+  moveByteOffToMBytesMutMem ::+    (MonadPrim s m, Prim e)+    => mw s -- ^ /memSource/ - Source memory from where to copy+    -> Off Word8+    -- ^ /memSourceOff/ - Offset in number of bytes into source memory+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memSourceOff+    --+    -- With offset applied it should still refer to the same memory region. For types that+    -- also implement `MemAlloc` this can be described as:+    --+    -- > sourceByteCount <- getByteCountMutMem memSource+    -- > unOff (toByteOff memSourceOff) <= unCount (sourceByteCount - byteCountType @e)+    -> MBytes p s -- ^ /memTarget/ - Target memory into where to copy+    -> Off Word8+    -- ^ /memTargetOff/ - Offset in number of bytes into target memory where writing will start+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memTargetOff+    --+    -- With offset applied it should still refer to the same memory region. For types that+    -- also implement `MemAlloc` this can be described as:+    --+    -- > targetByteCount <- getByteCountMutMem memTarget+    -- > unOffBytes memTargetOff <= unCount (targetByteCount - byteCountType @e)+    -> Count e+    -- ^ /memCount/ - Number of elements of type __@e@__ to copy+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- Both source and target memory regions must have enough memory to perform a copy+    -- of @memCount@ elements starting at their respective offsets. For types that also+    -- implement `MemAlloc` this can be described as:+    --+    -- > sourceByteCount <- getByteCountMutMem memSource+    -- > unOff memSourceOff + unCountBytes memCount <= unCount (sourceByteCount - byteCountType @e)+    --+    -- > targetByteCount <- getByteCountMutMem memTarget+    -- > unOff memTargetOff + unCountBytes memCount <= unCount (targetByteCount - byteCountType @e)+    -> m ()++  -- | Copy contiguous chunk of memory from the source mutable memory into the target+  -- `Ptr`. Source and target /may/ refer to overlapping memory regions.+  --+  -- [Unsafe] When any precondition for one of the offsets @memSourceOff@ or+  -- @memTargetOff@, a target pointer @memTarget@ or the element count @memCount@ is+  -- violated a call to this function can result in: copy of data that doesn't belong to+  -- @memSource@, heap corruption or failure with a segfault.+  --+  -- @since 0.3.0+  moveByteOffToPtrMutMem ::+    (MonadPrim s m, Prim e)+    => mw s -- ^ /memSource/ - Source memory from where to copy+    -> Off Word8+    -- ^ /memSourceOff/ - Offset in number of bytes into source memory+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memSourceOff+    --+    -- With offset applied it should still refer to the same memory region. For types that+    -- also implement `MemAlloc` this can be described as:+    --+    -- > sourceByteCount <- getByteCountMutMem memSource+    -- > unOff (toByteOff memSourceOff) <= unCount (sourceByteCount - byteCountType @e)+    -> Ptr e+    -- ^ /memTarget/ - Target memory into where to copy+    --+    -- /__Precondition:__/+    --+    -- Once the pointer is advanced by @memTargetOff@ the next @unCountBytes memCount@ bytes must+    -- still belong to the same region of memory @memTargetWrite@+    -> Off Word8+    -- ^ /memTargetOff/ - Offset in number of bytes into target memory where writing will start+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memTargetOff+    --+    -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same+    -- memory region @memTarget@+    -> Count e+    -- ^ /memCount/ - Number of elements of type __@e@__ to copy+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- Both source and target memory regions must have enough memory to perform a copy+    -- of @memCount@ elements starting at their respective offsets. For /memSource/ that also+    -- implements `MemAlloc` this can be described as:+    --+    -- > sourceByteCount <- getByteCountMutMem memSource+    -- > unOff memSourceOff + unCountBytes memCount <= unCount (sourceByteCount - byteCountType @e)+    -> m ()++  -- | Copy contiguous chunk of memory from the read only memory region into the target+  -- mutable memory region. Source and target /must not/ refer to the same memory region,+  -- otherwise that would imply that the source is not immutable which would be a+  -- violation of some other invariant elsewhere in the code.+  --+  -- [Unsafe] When any precondition for one of the offsets @memSourceOff@, @memTargetOff@+  -- or the element count @memCount@ is violated a call to this function can result in:+  -- copy of data that doesn't belong to @memSourceRead@, heap corruption or failure with+  -- a segfault.+  --+  -- @since 0.1.0+  copyByteOffMem :: (MonadPrim s m, MemRead mr, Prim e)+    => mr -- ^ /memSourceRead/ - Read-only source memory region from where to copy+    -> Off Word8+    -- ^ /memSourceOff/ - Offset into source memory in number of bytes+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memSourceOff+    --+    -- > unOff memSourceOff <= unCount (byteCountMem memSourceRead - byteCountType @e)+    -> mw s -- ^ /memTargetWrite/ - Target mutable memory+    -> Off Word8+    -- ^ /memTargetOff/ -  Offset into target memory in number of bytes+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memTargetOff+    --+    -- With offset applied it should still refer to the same memory region. For types that+    -- also implement `MemAlloc` this can be described as:+    --+    -- > targetByteCount <- getByteCountMutMem memTargetWrite+    -- > unOffBytes memTargetOff <= unCount (targetByteCount - byteCountType @e)+    -> Count e+    -- ^ /memCount/ - Number of elements of type __@e@__ to copy+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- Both source and target memory regions must have enough memory to perform a copy+    -- of @memCount@ elements starting at their respective offsets. For @memSourceRead@:+    --+    -- > unOff memSourceOff + unCountBytes memCount <= unCount (byteCountMem memSourceRead - byteCountType @e)+    --+    -- and for @memTargetWrite@ that also implements `MemAlloc` this can be described as:+    --+    -- > targetByteCount <- getByteCountMutMem memTargetWrite+    -- > unOff memTargetOff + unCountBytes memCount <= unCount (targetByteCount - byteCountType @e)+    -> m ()++  -- | Copy contiguous chunk of memory from a mutable memory region into the target+  -- mutable memory region. Source and target /may/ refer to the same memory region.+  --+  -- [Unsafe] When any precondition for one of the offsets @memSourceOff@, @memTargetOff@+  -- or the element count @memCount@ is violated a call to this function can result in:+  -- copy of data that doesn't belong to @memSourceRead@, heap corruption or failure with+  -- a segfault.+  --+  -- @since 0.3.0+  moveByteOffMutMem :: (MonadPrim s m, MemWrite mw', Prim e)+    => mw' s -- ^ /memSource/ - Source memory from where to copy+    -> Off Word8+    -- ^ /memSourceOff/ - Offset in number of bytes into source memory+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memSourceOff+    --+    -- With offset applied it should still refer to the same memory region. For types that+    -- also implement `MemAlloc` this can be described as:+    --+    -- > sourceByteCount <- getByteCountMutMem memSource+    -- > unOffBytes memSourceOff <= unCount (sourceByteCount - byteCountType @e)+    -> mw s -- ^ /memTarget/ - Target memory into where to copy+    -> Off Word8+    -- ^ /memTargetOff/ -  Offset into target memory in number of bytes+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memTargetOff+    --+    -- With offset applied it should still refer to the same memory region. For types that+    -- also implement `MemAlloc` this can be described as:+    --+    -- > targetByteCount <- getByteCountMutMem memTarget+    -- > unOffBytes (toByteOff memTargetOff) <= unCount (targetByteCount - byteCountType @e)+    -> Count e+    -- ^ /memCount/ - Number of elements of type __@e@__ to copy+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- Both source and target memory regions must have enough memory to perform a copy+    -- of @memCount@ elements starting at their respective offsets. For types that also+    -- implement `MemAlloc` this can be described as:+    --+    -- > sourceByteCount <- getByteCountMutMem memSource+    -- > unOff memSourceOff + unCountBytes memCount <= unCount (sourceByteCount - byteCountType @e)+    --+    -- > targetByteCount <- getByteCountMutMem memTarget+    -- > unOff memTargetOff + unCountBytes memCount <= unCount (targetByteCount - byteCountType @e)+    -> m ()++  -- TODO: Potential feature for the future implementation. Will require extra function in `Prim`.+  --setByteOffMutMem :: (MonadPrim s m, Prim e) => w s -> Off Word8 -> Count e -> e -> m ()++  -- | Write the same value @memCount@ times into each cell of @memTarget@ starting at an+  -- offset @memTargetOff@.+  --+  -- [Unsafe] Bounds are not checked. When precondition for @memTargetOff@ argument is+  -- violated the outcome is either heap corruption or failure with a segfault.+  --+  -- @since 0.3.0+  setMutMem+    :: (MonadPrim s m, Prim e)+    => mw s -- ^ /memTarget/ - Target memory into where to write the element+    -> Off e+    -- ^ /memTargetOff/ - Offset into target memory in number of elements at which element+    -- setting should start.+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memTargetOff+    --+    -- With offset applied it should still refer to the same memory region. For types that+    -- also implement `MemAlloc` this can be described as:+    --+    -- > targetByteCount <- getByteCountMutMem memTarget+    -- > unOffBytes memTargetOff <= unCount (targetByteCount - byteCountType @e)+    -> Count e+    -- ^ /memCount/ - Number of times the element @elt@ should be written+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- Target memory region should have enough memory to perform a set operation of the+    -- supplied element @memCount@ number of times starting at the supplied offset. For+    -- types that also implement `MemAlloc` this can be described as:+    --+    -- > targetByteCount <- getByteCountMutMem memTarget+    -- > unCountBytes memCount + unOff memTargetOff <= unCount (targetByteCount - byteCountType @e)+    -> e+    -- ^ /elt/ - Element to write into memory cells. This function is strict with+    -- respect to element, which means that the even @memCount = 0@ it might be still+    -- fully evaluated.+    -> m ()++-- | Generalized memory allocation and pure/mutable state conversion.+class (MemRead (FrozenMem ma), MemWrite ma) => MemAlloc ma where+  -- | Memory region in the immutable state. Types for frozen and thawed states of+  -- memory region are in one-to-one correspondence, therefore @ma <-> FrozeMem ma@ will+  -- always uniquely identify each other, which is an extremely useful property when it+  -- comes to type inference.+  type FrozenMem ma = (fm :: Type) | fm -> ma++  -- | Extract the number of bytes a mutable memory region can hold, i.e. what is the+  -- total allocated size for this region. The size of a region can be changes and in some+  -- circuimstances even in place without copy, see `reallocMutMem` for more info.+  --+  -- ====__Examples__+  --+  -- >>> m <- allocMutMem (10 :: Count Int64) :: IO (MBytes 'Pin RW)+  -- >>> getByteCountMutMem m+  -- Count {unCount = 80}+  --+  -- @since 0.3.0+  getByteCountMutMem :: MonadPrim s m => ma s -> m (Count Word8)++  -- | Allocate a mutable memory region for specified number of elements. Memory is not+  -- reset and will likely hold some garbage data, therefore prefer to use `allocZeroMutMem`,+  -- unless it is guaranteed that all of allocated memory will be overwritten.+  --+  -- [Unsafe] When any of preconditions for @memCount@ argument is violated the outcome is+  -- unpredictable. One possible outcome is termination with+  -- `Control.Exception.HeapOverflow` async exception. In a pure setting, such as when+  -- executed within `runST`, if allocated memory is not fully overwritten it can lead to+  -- violation of referential transparency, because contents of newly allocated region is+  -- non-determinstic.+  --+  -- @since 0.3.0+  allocMutMem :: (Prim e, MonadPrim s m)+    => Count e+    -- ^ /memCount/ - Amount of memory to allocate for the region in number of elements of+    -- type __@e@__+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- Possibility of overflow:+    --+    -- > memCount <= fromByteCount maxBound+    --+    -- When converted to bytes the value should be less then available physical memory+    -> m (ma s)++  -- | Convert the state of an immutable memory region to the mutable one. This is a no+  -- copy operation, as such it is fast, but dangerous. See `thawCloneMutMem` for a safe+  -- alternative.+  --+  -- [Unsafe] This function makes it possible to break referential transparency, because+  -- any subsequent destructive operation to the mutable region of memory will also be+  -- reflected in the frozen immutable type as well.+  --+  -- @since 0.1.0+  thawMem :: MonadPrim s m => FrozenMem ma -> m (ma s)++  -- | Convert the state of a mutable memory region to the immutable one. This is a no+  -- copy operation, as such it is fast, but dangerous. See `freezeCopyMem` for a safe alternative.+  --+  -- [Unsafe] It makes it possible to break referential transparency, because any+  -- subsequent destructive operation to the mutable region of memory will also be+  -- reflected in the frozen immutable type as well.+  --+  -- @since 0.3.0+  freezeMutMem :: MonadPrim s m => ma s -> m (FrozenMem ma)++  -- | Either grow or shrink currently allocated mutable region of memory. For some+  -- implementations it might be possible to change the size of the allocated region+  -- in-place, i.e. without copy. However in all implementations there is a good chance+  -- that the memory region has to be allocated anew, in which case all of the contents+  -- up to the minimum of new and old sizes will get copied over. After the resize+  -- operation is complete the supplied @memSource@ region must not be used+  -- anymore. Moreover, no reference to the old one should be kept in order to allow+  -- garbage collection of the original in case a new one had to be allocated.+  --+  -- Default implementation is `defaultReallocMutMem`+  --+  -- [Unsafe] Undefined behavior when @memSource@ is used afterwards. The same unsafety+  -- notice from `allocMutMem` with regards to @memCount@ is applicable here as well.+  --+  -- @since 0.3.0+  reallocMutMem :: (MonadPrim s m, Prim e)+    => ma s+    -- ^ /memSource/ - Source memory region to resize+    -> Count e+    -- ^ /memCount/ - Number of elements for the reallocated memory region+    --+    -- /__Preconditions:__/+    --+    -- > 0 <= memCount+    --+    -- Should be less then available physical memory+    -> m (ma s)+  reallocMutMem = defaultReallocMutMem+  {-# INLINE reallocMutMem #-}++instance MemRead (UArray e) where+  isSameMem = isSameUArray+  {-# INLINE isSameMem #-}+  byteCountMem = byteCountMem . fromUArrayBytes+  {-# INLINE byteCountMem #-}+  indexOffMem a = indexOffMem (fromUArrayBytes a)+  {-# INLINE indexOffMem #-}+  indexByteOffMem a = indexByteOffMem (fromUArrayBytes a)+  {-# INLINE indexByteOffMem #-}+  copyByteOffToMBytesMem a = copyByteOffToMBytesMem (fromUArrayBytes a)+  {-# INLINE copyByteOffToMBytesMem #-}+  copyByteOffToPtrMem a = copyByteOffToPtrMem (fromUArrayBytes a)+  {-# INLINE copyByteOffToPtrMem #-}+  compareByteOffToPtrMem a = compareByteOffToPtrMem (fromUArrayBytes a)+  {-# INLINE compareByteOffToPtrMem #-}+  compareByteOffToBytesMem a = compareByteOffToBytesMem (fromUArrayBytes a)+  {-# INLINE compareByteOffToBytesMem #-}+  compareByteOffMem mem1 off1 a = compareByteOffMem mem1 off1 (fromUArrayBytes a)+  {-# INLINE compareByteOffMem #-}++instance MemWrite (UMArray e) where+  isSameMutMem = isSameUMArray+  {-# INLINE isSameMutMem #-}+  readOffMutMem ma = readOffMutMem (fromUMArrayMBytes ma)+  {-# INLINE readOffMutMem #-}+  readByteOffMutMem ma = readByteOffMutMem (fromUMArrayMBytes ma)+  {-# INLINE readByteOffMutMem #-}+  writeOffMutMem ma = writeOffMutMem (fromUMArrayMBytes ma)+  {-# INLINE writeOffMutMem #-}+  writeByteOffMutMem ma = writeByteOffMutMem (fromUMArrayMBytes ma)+  {-# INLINE writeByteOffMutMem #-}+  moveByteOffToPtrMutMem ma = moveByteOffToPtrMutMem (fromUMArrayMBytes ma)+  {-# INLINE moveByteOffToPtrMutMem #-}+  moveByteOffToMBytesMutMem ma = moveByteOffToMBytesMutMem (fromUMArrayMBytes ma)+  {-# INLINE moveByteOffToMBytesMutMem #-}+  copyByteOffMem src srcOff ma = copyByteOffMem src srcOff (fromUMArrayMBytes ma)+  {-# INLINE copyByteOffMem #-}+  moveByteOffMutMem src srcOff ma = moveByteOffMutMem src srcOff (fromUMArrayMBytes ma)+  {-# INLINE moveByteOffMutMem #-}+  setMutMem ma = setMutMem (fromUMArrayMBytes ma)+  {-# INLINE setMutMem #-}++instance MemAlloc (UMArray e) where+  type FrozenMem (UMArray e) = UArray e+  getByteCountMutMem = getByteCountMutMem . fromUMArrayMBytes+  {-# INLINE getByteCountMutMem #-}+  allocMutMem = fmap toUMArrayMBytes . allocUnpinnedMBytes+  {-# INLINE allocMutMem #-}+  thawMem = fmap toUMArrayMBytes . thawBytes . fromUArrayBytes+  {-# INLINE thawMem #-}+  freezeMutMem = fmap toUArrayBytes . freezeMBytes . fromUMArrayMBytes+  {-# INLINE freezeMutMem #-}+  reallocMutMem ma = fmap toUMArrayMBytes . reallocMBytes (fromUMArrayMBytes ma)+  {-# INLINE reallocMutMem #-}+++instance MemRead ByteString where+  isSameMem bs1 bs2 =+    unsafeInlineIO $+    withPtrAccess bs1 $ \ptr1 ->+      withPtrAccess bs2 $ \ptr2 -> -- Can refer to the same memory but sliced differently:+        pure (ptr1 == (ptr2 :: Ptr Word8) && BS.length bs1 == BS.length bs2)+  {-# INLINE isSameMem #-}+  byteCountMem = Count . BS.length+  {-# INLINE byteCountMem #-}+  indexOffMem bs i = unsafeInlineIO $ withPtrAccess bs (`readOffPtr` i)+  {-# INLINE indexOffMem #-}+  indexByteOffMem bs i = unsafeInlineIO $ withPtrAccess bs (`readByteOffPtr` i)+  {-# INLINE indexByteOffMem #-}+  copyByteOffToMBytesMem bs srcOff mb dstOff c =+    withPtrAccess bs $ \srcPtr ->+      copyByteOffPtrToMBytes srcPtr srcOff mb dstOff c+  {-# INLINE copyByteOffToMBytesMem #-}+  copyByteOffToPtrMem bs srcOff dstPtr dstOff c =+    withPtrAccess bs $ \srcPtr ->+      copyByteOffPtrToPtr srcPtr srcOff dstPtr dstOff c+  {-# INLINE copyByteOffToPtrMem #-}+  compareByteOffToPtrMem bs off1 ptr2 off2 c =+    withPtrAccess bs $ \ptr1 ->+      pure $! compareByteOffPtrToPtr ptr1 off1 ptr2 off2 c+  {-# INLINE compareByteOffToPtrMem #-}+  compareByteOffToBytesMem bs off1 bytes off2 c =+    unsafeInlineIO $+    withPtrAccess bs $ \ptr1 ->+      pure $! compareByteOffPtrToBytes ptr1 off1 bytes off2 c+  {-# INLINE compareByteOffToBytesMem #-}+  compareByteOffMem mem1 off1 bs off2 c =+    unsafeInlineIO $+    withPtrAccess bs $ \ptr2 -> compareByteOffToPtrMem mem1 off1 ptr2 off2 c+  {-# INLINE compareByteOffMem #-}++instance MemWrite MByteString where+  isSameMutMem (MByteString bs1) (MByteString bs2) = isSameMem bs1 bs2+  {-# INLINE isSameMutMem #-}+  readOffMutMem (MByteString mbs) i = withPtrAccess mbs (`readOffPtr` i)+  {-# INLINE readOffMutMem #-}+  readByteOffMutMem (MByteString mbs) i = withPtrAccess mbs (`readByteOffPtr` i)+  {-# INLINE readByteOffMutMem #-}+  writeOffMutMem (MByteString mbs) i a = withPtrAccess mbs $ \ptr -> writeOffPtr ptr i a+  {-# INLINE writeOffMutMem #-}+  writeByteOffMutMem (MByteString mbs) i a = withPtrAccess mbs $ \ptr -> writeByteOffPtr ptr i a+  {-# INLINE writeByteOffMutMem #-}+  moveByteOffToPtrMutMem (MByteString fsrc) srcOff dstPtr dstOff c =+    withPtrAccess fsrc $ \srcPtr -> moveByteOffPtrToPtr srcPtr srcOff dstPtr dstOff c+  {-# INLINE moveByteOffToPtrMutMem #-}+  moveByteOffToMBytesMutMem (MByteString fsrc) srcOff dst dstOff c =+    withPtrAccess fsrc $ \srcPtr -> moveByteOffPtrToMBytes srcPtr srcOff dst dstOff c+  {-# INLINE moveByteOffToMBytesMutMem #-}+  copyByteOffMem src srcOff (MByteString fdst) dstOff c =+    withPtrAccess fdst $ \dstPtr -> copyByteOffToPtrMem src srcOff dstPtr dstOff c+  {-# INLINE copyByteOffMem #-}+  moveByteOffMutMem src srcOff (MByteString fdst) dstOff c =+    withPtrAccess fdst $ \dstPtr -> moveByteOffToPtrMutMem src srcOff dstPtr dstOff c+  {-# INLINE moveByteOffMutMem #-}+  setMutMem (MByteString mbs) off c a = withPtrAccess mbs $ \ptr -> setOffPtr ptr off c a+  {-# INLINE setMutMem #-}++instance MemAlloc MByteString where+  type FrozenMem MByteString = ByteString+  getByteCountMutMem (MByteString bs) = pure $! Count (BS.length bs)+  {-# INLINE getByteCountMutMem #-}+  allocMutMem c = do+    let cb = toByteCount c+    fp <- mallocByteCountPlainForeignPtr cb+    pure $ MByteString (PS fp 0 (coerce cb))+  {-# INLINE allocMutMem #-}+  thawMem bs = pure $ MByteString bs+  {-# INLINE thawMem #-}+  freezeMutMem (MByteString bs) = pure bs+  {-# INLINE freezeMutMem #-}+  reallocMutMem bsm@(MByteString (PS fp o n)) newc+    | newn > n = defaultReallocMutMem bsm newc+    | otherwise = pure $ MByteString (PS fp o newn)+    where -- constant time slice if we need to reduce the size+      Count newn = toByteCount newc+  {-# INLINE reallocMutMem #-}+++instance MemRead T.Array where+  isSameMem a1 a2 = isSameMem (T.fromArrayBytes a1) (T.fromArrayBytes a2)+  {-# INLINE isSameMem #-}+  byteCountMem = byteCountMem . T.fromArrayBytes+  {-# INLINE byteCountMem #-}+  indexOffMem a = indexOffMem (T.fromArrayBytes a)+  {-# INLINE indexOffMem #-}+  indexByteOffMem a = indexByteOffMem (T.fromArrayBytes a)+  {-# INLINE indexByteOffMem #-}+  copyByteOffToMBytesMem a = copyByteOffToMBytesMem (T.fromArrayBytes a)+  {-# INLINE copyByteOffToMBytesMem #-}+  copyByteOffToPtrMem a = copyByteOffToPtrMem (T.fromArrayBytes a)+  {-# INLINE copyByteOffToPtrMem #-}+  compareByteOffToPtrMem a = compareByteOffToPtrMem (T.fromArrayBytes a)+  {-# INLINE compareByteOffToPtrMem #-}+  compareByteOffToBytesMem a = compareByteOffToBytesMem (T.fromArrayBytes a)+  {-# INLINE compareByteOffToBytesMem #-}+  compareByteOffMem mem off1 a = compareByteOffMem mem off1 (T.fromArrayBytes a)+  {-# INLINE compareByteOffMem #-}++instance MemAlloc T.MArray where+  type FrozenMem T.MArray = T.Array+  getByteCountMutMem = getByteCountMBytes . T.fromMArrayMBytes+  {-# INLINE getByteCountMutMem #-}+  allocMutMem = fmap T.toMArrayMBytes . allocUnpinnedMBytes+  {-# INLINE allocMutMem #-}+  thawMem = fmap T.toMArrayMBytes . thawBytes . T.fromArrayBytes+  {-# INLINE thawMem #-}+  freezeMutMem = fmap T.toArrayBytes . freezeMBytes . T.fromMArrayMBytes+  {-# INLINE freezeMutMem #-}+  reallocMutMem m = fmap T.toMArrayMBytes . reallocMBytes (T.fromMArrayMBytes m)+  {-# INLINE reallocMutMem #-}++instance MemWrite T.MArray where+  isSameMutMem ma1 ma2 = isSameMutMem (T.fromMArrayMBytes ma1) (T.fromMArrayMBytes ma2)+  {-# INLINE isSameMutMem #-}+  readOffMutMem m = readOffMBytes (T.fromMArrayMBytes m)+  {-# INLINE readOffMutMem #-}+  readByteOffMutMem m = readByteOffMBytes (T.fromMArrayMBytes m)+  {-# INLINE readByteOffMutMem #-}+  writeOffMutMem m = writeOffMBytes (T.fromMArrayMBytes m)+  {-# INLINE writeOffMutMem #-}+  writeByteOffMutMem m = writeByteOffMBytes (T.fromMArrayMBytes m)+  {-# INLINE writeByteOffMutMem #-}+  moveByteOffToPtrMutMem m = moveByteOffMBytesToPtr (T.fromMArrayMBytes m)+  {-# INLINE moveByteOffToPtrMutMem #-}+  moveByteOffToMBytesMutMem m = moveByteOffMBytesToMBytes (T.fromMArrayMBytes m)+  {-# INLINE moveByteOffToMBytesMutMem #-}+  moveByteOffMutMem src srcOff m = moveByteOffToMBytesMutMem src srcOff (T.fromMArrayMBytes m)+  {-# INLINE moveByteOffMutMem #-}+  copyByteOffMem src srcOff m = copyByteOffToMBytesMem src srcOff (T.fromMArrayMBytes m)+  {-# INLINE copyByteOffMem #-}+  setMutMem m = setMBytes (T.fromMArrayMBytes m)+  {-# INLINE setMutMem #-}++instance MemRead T.Text where+  isSameMem (T.Text a1 o1 n1) (T.Text a2 o2 n2) = isSameMem a1 a2 && o1 == o2 && n1 == n2+  {-# INLINE isSameMem #-}+  byteCountMem (T.Text _ _ n) = toByteCount (Count n :: Count Word16)+  {-# INLINE byteCountMem #-}+  indexByteOffMem (T.Text a o _) i = indexByteOffMem a (toByteOff (Off o :: Off Word16) + i)+  {-# INLINE indexByteOffMem #-}+  copyByteOffToMBytesMem (T.Text a o _) i =+    copyByteOffToMBytesMem a (toByteOff (Off o :: Off Word16) + i)+  {-# INLINE copyByteOffToMBytesMem #-}+  copyByteOffToPtrMem (T.Text a o _) i =+    copyByteOffToPtrMem a (toByteOff (Off o :: Off Word16) + i)+  {-# INLINE copyByteOffToPtrMem #-}+  compareByteOffToPtrMem (T.Text a o _) off =+    compareByteOffToPtrMem a (toByteOff (Off o :: Off Word16) + off)+  {-# INLINE compareByteOffToPtrMem #-}+  compareByteOffToBytesMem (T.Text a o _) off =+    compareByteOffToBytesMem a (toByteOff (Off o :: Off Word16) + off)+  {-# INLINE compareByteOffToBytesMem #-}+  compareByteOffMem mem off1 (T.Text a o _) off2 =+    compareByteOffMem mem off1 a (toByteOff (Off o :: Off Word16) + off2)+  {-# INLINE compareByteOffMem #-}+++instance MemRead ShortByteString where+  isSameMem sbs1 sbs2 = isSameMem (fromShortByteStringBytes sbs1) (fromShortByteStringBytes sbs2)+  {-# INLINE isSameMem #-}+  byteCountMem = byteCountMem . fromShortByteStringBytes+  {-# INLINE byteCountMem #-}+  indexOffMem sbs = indexOffMem (fromShortByteStringBytes sbs)+  {-# INLINE indexOffMem #-}+  indexByteOffMem sbs = indexByteOffMem (fromShortByteStringBytes sbs)+  {-# INLINE indexByteOffMem #-}+  copyByteOffToMBytesMem sbs = copyByteOffToMBytesMem (fromShortByteStringBytes sbs)+  {-# INLINE copyByteOffToMBytesMem #-}+  copyByteOffToPtrMem sbs = copyByteOffToPtrMem (fromShortByteStringBytes sbs)+  {-# INLINE copyByteOffToPtrMem #-}+  compareByteOffToPtrMem sbs = compareByteOffToPtrMem (fromShortByteStringBytes sbs)+  {-# INLINE compareByteOffToPtrMem #-}+  compareByteOffToBytesMem sbs = compareByteOffToBytesMem (fromShortByteStringBytes sbs)+  {-# INLINE compareByteOffToBytesMem #-}+  compareByteOffMem mem off1 sbs = compareByteOffMem mem off1 (fromShortByteStringBytes sbs)+  {-# INLINE compareByteOffMem #-}++-- | A wrapper that adds a phantom state token. It can be used with types that either+-- don't have such state token or are designed to work in `IO` and therefore restricted+-- to `RealWorld`. Using this wrapper is very much unsafe, so make sure you know what you are+-- doing.+newtype MemState a s = MemState { unMemState :: a }++instance MemWrite (MemState (ForeignPtr a)) where+  isSameMutMem (MemState fptr1) (MemState fptr2) =+    unsafeInlineIO $+    withPtrAccess fptr1 $ \ptr1 ->+      withPtrAccess fptr2 $ \ptr2 ->+        pure (ptr1 == (ptr2 :: Ptr Word8))+  {-# INLINE isSameMutMem #-}+  readOffMutMem (MemState fptr) i = withForeignPtr fptr $ \ptr -> readOffPtr (castPtr ptr) i+  {-# INLINE readOffMutMem #-}+  readByteOffMutMem (MemState fptr) i =+    withForeignPtr fptr $ \ptr -> readByteOffPtr (castPtr ptr) i+  {-# INLINE readByteOffMutMem #-}+  writeOffMutMem (MemState fptr) i a = withForeignPtr fptr $ \ptr -> writeOffPtr (castPtr ptr) i a+  {-# INLINE writeOffMutMem #-}+  writeByteOffMutMem (MemState fptr) i a =+    withForeignPtr fptr $ \ptr -> writeByteOffPtr (castPtr ptr) i a+  {-# INLINE writeByteOffMutMem #-}+  moveByteOffToPtrMutMem (MemState fsrc) srcOff dstPtr dstOff c =+    withForeignPtr fsrc $ \srcPtr -> moveByteOffPtrToPtr (castPtr srcPtr) srcOff dstPtr dstOff c+  {-# INLINE moveByteOffToPtrMutMem #-}+  moveByteOffToMBytesMutMem (MemState fsrc) srcOff dst dstOff c =+    withForeignPtr fsrc $ \srcPtr -> moveByteOffPtrToMBytes (castPtr srcPtr) srcOff dst dstOff c+  {-# INLINE moveByteOffToMBytesMutMem #-}+  copyByteOffMem src srcOff (MemState fdst) dstOff c =+    withForeignPtr fdst $ \dstPtr ->+       copyByteOffToPtrMem src srcOff (castPtr dstPtr) dstOff c+  {-# INLINE copyByteOffMem #-}+  moveByteOffMutMem src srcOff (MemState fdst) dstOff c =+    withForeignPtr fdst $ \dstPtr ->+       moveByteOffToPtrMutMem src srcOff (castPtr dstPtr) dstOff c+  {-# INLINE moveByteOffMutMem #-}+  setMutMem (MemState fptr) off c a = withForeignPtr fptr $ \ptr -> setOffPtr (castPtr ptr) off c a+  {-# INLINE setMutMem #-}++--+-- @since 0.3.0+modifyFetchOldMutMem ::+     (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> e) -> m e+modifyFetchOldMutMem mem o f = modifyFetchOldMutMemM mem o (pure . f)+{-# INLINE modifyFetchOldMutMem #-}+++--+-- @since 0.3.0+modifyFetchNewMutMem ::+     (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> e) -> m e+modifyFetchNewMutMem mem o f = modifyFetchNewMutMemM mem o (pure . f)+{-# INLINE modifyFetchNewMutMem #-}+++--+-- @since 0.3.0+modifyFetchOldMutMemM ::+     (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> m e) -> m e+modifyFetchOldMutMemM mem o f = do+  a <- readOffMutMem mem o+  a <$ (writeOffMutMem mem o =<< f a)+{-# INLINE modifyFetchOldMutMemM #-}+++--+-- @since 0.3.0+modifyFetchNewMutMemM ::+     (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> m e) -> m e+modifyFetchNewMutMemM mem o f = do+  a <- readOffMutMem mem o+  a' <- f a+  a' <$ writeOffMutMem mem o a'+{-# INLINE modifyFetchNewMutMemM #-}++-- | An action that can be used as a default implementation for `reallocMutMem`. Whenever+-- current memory region byte count matches the supplied new size exactly then such memory+-- region is simply returned back and this function is a noop. Otherwise a new memory+-- region is allocated and all the data that can fit into the new region will be copied+-- over.+--+-- [Unsafe] Same unsafety notice as in `reallocMutMem`+--+-- @since 0.3.0+defaultReallocMutMem ::+     (Prim e, MemAlloc ma, MonadPrim s m) => ma s -> Count e -> m (ma s)+defaultReallocMutMem mem c = do+  let newByteCount = toByteCount c+  oldByteCount <- getByteCountMutMem mem+  if oldByteCount == newByteCount+    then pure mem+    else do+      newMem <- allocMutMem newByteCount+      oldMem <- freezeMutMem mem+      newMem <$ copyMem oldMem 0 newMem 0 (min oldByteCount newByteCount)+{-# INLINE defaultReallocMutMem #-}+++-- | Place @n@ copies of supplied region of memory one after another in a newly allocated+-- contiguous chunk of memory. Similar to `stimes`, but the source memory @memRead@ does+-- not have to match the type of `FrozenMem` ma.+--+-- ====__Example__+--+-- >>> :set -XTypeApplications+-- >>> :set -XDataKinds+-- >>> import Data.Prim.Memory+-- >>> let b = fromListMem @Word8 @(MBytes 'Inc) [0xde, 0xad, 0xbe, 0xef]+-- >>> cycleMemN @(MBytes 'Inc) 2 b+-- [0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef]+--+-- @since 0.1.0+cycleMemN ::+     forall ma mr. (MemAlloc ma, MemRead mr)+  => Int+  -> mr+  -> FrozenMem ma+cycleMemN n r+  | n <= 0 = emptyMem+  | otherwise =+    runST $ do+      let bc@(Count chunk) = byteCountMem r+          c@(Count c8) = Count n * bc+      mem <- allocMutMem c+      let go i = when (i < c8) $ copyByteOffMem r 0 mem (Off i) bc >> go (i + chunk)+      go 0+      freezeMutMem mem+{-# INLINE cycleMemN #-}+++-- | Construct an immutable memory region that can't hold any data. Same as @`mempty` ::+-- `FrozenMem` ma@+--+-- ====__Example__+--+-- >>> :set -XTypeApplications+-- >>> :set -XDataKinds+-- >>> import Data.Prim.Memory+-- >>> toListMem (emptyMem @(MBytes 'Inc)) :: [Int]+-- []+--+-- @since 0.1.0+emptyMem ::+     forall ma. MemAlloc ma+  => FrozenMem ma+emptyMem = createMemST_ (0 :: Count Word8) (\_ -> pure ())+{-# INLINE emptyMem #-}++-- | Allocate a region of immutable memory that holds a single element.+--+-- ====__Example__+--+-- >>> :set -XTypeApplications+-- >>> :set -XDataKinds+-- >>> import Data.Prim.Memory+-- >>> toListMem (singletonMem @Word16 @(MBytes 'Inc) 0xffff) :: [Word8]+-- [255,255]+--+-- @since 0.1.0+singletonMem ::+     forall e ma. (MemAlloc ma, Prim e)+  => e -- ^ The single element that will be stored in the newly allocated region of memory+  -> FrozenMem ma+singletonMem a = createMemST_ (1 :: Count e) $ \mem -> writeOffMutMem mem 0 a+{-# INLINE singletonMem #-}++-- | Same as `allocMutMem`, but also use `setMutMem` to reset all of newly allocated memory to+-- zeros.+--+-- [Unsafe] When precondition for @memCount@ argument is violated the outcome is+-- unpredictable. One possible outcome is termination with `Control.Exception.HeapOverflow`+-- async exception.+--+-- ====__Example__+--+-- >>> :set -XTypeApplications+-- >>> :set -XDataKinds+-- >>> import Data.Prim.Memory+-- >>> mb <- allocZeroMutMem @Int @(MBytes 'Inc) 10+-- >>> b <- freezeMutMem mb+-- >>> toListMem b :: [Int]+-- [0,0,0,0,0,0,0,0,0,0]+--+-- @since 0.3.0+allocZeroMutMem ::+     forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e)+  => Count e+  -- ^ /memCount/ - Amount of memory to allocate for the region in number of elements of+  -- type __@e@__+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- Possibility of overflow:+  --+  -- > memCount <= fromByteCount maxBound+  --+  -- When converted to bytes the value should be less then available physical memory+  -> m (ma s)+allocZeroMutMem n = do+  m <- allocMutMem n+  m <$ setMutMem m 0 (toByteCount n) (0 :: Word8)+{-# INLINE allocZeroMutMem #-}++-- | Allocate a mutable region of memory and fill it with the supplied `ST` action. Besides+-- the newly filled frozen memory this function also returns the result produced by the+-- filling action. See `createMemST_` for the version that discards it. Also see+-- `createZeroMemST` for a safer alternative.+--+-- [Unsafe] Same caviats as in `allocMutMem`+--+-- @since 0.1.0+createMemST ::+     forall e b ma. (MemAlloc ma, Prim e)+  => Count e+  -- ^ /memCount/ - Amount of memory to allocate for the region in number of elements of+  -- type __@e@__+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- Possibility of overflow:+  --+  -- > memCount <= fromByteCount maxBound+  --+  -- When converted to bytes the value should be less then available physical memory+  -> (forall s. ma s -> ST s b)+  -- ^ /memFillAction/ - This action will be used to modify the contents of newly+  -- allocated memory. Make sure to overwrite all of it, otherwise it might lead to+  -- breaking referential transparency.+  -> (b, FrozenMem ma)+createMemST n f = runST $ allocMutMem n >>= \m -> (,) <$> f m <*> freezeMutMem m+{-# INLINE createMemST #-}+++createMemST_ ::+     (MemAlloc ma, Prim e)+  => Count e+  -- ^ /memCount/ - Amount of memory to allocate for the region in number of elements of+  -- type __@e@__+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- Possibility of overflow:+  --+  -- > memCount <= fromByteCount maxBound+  --+  -- When converted to bytes the value should be less then available physical memory+  -> (forall s. ma s -> ST s b)+  -- ^ /memFillAction/ - This action will be used to modify the contents of newly+  -- allocated memory. Make sure to overwrite all of it, otherwise it might lead to+  -- breaking referential transparency.+  -> FrozenMem ma+createMemST_ n f = runST (allocMutMem n >>= \m -> f m >> freezeMutMem m)+{-# INLINE createMemST_ #-}++-- | Same as `createMemST`, except it in ensures that the memory is reset to zeros right+-- after allocation+--+-- [Unsafe] Same caviats as in `allocZeroMutMem`: violation of precondition for @memCount@ may+-- result in undefined behavior or `Control.Exception.HeapOverflow` async exception.+--+-- @since 0.1.0+createZeroMemST ::+     forall e ma b. (MemAlloc ma, Prim e)+  => Count e+  -- ^ /memCount/ - Amount of memory to allocate for the region in number of elements of+  -- type __@e@__+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- Possibility of overflow:+  --+  -- > memCount <= fromByteCount maxBound+  --+  -- When converted to bytes the value should be less then available physical memory+  -> (forall s. ma s -> ST s b)+  -- ^ /fillAction/ -- Action that will be used to modify contents of newly allocated+  -- memory. It is not required to overwrite the full region, since the whole thing will+  -- be reset to zeros before applying this action.+  -> (b, FrozenMem ma)+createZeroMemST n f = runST $ allocZeroMutMem n >>= \m -> (,) <$> f m <*> freezeMutMem m+{-# INLINE createZeroMemST #-}++-- | Same as `createMemST_`, except it ensures that the memory gets reset with zeros right+-- after allocation and prior applying the @ST@ filling action @fillAction@.+--+-- [Unsafe] Same reasons as `allocZeroMutMem`: violation of precondition for @memCount@ may+-- result in undefined behavior or `Control.Exception.HeapOverflow` async exception.+--+-- ====__Example__+--+-- Note that this example will work correctly only on little-endian machines:+--+-- >>> :set -XTypeApplications+-- >>> import Data.Prim+-- >>> import Control.Monad+-- >>> let ibs = zip [0, 4 ..] [0x48,0x61,0x73,0x6b,0x65,0x6c,0x6c] :: [(Off Word8, Word8)]+-- >>> let c = Count (length ibs) :: Count Char+-- >>> let bc = createZeroMemST_ @_ @(MBytes 'Inc) c $ \m -> forM_ ibs $ \(i, b) -> writeByteOffMutMem m i b+-- >>> toListMem bc :: String+-- "Haskell"+--+-- @since 0.1.0+createZeroMemST_ ::+     forall e ma b. (MemAlloc ma, Prim e)+  => Count e+  -- ^ /memCount/ - Amount of memory to allocate for the region in number of elements of+  -- type __@e@__+  --+  -- /__Precoditions:__/+  --+  -- Size should be non-negative, but smaller than amount of available memory. Note that the+  -- second condition simply describes overflow.+  --+  -- > 0 <= memCount+  --+  -- Possibility of overflow:+  --+  -- > memCount <= fromByteCount maxBound+  --+  -> (forall s. ma s -> ST s b)+  -- ^ /fillAction/ -- Action that will be used to modify contents of newly allocated+  -- memory. It is not required to overwrite the full region, since the whole thing will+  -- be reset to zeros before applying this action.+  -> FrozenMem ma+createZeroMemST_ n f = runST (allocZeroMutMem n >>= \m -> f m >> freezeMutMem m)+{-# INLINE createZeroMemST_ #-}++-- | Copy all of the data from the source into a newly allocate memory region of identical+-- size.+--+-- ====__Examples__+--+-- >>> :set -XDataKinds+-- >>> import Data.Prim.Memory+-- >>> import Data.Prim.Memory.Bytes+-- >>> let xs = fromByteListMem @(MBytes 'Pin) [0..15] :: Bytes 'Pin+-- >>> let ys = cloneMem xs+-- >>> let report bEq pEq = print $ "Bytes equal: " ++ show bEq ++ ", their pointers equal: " ++ show pEq+-- >>> withPtrBytes xs $ \ xsPtr -> withPtrBytes ys $ \ ysPtr -> report (xs == ys) (xsPtr == ysPtr)+-- "Bytes equal: True, their pointers equal: False"+-- >>> report (eqByteMem xs ys) (isSameBytes xs ys)+-- "Bytes equal: True, their pointers equal: False"+--+-- @since 0.2.0+cloneMem ::+     forall ma. MemAlloc ma+  => FrozenMem ma -- ^ /memSource/ - immutable source memory.+  -> FrozenMem ma+cloneMem fm =+  runST $ do+    let n = byteCountMem fm+    mm <- allocMutMem n+    copyMem fm 0 mm 0 n+    freezeMutMem mm+{-# INLINE cloneMem #-}++-- | Similar to `copyByteOffMem`, but supply offsets in number of elements instead of+-- bytes. Copy contiguous chunk of memory from the read only memory region into the target+-- mutable memory region. Source and target /must not/ refer to the same memory region,+-- otherwise that would imply that the source is not immutable which would be a violation+-- of some other invariant elsewhere in the code.+--+-- [Unsafe] When any precondition for one of the offsets @memSourceOff@, @memTargetOff@+-- or the element count @memCount@ is violated a call to this function can result in:+-- copy of data that doesn't belong to @memSourceRead@, heap corruption or failure with+-- a segfault.+--+-- @since 0.1.0+copyMem ::+     (MonadPrim s m, MemRead mr, MemWrite mw, Prim e)+  => mr -- ^ /memSourceRead/ - Read-only source memory region from which the data will+        -- copied+  -> Off e+  -- ^ /memSourceOff/ - Offset into source memory in number of elements of type __@e@__+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memSourceOff+  --+  -- > unOff memSourceOff < unCount (countMem memSourceRead)+  -> mw s -- ^ /memTargetWrite/ - Target mutable memory+  -> Off e+  -- ^ /memTargetOff/ -  Offset into target memory in number of elements+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memTargetOff+  --+  -- With offset applied it should still refer to the same memory region. For types that+  -- also implement `MemAlloc` this can be described as:+  --+  -- > targetCount <- getCountMutMem memTargetWrite+  -- > unOff memTargetOff < unCount targetCount+  -> Count e+  -- ^ /memCount/ - Number of elements of type __@e@__ to copy+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- Both source and target memory regions must have enough memory to perform a copy+  -- of @memCount@ elements starting at their respective offsets. For @memSourceRead@:+  --+  -- > unOff memSourceOff + unCount memCount < unCount (countMem memSourceRead)+  --+  -- and for @memTargetWrite@ that also implements `MemAlloc` this can be described as:+  --+  -- > targetCount <- getCountMutMem memTargetWrite+  -- > unOff memTargetOff + unCount memCount < unCount targetCount+  -> m ()+copyMem src srcOff dst dstOff = copyByteOffMem src (toByteOff srcOff) dst (toByteOff dstOff)+{-# INLINE copyMem #-}+++--+-- @since 0.3.0+moveMutMem ::+     (MonadPrim s m, MemWrite mw1, MemWrite mw2, Prim e)+  => mw1 s -- ^ Source memory region+  -> Off e -- ^ Offset into the source in number of elements+  -> mw2 s -- ^ Destination memory region+  -> Off e -- ^ Offset into destination in number of elements+  -> Count e -- ^ Number of elements to copy over+  -> m ()+moveMutMem src srcOff dst dstOff = moveByteOffMutMem src (toByteOff srcOff) dst (toByteOff dstOff)+{-# INLINE moveMutMem #-}+++appendMem ::+     forall mr1 mr2 ma. (MemRead mr1, MemRead mr2, MemAlloc ma)+  => mr1+  -> mr2+  -> FrozenMem ma+appendMem r1 r2 =+  createMemST_ (n1 + n2) $ \mem -> do+    copyMem r1 0 mem 0 n1+    copyMem r2 (coerce n1) mem (coerce n1) n2+  where+    n1 = byteCountMem r1+    n2 = byteCountMem r2+{-# INLINABLE appendMem #-}++concatMem ::+     forall mr ma. (MemRead mr, MemAlloc ma)+  => [mr]+  -> FrozenMem ma+concatMem xs = do+  let c = Foldable.foldl' (\ !acc b -> acc + byteCountMem b) 0 xs+  createMemST_ c $ \mb -> do+    let load i b = do+          let cb@(Count n) = byteCountMem b :: Count Word8+          (i + Off n) <$ copyMem b 0 mb i cb+    foldM_ load 0 xs+{-# INLINABLE concatMem #-}++-- | This is a safe version of `thawMem`. It first makes an exact copy of the supplied+-- memory region and only then thaws it, thus yielding a mutable region of memory. This+-- means any mutation, will only affect the newly allocated region that was returned and+-- not the source region.+--+-- ====__Examples__+--+-- >>> :set -XTypeApplications+-- >>> :set -XDataKinds+-- >>> import Data.Prim.Memory+-- >>> let fm = fromListMem @Word8 @(MBytes 'Inc) [1,2,3,4]+-- >>> mm <- thawCloneMem fm+-- >>> writeOffMutMem mm 1 (0xadde :: Word16)+-- >>> freezeMutMem mm+-- [0x01,0x02,0xde,0xad]+-- >>> fm+-- [0x01,0x02,0x03,0x04]+--+-- @since 0.1.0+thawCloneMem ::+     forall ma m s. (MemAlloc ma, MonadPrim s m)+  => FrozenMem ma+  -> m (ma s)+thawCloneMem a = thawCopyMem a 0 (byteCountMem a)+{-# INLINE thawCloneMem #-}+++-- | Similar to `thawCloneMem`, except it is possible to specify which portion of the+-- frozen region will be copied over and thawed.+--+-- [Unsafe] When any precondition for eihter an offset @memSourceOff@ or the element count+-- @memCount@ is violated a call to this function can result in: copy of data that doesn't+-- belong to @memSource@ or failure with a segfault.+--+-- ====__Examples__+--+-- >>> :set -XTypeApplications+-- >>> :set -XDataKinds+-- >>> import Data.Prim.Memory+-- >>> let fm = fromListMem @Word8 @(MBytes 'Inc) [1,2,3,4,5]+-- >>> mm <- thawCopyMem fm 1 (3 :: Count Word8)+-- >>> writeOffMutMem mm 1 (0 :: Word8)+-- >>> freezeMutMem mm+-- [0x02,0x00,0x04]+-- >>> fm+-- [0x01,0x02,0x03,0x04,0x05]+--+-- @since 0.1.0+thawCopyMem ::+     forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m)+  => FrozenMem ma -- ^ /memSource/ - Read-only source memory region from which the data+                  -- will copied and thawed+  -> Off e+  -- ^ /memSourceOff/ - Offset into source memory in number of elements of type __@e@__+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memSourceOff+  --+  -- > unOff memSourceOff < unCount (countMem memSource)+  -> Count e+  -- ^ /memCount/ - Number of elements of type __@e@__ to copy+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- > unOff memSourceOff + unCount memCount < unCount (countMem memSource)+  -> m (ma s)+thawCopyMem a off c = do+  mem <- allocMutMem c+  mem <$ copyMem a off mem 0 c+{-# INLINE thawCopyMem #-}++++--+-- @since 0.3.0+freezeCopyMutMem ::+     forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m)+  => ma s+  -> Off e+  -> Count e+  -> m (FrozenMem ma)+freezeCopyMutMem mem off c = freezeMutMem mem >>= \r -> thawCopyMem r off c >>= freezeMutMem+{-# INLINE freezeCopyMutMem #-}++-- | Safe version of `freezeMutMem`. Yields an immutable copy of the supplied mutable+-- memory region. Further mutation of the source memory region will not affect the+-- produced copy.+---+-- ====__Example__+--+-- >>> :set -XTypeApplications+-- >>> :set -XDataKinds+-- >>> import Data.Prim.Memory+-- >>> mb <- allocZeroMutMem @Word8 @(MBytes 'Pin) 4+-- >>> writeOffMutMem mb 2 (0xff :: Word8)+-- >>> b <- freezeCloneMutMem mb+-- >>> writeOffMutMem mb 1 (0xab :: Word8)+-- >>> b+-- [0x00,0x00,0xff,0x00]+-- >>> freezeMutMem mb+-- [0x00,0xab,0xff,0x00]+--+-- @since 0.3.0+freezeCloneMutMem ::+     forall ma m s. (MemAlloc ma, MonadPrim s m)+  => ma s+  -> m (FrozenMem ma)+freezeCloneMutMem = freezeMutMem >=> thawCloneMem >=> freezeMutMem+{-# INLINE freezeCloneMutMem #-}++-- | /O(n)/ - Convert a read-only memory region into a newly allocated other type of+-- memory region+--+-- >>> import Data.ByteString (pack)+-- >>> let bs = pack [0x10 .. 0x20]+-- >>> bs+-- "\DLE\DC1\DC2\DC3\DC4\NAK\SYN\ETB\CAN\EM\SUB\ESC\FS\GS\RS\US "+-- >>> convertMem bs :: Bytes 'Inc+-- [0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20]+--+-- @since 0.1.0+convertMem :: (MemRead mr, MemAlloc ma) => mr -> FrozenMem ma+convertMem m =+  let c = byteCountMem m+   in createMemST_ c (\mm -> copyMem m 0 mm 0 c)+{-# INLINE convertMem #-}++-- | Figure out how many elements fits into the immutable region of memory. It is+-- possible that there is a remainder of bytes left, see `countRemMem` for getting that+-- too.+--+-- ====__Examples__+--+-- >>> let b = fromListMem [0 .. 5 :: Word8] :: Bytes 'Pin+-- >>> b+-- [0x00,0x01,0x02,0x03,0x04,0x05]+-- >>> countMem b :: Count Word16+-- Count {unCount = 3}+-- >>> countMem b :: Count Word32+-- Count {unCount = 1}+-- >>> countMem b :: Count Word64+-- Count {unCount = 0}+--+-- @since 0.1.0+countMem ::+     forall e mr. (MemRead mr, Prim e)+  => mr+  -> Count e+countMem = fromByteCount . byteCountMem+{-# INLINE countMem #-}++-- | Figure out how many elements and a byte size remainder can fit into the immutable+-- region of memory.+--+-- ====__Examples__+--+-- >>> let b = fromListMem [0 .. 5 :: Word8] :: Bytes 'Pin+-- >>> b+-- [0x00,0x01,0x02,0x03,0x04,0x05]+-- >>> countRemMem @Word16 b+-- (Count {unCount = 3},Count {unCount = 0})+-- >>> countRemMem @Word32 b+-- (Count {unCount = 1},Count {unCount = 2})+-- >>> countRemMem @Word64 b+-- (Count {unCount = 0},Count {unCount = 6})+--+-- @since 0.1.0+countRemMem :: forall e mr. (MemRead mr, Prim e) => mr -> (Count e, Count Word8)+countRemMem = fromByteCountRem . byteCountMem+{-# INLINE countRemMem #-}++-- | Figure out how many elements fits into the mutable region of memory. Similar to+-- `countMem`, except that it is not a pure funciton, since the size of mutable memory can+-- change throuhout its lifetime. It is possible that there is a remainder of bytes left,+-- see `getCountRemMem` for getting that too.+--+-- ====__Examples__+--+-- >>> mb <- thawMem (fromListMem [0 .. 5 :: Word8] :: Bytes 'Pin)+-- >>> getCountMutMem mb :: IO (Count Word16)+-- Count {unCount = 3}+-- >>> getCountMutMem mb :: IO (Count Word32)+-- Count {unCount = 1}+-- >>> getCountMutMem mb :: IO (Count Word64)+-- Count {unCount = 0}+-- >>> mb' <- reallocMutMem mb (6 :: Count Word64)+-- >>> getCountMutMem mb' :: IO (Count Word32)+-- Count {unCount = 12}+--+-- @since 0.3.0+getCountMutMem :: forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e) => ma s -> m (Count e)+getCountMutMem = fmap (fromByteCount . coerce) . getByteCountMutMem+{-# INLINE getCountMutMem #-}+++-- | Figure out how many elements and a byte size remainder can fit into the mutable+-- region of memory. Similar to `countRemMem`, except it is a monadic action for mutable+-- regions instead of a pure function for immutable memory. See `getCountMutMem` for getting+-- the element count only.+--+-- ====__Examples__+--+-- >>> b <- thawMem (fromListMem [0 .. 5 :: Word8] :: Bytes 'Pin)+-- >>> getCountRemMutMem @Word16 b+-- (Count {unCount = 3},Count {unCount = 0})+-- >>> getCountRemMutMem @Word32 b+-- (Count {unCount = 1},Count {unCount = 2})+-- >>> getCountRemMutMem @Word64 b+-- (Count {unCount = 0},Count {unCount = 6})+--+-- @since 0.3.0+getCountRemMutMem ::+     forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e)+  => ma s+  -> m (Count e, Count Word8)+getCountRemMutMem = fmap (fromByteCountRem . coerce) . getByteCountMutMem+{-# INLINE getCountRemMutMem #-}++-- | Allocate the same amount of memory as the source memory region and copy all of its+-- data over.+--+-- @since 0.3.0+cloneMutMem ::+     forall ma m s. (MemAlloc ma, MonadPrim s m)+  => ma s+  -> m (ma s)+cloneMutMem = freezeMutMem >=> thawCloneMem+{-# INLINE cloneMutMem #-}++-- | Compare two memory regions byte-by-byte. Computation may be short-circuited on the+-- first mismatch, but it is `MemRead` implementation specific.+--+-- @since 0.3.0+eqByteOffMem ::+     (MemRead mr1, MemRead mr2)+  => mr1 -- ^ /memRead1/ - First region of memory+  -> Off Word8+  -- ^ /memOff1/ - Offset for @memRead1@ in number of bytes+  --+  -- /__Precondition:__/+  --+  -- > 0 <= memOff1+  -> mr2 -- ^ /memRead2/ - Second region of memory+  -> Off Word8+  -- ^ /memOff2/ - Offset for @memRead1@ in number of bytes+  --+  -- /__Precondition:__/+  --+  -- > 0 <= memOff2+  -> Count Word8+  -- ^ /memCount/ - Number of bytes compare+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- > offToCount memOff1 + memCount < countMem memRead1+  --+  -- > offToCount memOff2 + memCount < countMem memRead2+  -> Bool+eqByteOffMem b1 off1 b2 off2 n = compareByteOffMem b1 off1 b2 off2 n == EQ+{-# INLINE eqByteOffMem #-}++-- | Compare two memory regions for equality byte-by-byte. `False` is returned immediately+-- when sizes reported by `byteCountMem` do not match.+--+-- @since 0.3.0+eqByteMem :: (MemRead mr1, MemRead mr2) => mr1 -> mr2 -> Bool+eqByteMem b1 b2 = n == byteCountMem b2 && eqByteOffMem b1 0 b2 0 n+  where+    n = byteCountMem b1+{-# INLINE eqByteMem #-}+++-- | Compare two memory regions byte-by-byte.+--+-- @since 0.3.0+compareByteMem :: (MemRead mr1, MemRead mr2) => mr1 -> mr2 -> Ordering+compareByteMem b1 b2 = compare n (byteCountMem b2) <> compareByteOffMem b1 0 b2 0 n+  where+    n = byteCountMem b1+{-# INLINE compareByteMem #-}++-- =============== --+-- List conversion --+-- =============== --++-------------+-- To List --+-------------++-- | Convert an immutable memory region to a list. Whenever memory byte count is not+-- exactly divisible by the size of the element there will be some slack left unaccounted+-- for. In order to get a hold of this slack use `toListSlackMem` instead.+--+-- ====__Examples__+--+-- >>> import Data.Prim.Memory+-- >>> import Numeric (showHex)+-- >>> let b = fromByteListMem [0x48,0x61,0x73,0x6b,0x65,0x6c,0x6c] :: Bytes 'Inc+-- >>> toListMem b :: [Int8]+-- [72,97,115,107,101,108,108]+-- >>> let xs = toListMem b :: [Word32]+-- >>> xs+-- [1802723656]+-- >>> showHex (head xs) ""+-- "6b736148"+--+-- @since 0.1.0+toListMem :: forall e mr. (MemRead mr, Prim e) => mr -> [e]+toListMem ba = build (\ c n -> foldrCountMem (countMem ba) c n ba)+{-# INLINE toListMem #-}+{-# SPECIALIZE toListMem :: Prim e => Bytes p -> [e] #-}++-- | Same as `toListMem`, except when there is some slack towards the end of the memory+-- region that didn't fit into a list it will be returned as a list of bytes.+--+-- ====__Examples__+--+-- >>> import Data.Word+-- >>> :set -XDataKinds+-- >>> let a = fromListMem [0 .. 10 :: Word8] :: Bytes 'Pin+-- >>> a+-- [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a]+-- >>> toListSlackMem a :: ([Word8], [Word8])+-- ([0,1,2,3,4,5,6,7,8,9,10],[])+-- >>> toListSlackMem a :: ([Word16], [Word8])+-- ([256,770,1284,1798,2312],[10])+-- >>> toListSlackMem a :: ([Word32], [Word8])+-- ([50462976,117835012],[8,9,10])+-- >>> toListSlackMem a :: ([Word64], [Word8])+-- ([506097522914230528],[8,9,10])+--+-- @since 0.1.0+toListSlackMem ::+     forall e mr. (MemRead mr, Prim e)+  => mr+  -> ([e], [Word8])+toListSlackMem mem =+  (build (\c n -> foldrCountMem k c n mem), getSlack (k8 + r8) [])+  where+    (k, Count r8) = countRemMem mem+    Count k8 = toByteCount k+    getSlack i !acc+      | i == k8 = acc+      | otherwise =+        let i' = i - 1+         in getSlack i' (indexByteOffMem mem (Off i') : acc)+{-# INLINABLE toListSlackMem #-}++-- | Right fold that is useful for converting to a list while tapping into list fusion.+--+-- [Unsafe] Supplying Count larger than memory holds will result in reading out of bounds+-- and a potential segfault.+--+-- @since 0.1.0+foldrCountMem :: forall e b mr. (MemRead mr, Prim e) => Count e -> (e -> b -> b) -> b -> mr -> b+foldrCountMem (Count k) c nil bs = go 0+  where+    go i+      | i == k = nil+      | otherwise =+        let !v = indexOffMem bs (Off i)+         in v `c` go (i + 1)+{-# INLINE[0] foldrCountMem #-}++---------------+-- From List --+---------------++-- Pure immutable conversion --++-- | Just like `fromListMemN`, except it ensures safety by using the length of the+-- list for allocation. Because it has to figure out the length of the list first it+-- will be just a little bit slower, but that much safer.+--+-- ====__Examples__+--+-- >>> import Data.Prim.Memory+-- >>> :set -XDataKinds+-- >>> fromListMem "Hi" :: Bytes 'Inc+-- [0x48,0x00,0x00,0x00,0x69,0x00,0x00,0x00]+--+-- @since 0.1.0+fromListMem ::+     forall e ma. (Prim e, MemAlloc ma)+  => [e]+  -> FrozenMem ma+fromListMem xs =+  let count = coerce (length xs) `countForProxyTypeOf` xs+   in createMemST_ count (loadListMutMemN_ count xs)+{-# INLINE fromListMem #-}+++-- | Same as `fromListMem` but restricted to a list of `Word8`. Load a list of bytes into+-- a newly allocated memory region. Equivalent to `Data.ByteString.pack` for+-- `Data.ByteString.ByteString`+--+-- ====__Examples__+--+-- >>> fromByteListMem [0..10] :: Bytes 'Pin+-- [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a]+--+-- @since 0.1.0+fromByteListMem ::+     forall ma. MemAlloc ma+  => [Word8]+  -> FrozenMem ma+fromByteListMem = fromListMem+{-# INLINE fromByteListMem #-}+++-- | Similarly to `fromListMem` load a list into a newly allocated memory region, but+-- unlike the aforementioned function it also accepts a hint of how many elements is+-- expected to be in the list. Because the number of expected an actual elements might+-- not match we return not only the frozen memory region, but also:+--+-- * either a list with leftover elements from the input @list@, if it did not fully fit+--   into the allocated region. An empty list would indicate that it did fit exactly.+--+--     @+--     unCount memCount <= length list+--     @+--+-- * or an exact count of how many elements have been loaded when there was no+--   enough elements in the list+--+--+-- In the latter case a zero value would indicate that the list did fit into the newly+-- allocated memory region exactly, which is perfectly fine. But a positive value would+-- mean that the tail of the memory region is still unset and might contain garbage+-- data. Make sure to overwrite the surplus memory yourself or use the safe version+-- `fromListZeroMemN` that fills the surplus with zeros.+--+-- [Unsafe] Whenever @memCount@ precodition is violated, because on each call with the+-- same input it can produce different output therefore it will break referential+-- transparency.+--+-- ====__Examples__+--+-- >>> :set -XTypeApplications+-- >>> fromListMemN @Char @(MBytes 'Inc) 3 "Hello"+-- (Left "lo",[0x48,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00])+-- >>> fromListMemN @Char @(MBytes 'Inc) 2 "Hi"+-- (Left "",[0x48,0x00,0x00,0x00,0x69,0x00,0x00,0x00])+-- >>> fst $ fromListMemN @Char @(MBytes 'Inc) 5 "Hi"+-- Right (Count {unCount = 2})+--+-- @since 0.2.0+fromListMemN ::+     forall e ma. (Prim e, MemAlloc ma)+  => Count e+  -- ^ /memCount/ - Expected number of elements in the list, which exactly how much+  -- memory will be allocated.+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  -- > unCount memCount <= length list+  -> [e]+  -- ^ /list/ - A list of elements to load into the newly allocated memory region.+  -> (Either [e] (Count e), FrozenMem ma)+fromListMemN count xs =+  createMemST count $ \mm -> do+    (ys, loadedCount) <- loadListOffMutMemN count xs mm 0+    pure $+      if loadedCount /= count && null ys+        then Right loadedCount+        else Left ys+{-# INLINE fromListMemN #-}+++-- | Just like `fromListMemN`, except it ensures safety by filling tail with zeros,+-- whenever the list is not long enough.+--+-- ====__Examples__+--+-- >>> import Data.Prim.Memory+-- >>> :set -XTypeApplications+-- >>> fromListZeroMemN @Char @(MBytes 'Inc) 3 "Hi"+-- (Right (Count {unCount = 2}),[0x48,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x00,0x00,0x00,0x00])+--+-- @since 0.2.0+fromListZeroMemN ::+     forall e ma. (Prim e, MemAlloc ma)+  => Count e -- ^ /memCount/ - Number of elements to load from the list.+  -> [e]+  -> (Either [e] (Count e), FrozenMem ma)+fromListZeroMemN count xs =+  createMemST (max 0 count) $ \mm -> do+    (ys, loadedCount) <- loadListOffMutMemN count xs mm 0+    let loadedByteCount = toByteCount loadedCount+        surplusByteCount = toByteCount count - loadedByteCount+    when (surplusByteCount > 0) $ setMutMem mm (countToOff loadedByteCount) surplusByteCount 0+    pure $+      if loadedCount /= count && null ys+        then Right loadedCount+        else Left ys+{-# INLINE fromListZeroMemN #-}++-- | Same as `fromListZeroMemN`, but ignore the extra information about how the loading went.+--+-- ====__Examples__+--+-- >>> import Data.Prim.Memory+-- >>> fromListZeroMemN_ 3 "Hi" :: Bytes 'Inc+-- [0x48,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x00,0x00,0x00,0x00]+--+-- @since 0.2.0+fromListZeroMemN_ ::+     forall e ma. (Prim e, MemAlloc ma)+  => Count e+  -> [e]+  -> FrozenMem ma+fromListZeroMemN_ !n = snd . fromListZeroMemN n+{-# INLINE fromListZeroMemN_ #-}++++-- Mutable loading --+++loadListByteOffHelper ::+     (MemWrite mw, MonadPrim s m, Prim e)+  => [e]+  -> mw s+  -> Off Word8 -- ^ Offset+  -> Off Word8 -- ^ Upper bound+  -> Off Word8 -- ^ Element size+  -> m ([e], Count e)+loadListByteOffHelper ys mw byteOff k step =+  let go []       i = pure ([], toLoadedCount i)+      go a@(x:xs) i+        | i < k = writeByteOffMutMem mw i x >> go xs (i + step)+        | otherwise = pure (a, toLoadedCount i)+      toLoadedCount i = fromByteCount (offToCount (i - byteOff))+   in go ys byteOff+{-# INLINE loadListByteOffHelper #-}+++-- | Load elements from the supplied list into a mutable memory region. Loading will+-- start at the supplied offset in number of bytes and will stop when either supplied+-- @elemCount@ number is reached or there are no more elements left in the list to+-- load. This action returns a list of elements that did not get loaded and the count of+-- how many elements did get loaded.+--+-- [Unsafe] When any precondition for either the offset @memTargetOff@ or the element+-- count @memCount@ is violated then a call to this function can result in heap corruption+-- or failure with a segfault.+--+-- ====__Examples__+--+-- For example load the @"Hell"@ somewhere in the middle of `MBytes`:+--+-- >>> ma <- allocZeroMutMem (6 :: Count Char) :: IO (MBytes 'Inc RW)+-- >>> loadListByteOffMutMemN 4 "Hello!" ma (toByteOff (1 :: Off Char))+-- ("o!",Count {unCount = 4})+-- >>> freezeMutMem ma+-- [0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00]+--+-- Or something more useful like loading prefixes from nested lists:+--+-- >>> import Control.Monad+-- >>> foldM_ (\o xs -> (+ o) . countToByteOff . snd <$> loadListByteOffMutMemN 4 xs ma o) 2 [[x..] | x <- [1..5] :: [Word8]]+-- >>> freezeMutMem ma+-- [0x00,0x00,0x01,0x02,0x03,0x04,0x02,0x03,0x04,0x05,0x03,0x04,0x05,0x06,0x04,0x05,0x06,0x07,0x05,0x06,0x07,0x08,0x00,0x00]+--+-- @since 0.2.0+loadListByteOffMutMemN ::+     (MemWrite mw, MonadPrim s m, Prim e)+  => Count e+  -- ^ /elemCount/ - Maximum number of elements to load from list into the memory region+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- Target memory region must have enough memory to perform loading of @elemCount@+  -- elements starting at the @memTargetOff@ offset. For types that also implement+  -- `MemAlloc` this can be described as:+  --+  -- > targetByteCount <- getByteCountMutMem memTarget+  -- > unOff memTargetOff + unCountBytes elemCount <= unCount (targetByteCount - byteCountType @e)+  -> [e] -- ^ /listSource/ - List with elements that should be loaded+  -> mw s -- ^ /memTarget/ - Memory region where to load the elements into+  -> Off Word8+  -- ^ /memTargetOff/ - Offset in number of bytes into target memory where writing will start+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memTargetOff+  --+  -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same memory+  -- region @memTarget@. For types that also implement `MemAlloc` this can be described+  -- as:+  --+  -- > targetByteCount <- getByteCountMutMem memTarget+  -- > unOff memTargetOff <= unCount (targetByteCount - byteCountType @e)+  -> m ([e], Count e)+  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.+loadListByteOffMutMemN count ys mw byteOff = loadListByteOffHelper ys mw byteOff k step+  where+    k = byteOff + countToOff (toByteCount count)+    step = countToOff $ byteCountProxy ys+{-# INLINABLE loadListByteOffMutMemN #-}++-- | Same as `loadListByteOffMutMemN`, but infer the count from number of bytes that is+-- available in the target memory region.+--+-- [Unsafe] When a precondition for the element count @memCount@ is violated then a call+-- to this function can result in heap corruption or failure with a segfault.+--+-- ====__Examples__+--+-- >>> :set -XDataKinds+-- >>> import Data.Prim.Memory+-- >>> ma <- allocZeroMutMem (5 :: Count Char) :: IO (MBytes 'Inc RW)+-- >>> freezeMutMem ma+-- [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]+-- >>> loadListByteOffMutMem "Hello World" ma 0+-- (" World",Count {unCount = 5})+-- >>> freezeMutMem ma+-- [0x48,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6f,0x00,0x00,0x00]+-- >>> loadListByteOffMutMem ([0xff,0xff,0xff] :: [Word8]) ma 1+-- ([],Count {unCount = 3})+-- >>> freezeMutMem ma+-- [0x48,0xff,0xff,0xff,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6f,0x00,0x00,0x00]+--+-- @since 0.3.0+loadListByteOffMutMem ::+     (MemAlloc ma, MonadPrim s m, Prim e)+  => [e] -- ^ /listSource/ - List with elements that should be loaded+  -> ma s -- ^ /memTarget/ - Memory region where to load the elements into+  -> Off Word8+  -- ^ /memTargetOff/ - Offset in number of bytes into target memory where writing will start+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memTargetOff+  --+  -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same memory+  -- region @memTarget@. For types that also implement `MemAlloc` this can be described+  -- as:+  --+  -- > targetByteCount <- getByteCountMutMem memTarget+  -- > unOff memTargetOff <= unCount (targetByteCount - byteCountType @e)+  -> m ([e], Count e)+  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.+loadListByteOffMutMem ys ma byteOff = do+  bCount <- getByteCountMutMem ma+  let k = countToOff bCount - byteOff+      step = countToOff $ byteCountProxy ys+  loadListByteOffHelper ys ma byteOff k step+{-# INLINABLE loadListByteOffMutMem #-}++-- | Same as `loadListByteOffMutMemN`, but works with offset in number of elements instead of+-- bytes.+--+-- [Unsafe] When preconditions for either the offset @memTargetOff@ or the element count+-- @memCount@ is violated then a call to this function can result in heap corruption or+-- failure with a segfault.+--+-- @since 0.2.0+loadListOffMutMemN ::+     (MemWrite mw, MonadPrim s m, Prim e)+  => Count e+  -- ^ /elemCount/ - Maximum number of elements to load from list into the memory region+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- Target memory region must have enough memory to perform loading of @elemCount@+  -- elements starting at the @memTargetOff@ offset. For types that also implement+  -- `MemAlloc` this can be described as:+  --+  -- > targetCount <- getCountMutMem memTarget+  -- > unOff memTargetOff + unCount elemCount < unCount targetCount+  -> [e] -- ^ /listSource/ - List with elements that should be loaded+  -> mw s -- ^ /memTarget/ - Memory region where to load the elements into+  -> Off e+  -- ^ /memTargetOff/ - Offset in number of elements into target memory where writing will start+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memTargetOff+  --+  -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same memory+  -- region @memTarget@. For types that also implement `MemAlloc` this can be described+  -- as:+  --+  -- > targetCount <- getByteCountMutMem memTarget+  -- > unOff memTargetOff < unCount targetCount+  -> m ([e], Count e)+  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.+loadListOffMutMemN count ys mw off =+  let go []       i = pure ([], toLoadedCount i)+      go a@(x:xs) i+        | i < k = writeOffMutMem mw i x >> go xs (i + 1)+        | otherwise = pure (a, toLoadedCount i)+      k = off + countToOff count+      toLoadedCount i = offToCount (i - off)+  in go ys off+{-# INLINABLE loadListOffMutMemN #-}+++-- | Same as `loadListOffMutMemN`, but start loading at @0@ offset.+--+-- [Unsafe] When any precondition for the element count @memCount@ is violated then a call to+-- this function can result in heap corruption or failure with a segfault.+--+-- @since 0.2.0+loadListMutMemN ::+     forall e mw m s. (MemWrite mw, MonadPrim s m, Prim e)+  => Count e+  -- ^ /elemCount/ - Maximum number of elements to load from list into the memory region+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- Target memory region must have enough memory to perform loading of @elemCount@+  -- elements. For types that also implement `MemAlloc` this can be described as:+  --+  -- > targetCount <- getCountMutMem memTarget+  -- > elemCount <= targetCount+  -> [e] -- ^ /listSource/ - List with elements that should be loaded+  -> mw s -- ^ /memTarget/ - Memory region where to load the elements into+  -> m ([e], Count e)+  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.+loadListMutMemN count xs mw = loadListOffMutMemN count xs mw 0+{-# INLINABLE loadListMutMemN #-}++++-- | Same as `loadListMutMemN`, but ignores the result.+--+-- [Unsafe] When any precondition for the element count @memCount@ is violated then a call+-- to this function can result in heap corruption or failure with a segfault.+--+-- @since 0.2.0+loadListMutMemN_ ::+     forall e mw m s. (Prim e, MemWrite mw, MonadPrim s m)+  => Count e+  -- ^ /elemCount/ - Maximum number of elements to load from list into the memory region+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memCount+  --+  -- Target memory region must have enough memory to perform loading of @elemCount@+  -- elements. For types that also implement `MemAlloc` this can be described as:+  --+  -- > targetCount <- getCountMutMem memTarget+  -- > elemCount <= targetCount+  -> [e] -- ^ /listSource/ - List with elements that should be loaded+  -> mw s -- ^ /memTarget/ - Memory region where to load the elements into+  -> m ()+loadListMutMemN_ (Count n) ys mb =+  let go []     _ = pure ()+      go (x:xs) i = when (i < n) $ writeOffMutMem mb (Off i) x >> go xs (i + 1)+   in go ys 0+{-# INLINABLE loadListMutMemN_ #-}+++++-- | Same as `loadListOffMutMemN`, but infer the count from number of bytes that is available+-- in the target memory region.+--+-- [Unsafe] When a precondition for the element count @memCount@ is violated then a call+-- to this function can result in heap corruption or failure with a segfault.+--+-- @since 0.3.0+loadListOffMutMem ::+     forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m)+  => [e] -- ^ /listSource/ - List with elements that should be loaded+  -> ma s -- ^ /memTarget/ - Memory region where to load the elements into+  -> Off e+  -- ^ /memTargetOff/ - Offset in number of elements into target memory where writing will+  -- start+  --+  -- /__Preconditions:__/+  --+  -- > 0 <= memTargetOff+  --+  -- Once the pointer is advanced by @memTargetOff@ it must still refer to the same memory+  -- region @memTarget@. For types that also implement `MemAlloc` this can be described+  -- as:+  --+  -- > targetCount <- getCountMutMem memTarget+  -- > unOff memTargetOff < unCount targetCount+  -> m ([e], Count e)+  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.+loadListOffMutMem ys ma off = getCountMutMem ma >>= \c -> loadListOffMutMemN (c - offToCount off) ys ma off+{-# INLINE loadListOffMutMem #-}+++-- | Same as `loadListMutMemN`, but tries to fit as many elements as possible into the mutable+-- memory region starting at the beginning. This operation is always safe.+--+-- ====__Examples__+--+-- >>> import Data.Prim.Memory+-- >>> ma <- allocMutMem (5 :: Count Char) :: IO (MBytes 'Inc RW)+-- >>> loadListMutMem "HelloWorld" ma+-- ("World",Count {unCount = 5})+-- >>> freezeMutMem ma+-- [0x48,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6f,0x00,0x00,0x00]+-- >>> loadListMutMem (replicate 6 (0xff :: Word8)) ma+-- ([],Count {unCount = 6})+-- >>> freezeMutMem ma+-- [0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6f,0x00,0x00,0x00]+--+-- @since 0.3.0+loadListMutMem ::+     forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m)+  => [e] -- ^ /listSource/ - List with elements to load+  -> ma s -- ^ /memTarget/ - Mutable region where to load elements from the list+  -> m ([e], Count e)+  -- ^ Leftover part of the @listSource@ if any and the exact count of elements that have been loaded.+loadListMutMem ys ma = getCountMutMem ma >>= \c -> loadListOffMutMemN (c `countForProxyTypeOf` ys) ys ma 0+{-# INLINE loadListMutMem #-}++-- | Same as `loadListMutMem`, but ignores the result. Equivalence as property:+--+-- prop> let c = fromInteger (abs i) :: Count Int in (createZeroMemST_ c (loadListMutMem_ (xs :: [Int])) :: Bytes 'Inc) == createZeroMemST_ c (void . loadListMutMem xs)+--+-- @since 0.2.0+loadListMutMem_ ::+     forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m)+  => [e] -- ^ /listSource/ - List with elements to load+  -> ma s -- ^ /memTarget/ - Mutable region where to load elements from the list+  -> m ()+loadListMutMem_ ys mb = getCountMutMem mb >>= \c -> loadListMutMemN_ (c `countForProxyTypeOf` ys) ys mb+{-# INLINE loadListMutMem_ #-}+++-- | Convert a memory region to a list of bytes. Equivalent to `Data.ByteString.unpack`+-- for `Data.ByteString.ByteString`+--+-- ====__Example__+--+-- >>> toByteListMem (fromByteListMem [0..10] :: Bytes 'Pin)+-- [0,1,2,3,4,5,6,7,8,9,10]+--+-- @since 0.1.0+toByteListMem ::+     forall ma. MemAlloc ma+  => FrozenMem ma+  -> [Word8]+toByteListMem = toListMem+{-# INLINE toByteListMem #-}++-- mapMem ::+--      forall e e' mr ma. (MemRead mr, MemAlloc ma, Prim e, Prim e')+--   => (e -> e')+--   -> mr+--   -> (FrozenMem ma, [Word8])+-- mapMem f = undefined+++mapByteMem ::+     forall e mr ma. (MemRead mr, MemAlloc ma, Prim e)+  => (Word8 -> e)+  -> mr+  -> FrozenMem ma+mapByteMem f = imapByteOffMem (const f)++-- Map an index aware function over memory region+--+-- >>> import Data.Prim.Memory+-- >>> a = fromListMem [1 .. 10 :: Word8] :: Bytes 'Inc+-- >>> a+-- [0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a]+-- >>> imapByteOffMem (\i e -> (fromIntegral i :: Int8, e + 0xf0)) a :: Bytes 'Pin+-- [0x00,0xf1,0x01,0xf2,0x02,0xf3,0x03,0xf4,0x04,0xf5,0x05,0xf6,0x06,0xf7,0x07,0xf8,0x08,0xf9,0x09,0xfa]+--+-- @since 0.1.0+imapByteOffMem ::+     (MemRead mr, MemAlloc ma, Prim e) => (Off Word8 -> Word8 -> e) -> mr -> FrozenMem ma+imapByteOffMem f r = runST $ mapByteOffMemM (\i -> pure . f i) r++-- @since 0.1.0+mapByteMemM ::+     (MemRead mr, MemAlloc ma, MonadPrim s m, Prim e)+  => (Word8 -> m e)+  -> mr+  -> m (FrozenMem ma)+mapByteMemM f = mapByteOffMemM (const f)+++-- @since 0.1.0+mapByteOffMemM ::+     forall e mr ma m s. (MemRead mr, MemAlloc ma, MonadPrim s m, Prim e)+  => (Off Word8 -> Word8 -> m e)+  -> mr+  -> m (FrozenMem ma)+mapByteOffMemM f r = do+  let bc@(Count n) = byteCountMem r+      c = Count n `countForProxyTypeOf` f 0 0+  mem <- allocMutMem c+  _ <- forByteOffMemM_ r 0 bc f+  -- let go i =+  --       when (i < n) $ do+  --         f i (indexByteOffMem r (Off i)) >>=+  --           writeOffMem mem (offAsProxy c (Off i))+  --         go (i + 1)+  -- go 0+  freezeMutMem mem+++-- | Iterate over a region of memory+forByteOffMemM_ ::+     (MemRead mr, MonadPrim s m, Prim e)+  => mr+  -> Off Word8+  -> Count e+  -> (Off Word8 -> e -> m b)+  -> m (Off Word8)+forByteOffMemM_ r (Off byteOff) c f =+  let n = coerce (toByteCount c) + byteOff+      Count k = byteCountProxy c+      go i+        | i < n = f (Off i) (indexByteOffMem r (Off i)) >> go (i + k)+        | otherwise = pure $ Off i+   in go byteOff++{-++loopShort :: Int -> (Int -> a -> Bool) -> (Int -> Int) -> a -> (Int -> a -> a) -> a+loopShort !startAt condition increment !initAcc f = go startAt initAcc+  where+    go !step !acc =+      if condition step acc+        then go (increment step) (f step acc)+        else acc+{-# INLINE loopShort #-}++loopShortM :: Monad m => Int -> (Int -> a -> m Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a+loopShortM !startAt condition increment !initAcc f = go startAt initAcc+  where+    go !step !acc = do+      shouldContinue <- condition step acc+      if shouldContinue+        then f step acc >>= go (increment step)+        else return acc+{-# INLINE loopShortM #-}++++ifoldlShortBytes ::+     (Prim e)+  => Off e+  -- ^ Initial offset to start at+  -> Count e+  -- ^ Total number of elements to iterate through+  -> (a -> Bool)+  -- ^ Continuation condition applied to an accumulator. When `False` it will terminate+  -- early+  -> (a -> Off e -> e -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> Bytes p+  -- ^ Memory region to iterate over+  -> a+ifoldlShortBytes off count g f initAcc mem =+  loopShort (coerce off) cond (+ 1) initAcc inner+  where+    inner !i !acc =+      let ioff = coerce i+       in f acc ioff $! indexOffBytes mem ioff+    {-# INLINE inner #-}+    cond i a = g a && i < k+    {-# INLINE cond #-}+    k = coerce count+{-# INLINE ifoldlShortBytes #-}+-}++++++++{-+++++ifoldlShortMem ::+     (Prim e, MemRead mr)+  => Off e+  -- ^ Initial offset to start at+  -> Count e+  -- ^ Total number of elements to iterate through+  -> (a -> Bool)+  -- ^ Continuation condition applied to an accumulator. When `False` it will terminate+  -- early+  -> (a -> Off e -> e -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+ifoldlShortMem off count g f initAcc mem = loop initAcc off+  where+    k = countToOff count + off+    loop !acc !i+      | g acc && i < k = loop (f acc i (indexOffMem mem i)) (i + 1)+      | otherwise = acc++  -- loopShort (coerce off) (\i a -> g a && i < k) (+ 1) initAcc $ \ !i !acc ->+  --   let ioff = coerce i+  --    in f acc ioff (indexOffMem mem ioff)+  -- where+  --   k = coerce count+{-# INLINE ifoldlShortMem #-}++ifoldlShortMemM ::+     (Prim e, MemRead mr, Monad m)+  => Off e+  -- ^ Initial offset to start at+  -> Count e+  -- ^ Total number of elements to iterate through+  -> (a -> m Bool)+  -- ^ Continuation condition applied to an accumulator. When `False` it will terminate+  -- early+  -> (a -> Off e -> e -> m a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> m a+ifoldlShortMemM off count g f initAcc mem =+  loopShortM (coerce off) (\i a -> (\p -> p && i < k) <$> g a) (+ 1) initAcc $ \ !i !acc ->+    let ioff = coerce i+     in f acc ioff (indexOffMem mem ioff)+  where+    k = coerce count+{-# INLINE ifoldlShortMemM #-}+++foldlShortMem ::+     (Prim e, MemRead mr)+  => Off e+  -- ^ Initial offset to start at+  -> Count e+  -- ^ Total number of elements to iterate through+  -> (a -> Bool)+  -- ^ Continuation condition applied to an accumulator. When `False` it will terminate+  -- early+  -> (a -> e -> a)+  -- ^ Folding function+  -> a+  -- ^ Initial accumulator+  -> mr+  -- ^ Memory region to iterate over+  -> a+foldlShortMem off count g f = ifoldlShortMem off count g (\a _ -> f a)+{-# INLINE foldlShortMem #-}+-}+++++-- -- | Iterate over a region of memory+-- loopMemM_ ::+--      (MemRead mr, MonadPrim s m, Prim e)+--   => r+--   -> Off Word8+--   -> Count e+--   -> (Count Word8 -> a -> Bool)+--   -> (Off Word8 -> e -> m b)+--   -> m (Off Word8)+-- foldlByteOffMemM_ r (Off byteOff) c f =+--   loopShortM byteOff (\i -> f (coerce i))+--   let n = coerce (toByteCount c) + byteOff+--       Count k = byteCountProxy c+--       go i+--         | i < n = f (Off i) (indexByteOffMem r (Off i)) >> go (i + k)+--         | otherwise = pure $ Off i+--    in go byteOff+++data MemView a = MemView+  { mvOffset :: {-# UNPACK #-} !(Off Word8)+  , mvCount  :: {-# UNPACK #-} !(Count Word8)+  , mvMem    :: !a+  }++data MMemView a s = MMemView+  { mmvOffset :: {-# UNPACK #-} !(Off Word8)+  , mmvCount  :: {-# UNPACK #-} !(Count Word8)+  , mmvMem    :: !(a s)+  }++izipWithByteOffMemM_ ::+     (MemRead mr1, MemRead mr2, MonadPrim s m, Prim e)+  => mr1+  -> Off Word8+  -> mr2+  -> Off Word8+  -> Count e+  -> (Off Word8 -> e -> Off Word8 -> e -> m b)+  -> m (Off Word8)+izipWithByteOffMemM_ r1 (Off byteOff1) r2 off2 c f =+  let n = coerce (toByteCount c) + byteOff1+      Count k = byteCountProxy c+      go i+        | i < n =+          let o1 = Off i+              o2 = Off i + off2+           in f o1 (indexByteOffMem r1 o1) o2 (indexByteOffMem r2 o2) >>+              go (i + k)+        | otherwise = pure $ Off i+   in go byteOff1+++izipWithOffMemM_ ::+     (MemRead mr1, MemRead mr2, MonadPrim s m, Prim e1, Prim e2)+  => mr1+  -> Off e1+  -> mr2+  -> Off e2+  -> Int+  -> (Off e1 -> e1 -> Off e2 -> e2 -> m b)+  -> m ()+izipWithOffMemM_ r1 off1 r2 off2 nc f =+  let n = nc + coerce off1+      go o1@(Off i) o2 =+        when (i < n) $+        f o1 (indexOffMem r1 o1) o2 (indexOffMem r2 o2) >> go (o1 + 1) (o2 + 1)+   in go off1 off2+++-- class Mut f => MFunctor f where+--   mmap :: (Elt f a, Elt f b, MonadPrim s m) => (a -> b) -> f a s -> m (f b s)++-- class Mut f => MTraverse f where+--   mmapM :: (Elt f a, Elt f b, MonadPrim s m) => (a -> m b) -> f a s -> m (f b s)++-- class MFunctor f => MApplicative f where+--   pureMut :: (Elt f a, MonadPrim s m) => a -> m (f a s)+--   liftMut ::+--     (Elt f a, Elt f b, Elt f c, MonadPrim s m) => (a -> b -> m c) -> f a s -> f b s -> m (f c s)++-- class MApplicative f => MMonad f where+--   bindMut ::+--     (Elt f a, Elt f b, MonadPrim s m) => f a s -> (a -> m b) -> m (f b s)++-- instance MFunctor MAddr where+--   mmap f maddr = do+--     Count n <- getCountMAddr maddr+--     maddr' <- allocMAddr (Count n)+--     let go i =+--           when (i < n) $ do+--             writeOffMAddr maddr' (Off i) . f =<< readOffMAddr maddr (Off i)+--             go (i + 1)+--     maddr' <$ go 0++-- instance MTraverse MAddr where+--   mmapM f maddr = do+--     Count n <- getCountMAddr maddr+--     maddr' <- allocMAddr (Count n)+--     let go i =+--           when (i < n) $ do+--             writeOffMAddr maddr' (Off i) =<< f =<< readOffMAddr maddr (Off i)+--             go (i + 1)+--     maddr' <$ go 0+++---------------------+-- Bytes instances --+---------------------++instance MemRead (Bytes p) where+  isSameMem = isSameBytes+  {-# INLINE isSameMem #-}+  byteCountMem = byteCountBytes+  {-# INLINE byteCountMem #-}+  indexOffMem = indexOffBytes+  {-# INLINE indexOffMem #-}+  indexByteOffMem = indexByteOffBytes+  {-# INLINE indexByteOffMem #-}+  copyByteOffToMBytesMem = copyByteOffBytesToMBytes+  {-# INLINE copyByteOffToMBytesMem #-}+  copyByteOffToPtrMem = copyByteOffBytesToPtr+  {-# INLINE copyByteOffToPtrMem #-}+  compareByteOffToPtrMem bytes1 off1 ptr2 off2 c =+    pure $! compareByteOffBytesToPtr bytes1 off1 ptr2 off2 c+  {-# INLINE compareByteOffToPtrMem #-}+  compareByteOffToBytesMem bytes1 off1 bytes2 off2 c =+    compareByteOffBytes bytes1 off1 bytes2 off2 c+  {-# INLINE compareByteOffToBytesMem #-}+  compareByteOffMem mem1 off1 bs off2 c =+    compareByteOffToBytesMem mem1 off1 bs off2 c+  {-# INLINE compareByteOffMem #-}++instance Typeable p => MemAlloc (MBytes p) where+  type FrozenMem (MBytes p) = Bytes p+  getByteCountMutMem = getByteCountMBytes+  {-# INLINE getByteCountMutMem #-}+  allocMutMem = allocMBytes+  {-# INLINE allocMutMem #-}+  thawMem = thawBytes+  {-# INLINE thawMem #-}+  freezeMutMem = freezeMBytes+  {-# INLINE freezeMutMem #-}+  reallocMutMem = reallocMBytes+  {-# INLINE reallocMutMem #-}++instance MemWrite (MBytes p) where+  isSameMutMem = isSameMBytes+  {-# INLINE isSameMutMem #-}+  readOffMutMem = readOffMBytes+  {-# INLINE readOffMutMem #-}+  readByteOffMutMem = readByteOffMBytes+  {-# INLINE readByteOffMutMem #-}+  writeOffMutMem = writeOffMBytes+  {-# INLINE writeOffMutMem #-}+  writeByteOffMutMem = writeByteOffMBytes+  {-# INLINE writeByteOffMutMem #-}+  moveByteOffToPtrMutMem = moveByteOffMBytesToPtr+  {-# INLINE moveByteOffToPtrMutMem #-}+  moveByteOffToMBytesMutMem = moveByteOffMBytesToMBytes+  {-# INLINE moveByteOffToMBytesMutMem #-}+  moveByteOffMutMem = moveByteOffToMBytesMutMem+  {-# INLINE moveByteOffMutMem #-}+  copyByteOffMem = copyByteOffToMBytesMem+  {-# INLINE copyByteOffMem #-}+  setMutMem = setMBytes+  {-# INLINE setMutMem #-}+++instance Show (Bytes p) where+  show b =+    Foldable.foldr' ($) "]" $+    ('[' :) : List.intersperse (',' :) (map (("0x" ++) .) (showsHexMem b))++instance Typeable p => IsList (Bytes p) where+  type Item (Bytes p) = Word8+  fromList = fromListMem+  {-# INLINE fromList #-}+  fromListN n = fromListZeroMemN_ (Count n)+  {-# INLINE fromListN #-}+  toList = toListMem+  {-# INLINE toList #-}++instance Eq (Bytes p) where+  b1 == b2 = isSameBytes b1 b2 || eqByteMem b1 b2+  {-# INLINE (==) #-}++instance Ord (Bytes p) where+  compare b1 b2 =+    compare n (byteCountBytes b2) <> compareByteOffBytes b1 0 b2 0 n+    where+      n = byteCountBytes b1+  {-# INLINE compare #-}++instance Typeable p => Semigroup.Semigroup (Bytes p) where+  (<>) = appendMem+  {-# INLINE (<>) #-}+  sconcat (x :| xs) = concatMem (x:xs)+  {-# INLINE sconcat #-}+  stimes i = cycleMemN (fromIntegral i)+  {-# INLINE stimes #-}++instance Typeable p => Monoid.Monoid (Bytes p) where+  mappend = appendMem+  {-# INLINE mappend #-}+  mconcat = concatMem+  {-# INLINE mconcat #-}+  mempty = emptyMem+  {-# INLINE mempty #-}+++-- | A list of `ShowS` which covert bytes to base16 encoded strings. Each element of the list+-- is a function that will convert one byte.+--+-- ====__Example__+--+-- >>> :set -XDataKinds+-- >>> import Data.Prim.Memory+-- >>> concatMap ($ " ") $ showsHexMem (fromListMem [1 :: Int16 .. 15] :: Bytes 'Inc)+-- "01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 0a 00 0b 00 0c 00 0d 00 0e 00 0f 00 "+--+-- @since 0.1.0+showsHexMem :: MemRead mr => mr -> [ShowS]+showsHexMem b = map toHex (toListMem b :: [Word8])+  where+    toHex b8 =+      (if b8 <= 0x0f+         then ('0' :)+         else id) .+      showHex b8++-- | Allocate a new region of memory and Ensure that it is filled with zeros before and+-- after it gets used. `PtrAccess` is not used directly, but instead is used to guarantee+-- that the memory is pinned and its contents will not get moved around by the garbage+-- collector.+--+-- @since 0.3.0+withScrubbedMutMem ::+     forall e ma m a.+     (MonadUnliftPrim RW m, Prim e, MemAlloc ma, PtrAccess RW (ma RW))+  => Count e+  -> (ma RW -> m a)+  -> m a+withScrubbedMutMem c f = do+  mem <- allocZeroMutMem c+  let _fptr = toForeignPtr mem :: IO (ForeignPtr e) -- Enforce the `PtrAccess` constraint.+  f mem `ufinally` setMutMem mem 0 (toByteCount c) 0+{-# INLINE withScrubbedMutMem #-}
+ src/Data/Prim/Memory/PArray.hs view
@@ -0,0 +1,355 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RoleAnnotations #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module      : Data.Prim.Memory.PArray+-- Copyright   : (c) Alexey Kuleshevich 2020+-- License     : BSD3+-- Maintainer  : Alexey Kuleshevich <alexey@kuleshevi.ch>+-- Stability   : experimental+-- Portability : non-portable+--+module Data.Prim.Memory.PArray+  ( PArray(..)+  , PMArray(..)+  , Pinned(..)+  , fromBytesPArray+  , toBytesPArray+  , fromUArrayPArray+  , toUArrayPArray+  , castPArray+  , fromMBytesPMArray+  , toMBytesPMArray+  , fromUMArrayPMArray+  , toUMArrayPMArray+  , castPMArray+  , allocPMArray+  , allocPinnedPMArray+  , allocAlignedPMArray+  , allocUnpinnedPMArray+  , shrinkPMArray+  , resizePMArray+  , reallocPMArray+  , isPinnedPArray+  , isPinnedPMArray++  , thawPArray+  , freezePMArray+  , sizePArray+  , getSizePMArray+  , readPMArray+  , writePMArray++  , setPMArray+  , copyPArrayToPMArray+  , movePMArrayToPMArray+  ) where++import Control.DeepSeq+import Control.Prim.Monad+import Data.Prim+import Data.Prim.Array (Size(..), UArray(..), UMArray(..))+import Data.Prim.Memory.Bytes+import Data.Prim.Memory.Fold+import Data.Prim.Memory.ForeignPtr+import Data.Prim.Memory.Internal+import Foreign.Prim++-- | An immutable array with elements of type @e@+newtype PArray (p :: Pinned) e = PArray (Bytes p)+  deriving (NFData, Semigroup, Monoid, MemRead)+type role PArray nominal nominal+++instance (Prim e, Eq e) => Eq (PArray p e) where+  (==) = eqMem @e+  {-# INLINE (==) #-}++instance (Prim e, Ord e) => Ord (PArray p e) where+  compare = compareMem @e+  {-# INLINE compare #-}++-- | A mutable array with elements of type @e@+newtype PMArray (p :: Pinned) e s = PMArray (MBytes p s)+  deriving (NFData, MemWrite)+type role PMArray nominal nominal nominal++-- | Read-only access, but it is not enforced.+instance PtrAccess s (PArray 'Pin e) where+  toForeignPtr = pure . toForeignPtrBytes . toBytesPArray+  {-# INLINE toForeignPtr #-}+  withPtrAccess b = withPtrBytes (toBytesPArray b)+  {-# INLINE withPtrAccess #-}+  withNoHaltPtrAccess b = withNoHaltPtrBytes (toBytesPArray b)+  {-# INLINE withNoHaltPtrAccess #-}++instance PtrAccess s (PMArray 'Pin e s) where+  toForeignPtr = pure . toForeignPtrMBytes . toMBytesPMArray+  {-# INLINE toForeignPtr #-}+  withPtrAccess mb = withPtrMBytes (toMBytesPMArray mb)+  {-# INLINE withPtrAccess #-}+  withNoHaltPtrAccess mb = withNoHaltPtrMBytes (toMBytesPMArray mb)+  {-# INLINE withNoHaltPtrAccess #-}++instance Typeable p => MemAlloc (PMArray p e) where+  type FrozenMem (PMArray p e) = PArray p e+  getByteCountMutMem = getByteCountMutMem . toMBytesPMArray+  {-# INLINE getByteCountMutMem #-}+  allocMutMem = fmap fromMBytesPMArray . allocMBytes+  {-# INLINE allocMutMem #-}+  thawMem = thawPArray+  {-# INLINE thawMem #-}+  freezeMutMem = freezePMArray+  {-# INLINE freezeMutMem #-}+  reallocMutMem mba = fmap fromMBytesPMArray . reallocMBytes (toMBytesPMArray mba)+  {-# INLINE reallocMutMem #-}++instance (Typeable p, Prim e) => IsList (PArray p e) where+  type Item (PArray p e) = e+  fromList = fromListMem+  fromListN n = fromListZeroMemN_ (Count n)+  toList = toListMem++instance Typeable p => IsString (PArray p Char) where+  fromString = fromListMem++instance (Show e, Prim e) => Show (PArray p e) where+  show = show . toListPArray+++toListPArray :: Prim e => PArray p e -> [e]+toListPArray = toListMem++castPArray :: PArray p e' -> PArray p e+castPArray = coerce++-- | /O(1)/ - Cast `PArray` to `UArray`+--+-- @since 0.3.0+toUArrayPArray :: PArray p e -> UArray e+toUArrayPArray pa = UArray (toByteArray# (toBytesPArray pa))+{-# INLINE toUArrayPArray #-}++-- | /O(1)/ - Cast `UArray` to `PArray`+--+-- @since 0.3.0+fromUArrayPArray :: UArray e -> PArray 'Inc e+fromUArrayPArray (UArray ba#) = fromBytesPArray (fromByteArray# ba#)+{-# INLINE fromUArrayPArray #-}++fromBytesPArray :: Bytes p -> PArray p e+fromBytesPArray = coerce++toBytesPArray :: PArray p e -> Bytes p+toBytesPArray = coerce++castPMArray :: PMArray p e' s -> PMArray p e s+castPMArray = coerce++fromMBytesPMArray :: MBytes p s -> PMArray p e s+fromMBytesPMArray = coerce++toMBytesPMArray :: PMArray p e s -> MBytes p s+toMBytesPMArray = coerce++-- | /O(1)/ - Cast `PMArray` to `UMArray`+--+-- @since 0.3.0+toUMArrayPMArray :: PMArray p e s -> UMArray e s+toUMArrayPMArray pa = UMArray (toMutableByteArray# (toMBytesPMArray pa))+{-# INLINE toUMArrayPMArray #-}++-- | /O(1)/ - Cast `UMArray` to `PMArray`+--+-- @since 0.3.0+fromUMArrayPMArray :: UMArray e s -> PMArray 'Inc e s+fromUMArrayPMArray (UMArray mba#) = fromMBytesPMArray (fromMutableByteArray# mba#)+{-# INLINE fromUMArrayPMArray #-}+++sizePArray :: forall e p. Prim e => PArray p e -> Size+sizePArray = (coerce :: Count e -> Size) . countBytes . toBytesPArray+{-# INLINE sizePArray #-}++getSizePMArray :: forall e p m s. (MonadPrim s m, Prim e) => PMArray p e s -> m Size+getSizePMArray = fmap (coerce :: Count e -> Size) . getCountMBytes . toMBytesPMArray+{-# INLINE getSizePMArray #-}++allocPMArray ::+     forall e p m s . (Typeable p, Prim e, MonadPrim s m) => Size -> m (PMArray p e s)+allocPMArray sz = fromMBytesPMArray <$> allocMBytes (coerce sz :: Count e)+{-# INLINE allocPMArray #-}++allocUnpinnedPMArray :: forall e m s . (MonadPrim s m, Prim e) => Size -> m (PMArray 'Inc e s)+allocUnpinnedPMArray sz = fromMBytesPMArray <$> allocUnpinnedMBytes (coerce sz :: Count e)+{-# INLINE allocUnpinnedPMArray #-}++allocPinnedPMArray :: forall e m s . (MonadPrim s m, Prim e) => Size -> m (PMArray 'Pin e s)+allocPinnedPMArray sz = fromMBytesPMArray <$> allocPinnedMBytes (coerce sz :: Count e)+{-# INLINE allocPinnedPMArray #-}++allocAlignedPMArray ::+     (MonadPrim s m, Prim e)+  => Count e -- ^ Size in number of bytes+  -> m (PMArray 'Pin e s)+allocAlignedPMArray = fmap fromMBytesPMArray . allocAlignedMBytes+{-# INLINE allocAlignedPMArray #-}++freezePMArray :: MonadPrim s m => PMArray p e s -> m (PArray p e)+freezePMArray = fmap fromBytesPArray . freezeMBytes . toMBytesPMArray+{-# INLINE freezePMArray #-}++thawPArray :: MonadPrim s m => PArray p e -> m (PMArray p e s)+thawPArray = fmap fromMBytesPMArray . thawBytes . toBytesPArray+{-# INLINE thawPArray #-}++-- | Shrink mutable bytes to new specified count of elements. The new count must be less+-- than or equal to the current count as reported by `getCountPMArray`.+shrinkPMArray ::+     forall e p m s. (MonadPrim s m, Prim e)+  => PMArray p e s+  -> Size+  -> m ()+shrinkPMArray mba sz = shrinkMBytes (toMBytesPMArray mba) (coerce sz :: Count e)+{-# INLINE shrinkPMArray #-}+++-- | Attempt to resize mutable bytes in place.+--+-- * New bytes might be allocated, with the copy of an old one.+-- * Old references should not be kept around to allow GC to claim it+-- * Old references should not be used to avoid undefined behavior+resizePMArray ::+     forall e p m s. (MonadPrim s m, Prim e)+  => PMArray p e s+  -> Size+  -> m (PMArray 'Inc e s)+resizePMArray mba sz =+  fromMBytesPMArray <$>+  resizeMBytes (toMBytesPMArray mba) (coerce sz :: Count e)+{-# INLINE resizePMArray #-}++reallocPMArray ::+     forall e p m s. (MonadPrim s m, Typeable p,  Prim e)+  => PMArray p e s+  -> Size+  -> m (PMArray p e s)+reallocPMArray mba sz =+  fromMBytesPMArray <$>+  reallocMBytes (toMBytesPMArray mba) (coerce sz :: Count e)+{-# INLINABLE reallocPMArray #-}+++isPinnedPArray :: PArray p e -> Bool+isPinnedPArray (PArray b) = isPinnedBytes b+{-# INLINE isPinnedPArray #-}++isPinnedPMArray :: PMArray p e s -> Bool+isPinnedPMArray (PMArray mb) = isPinnedMBytes mb+{-# INLINE isPinnedPMArray #-}++readPMArray :: (MonadPrim s m, Prim e) => PMArray p e s -> Int -> m e+readPMArray (PMArray mb) = readOffMBytes mb . coerce+{-# INLINE readPMArray #-}++writePMArray :: (MonadPrim s m, Prim e) => PMArray p e s -> Int -> e -> m ()+writePMArray (PMArray mb) o = writeOffMBytes mb (coerce o)+{-# INLINE writePMArray #-}++++setPMArray ::+     forall e p m s. (MonadPrim s m, Prim e)+  => PMArray p e s -- ^ Chunk of memory to fill+  -> Int -- ^ Offset in number of elements+  -> Size -- ^ Number of cells to fill+  -> e -- ^ A value to fill the cells with+  -> m ()+setPMArray (PMArray mb) off sz = setMBytes mb (coerce off) (coerce sz)+{-# INLINE setPMArray #-}++copyPArrayToPMArray ::+     forall e p m s. (MonadPrim s m, Prim e)+  => PArray p e+  -> Int+  -> PMArray p e s+  -> Int+  -> Size+  -> m ()+copyPArrayToPMArray ba srcOff mba dstOff sz =+  copyMem ba (coerce srcOff) mba (coerce dstOff) (coerce sz `countForProxyTypeOf` ba)+{-# INLINE copyPArrayToPMArray #-}++movePMArrayToPMArray ::+     forall e p m s. (MonadPrim s m, Prim e)+  => PMArray p e s+  -> Int+  -> PMArray p e s+  -> Int+  -> Size+  -> m ()+movePMArrayToPMArray ba srcOff mba dstOff sz =+  moveMutMem ba (coerce srcOff) mba (coerce dstOff) (coerce sz :: Count e)+{-# INLINE movePMArrayToPMArray #-}++++-- toPtrPArray :: PArray Pin e -> Ptr e+-- toPtrPArray (PArray ba#) = Ptr (byteArrayContents# ba#)+-- {-# INLINE toPtrPArray #-}++-- toPtrPMArray :: PMArray Pin e s -> Ptr e+-- toPtrPMArray (PMArray mba#) = Ptr (mutablePArrayContents# mba#)+-- {-# INLINE toPtrPMArray #-}++-- -- | Pointer access to immutable `PArray` should be for read only purposes, but it is+-- -- not enforced. Any mutation will break referential transparency+-- withPtrPArray :: MonadPrim s m => PArray Pin e -> (Ptr e -> m b) -> m b+-- withPtrPArray b f = do+--   res <- f (toPtrPArray b)+--   res <$ touch b+-- {-# INLINE withPtrPArray #-}++-- -- | Same as `withPtrPArray`, but is suitable for actions that don't terminate+-- withNoHaltPtrPArray :: MonadUnliftPrim s m => PArray Pin e -> (Ptr e -> m b) -> m b+-- withNoHaltPtrPArray b f = withAliveUnliftPrim b $ f (toPtrPArray b)+-- {-# INLINE withNoHaltPtrPArray #-}++-- withPtrPMArray :: MonadPrim s m => PMArray Pin e s -> (Ptr e -> m b) -> m b+-- withPtrPMArray mb f = do+--   res <- f (toPtrPMArray mb)+--   res <$ touch mb+-- {-# INLINE withPtrPMArray #-}++-- withNoHaltPtrPMArray :: MonadUnliftPrim s m => PMArray Pin e s -> (Ptr e -> m b) -> m b+-- withNoHaltPtrPMArray mb f = withAliveUnliftPrim mb $ f (toPtrPMArray mb)+-- {-# INLINE withNoHaltPtrPMArray #-}+++-- -- -- | Check if two byte arrays refer to pinned memory and compare their pointers.+-- -- isSamePArray :: PArray p1 e -> PArray p2 e -> Bool+-- -- isSamePArray (PArray b1#) (PArray b2#) = isTrue# (isSameByteArray# b1# b2#)+-- -- {-# INLINE[0] isSamePArray #-}+-- -- {-# RULES+-- -- "isSamePinnedPArray" isSamePArray = isSamePinnedPArray+-- --   #-}++-- -- -- | Perform pointer equality on pinned `PArray`.+-- -- isSamePinnedPArray :: PArray Pin e -> PArray Pin e -> Bool+-- -- isSamePinnedPArray pb e1 pb2 = toPtrPArray pb e1 == toPtrPArray pb e2+-- -- {-# INLINE isSamePinnedPArray #-}++++-- -- byteStringConvertError :: String -> a+-- -- byteStringConvertError msg = error $ "Cannot convert 'ByteString'. " ++ msg+-- -- {-# NOINLINE byteStringConvertError #-}+
− src/Data/Prim/Memory/PrimArray.hs
@@ -1,310 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE RoleAnnotations #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}--- |--- Module      : Data.Prim.Memory.PrimArray--- Copyright   : (c) Alexey Kuleshevich 2020--- License     : BSD3--- Maintainer  : Alexey Kuleshevich <alexey@kuleshevi.ch>--- Stability   : experimental--- Portability : non-portable----module Data.Prim.Memory.PrimArray-  ( PrimArray(..)-  , MPrimArray(..)-  , Pinned(..)-  , fromBytesPrimArray-  , toBytesPrimArray-  , castPrimArray-  , fromMBytesMPrimArray-  , toMBytesMPrimArray-  , castMPrimArray-  , allocMPrimArray-  , allocPinnedMPrimArray-  , allocAlignedMPrimArray-  , allocUnpinnedMPrimArray-  , shrinkMPrimArray-  , resizeMPrimArray-  , reallocMPrimArray-  , isPinnedPrimArray-  , isPinnedMPrimArray--  , thawPrimArray-  , freezeMPrimArray-  , sizePrimArray-  , getSizeMPrimArray-  , readMPrimArray-  , writeMPrimArray--  , setMPrimArray-  , copyPrimArrayToMPrimArray-  , moveMPrimArrayToMPrimArray-  ) where--import Control.DeepSeq-import Control.Prim.Monad-import Foreign.Prim-import Data.Prim-import Data.Prim.Memory.Bytes-import Data.Prim.Memory.Internal-import Data.Prim.Memory.ForeignPtr----- | An immutable array of bytes of type @e@-newtype PrimArray (p :: Pinned) e = PrimArray (Bytes p)-  deriving (NFData, Semigroup, Monoid, MemRead)-type role PrimArray nominal nominal---- | A mutable array of bytes of type @e@-newtype MPrimArray (p :: Pinned) e s = MPrimArray (MBytes p s)-  deriving (NFData, MemWrite)-type role MPrimArray nominal nominal nominal---- | Read-only access, but it is not enforced.-instance PtrAccess s (PrimArray 'Pin e) where-  toForeignPtr = pure . toForeignPtrBytes . toBytesPrimArray-  {-# INLINE toForeignPtr #-}-  withPtrAccess b = withPtrBytes (toBytesPrimArray b)-  {-# INLINE withPtrAccess #-}-  withNoHaltPtrAccess b = withNoHaltPtrBytes (toBytesPrimArray b)-  {-# INLINE withNoHaltPtrAccess #-}--instance PtrAccess s (MPrimArray 'Pin e s) where-  toForeignPtr = pure . toForeignPtrMBytes . toMBytesMPrimArray-  {-# INLINE toForeignPtr #-}-  withPtrAccess mb = withPtrMBytes (toMBytesMPrimArray mb)-  {-# INLINE withPtrAccess #-}-  withNoHaltPtrAccess mb = withNoHaltPtrMBytes (toMBytesMPrimArray mb)-  {-# INLINE withNoHaltPtrAccess #-}--instance Typeable p => MemAlloc (MPrimArray p e) where-  type FrozenMem (MPrimArray p e) = PrimArray p e-  getByteCountMem = getByteCountMem . toMBytesMPrimArray-  {-# INLINE getByteCountMem #-}-  allocMem = fmap fromMBytesMPrimArray . allocMBytes-  {-# INLINE allocMem #-}-  thawMem = thawPrimArray-  {-# INLINE thawMem #-}-  freezeMem = freezeMPrimArray-  {-# INLINE freezeMem #-}-  resizeMem mba = fmap fromMBytesMPrimArray . reallocMBytes (toMBytesMPrimArray mba)-  {-# INLINE resizeMem #-}--instance (Typeable p, Prim e) => IsList (PrimArray p e) where-  type Item (PrimArray p e) = e-  fromList = fromListMem-  fromListN n = fromListZeroMemN_ (Count n)-  toList = toListMem--instance Typeable p => IsString (PrimArray p Char) where-  fromString = fromListMem--instance (Show e, Prim e) => Show (PrimArray p e) where-  show = show . toListPrimArray---toListPrimArray :: Prim e => PrimArray p e -> [e]-toListPrimArray = toListMem--castPrimArray :: PrimArray p e' -> PrimArray p e-castPrimArray = coerce--fromBytesPrimArray :: Bytes p -> PrimArray p e-fromBytesPrimArray = coerce--toBytesPrimArray :: PrimArray p e -> Bytes p-toBytesPrimArray = coerce--castMPrimArray :: MPrimArray p e' s -> MPrimArray p e s-castMPrimArray = coerce--fromMBytesMPrimArray :: MBytes p s -> MPrimArray p e s-fromMBytesMPrimArray = coerce--toMBytesMPrimArray :: MPrimArray p e s -> MBytes p s-toMBytesMPrimArray = coerce--sizePrimArray :: forall e p. Prim e => PrimArray p e -> Size-sizePrimArray = (coerce :: Count e -> Size) . countBytes . toBytesPrimArray-{-# INLINE sizePrimArray #-}--getSizeMPrimArray :: forall e p m s. (MonadPrim s m, Prim e) => MPrimArray p e s -> m Size-getSizeMPrimArray = fmap (coerce :: Count e -> Size) . getCountMBytes . toMBytesMPrimArray-{-# INLINE getSizeMPrimArray #-}--allocMPrimArray ::-     forall e p m s . (Typeable p, Prim e, MonadPrim s m) => Size -> m (MPrimArray p e s)-allocMPrimArray sz = fromMBytesMPrimArray <$> allocMBytes (coerce sz :: Count e)-{-# INLINE allocMPrimArray #-}--allocUnpinnedMPrimArray :: forall e m s . (MonadPrim s m, Prim e) => Size -> m (MPrimArray 'Inc e s)-allocUnpinnedMPrimArray sz = fromMBytesMPrimArray <$> allocUnpinnedMBytes (coerce sz :: Count e)-{-# INLINE allocUnpinnedMPrimArray #-}--allocPinnedMPrimArray :: forall e m s . (MonadPrim s m, Prim e) => Size -> m (MPrimArray 'Pin e s)-allocPinnedMPrimArray sz = fromMBytesMPrimArray <$> allocPinnedMBytes (coerce sz :: Count e)-{-# INLINE allocPinnedMPrimArray #-}--allocAlignedMPrimArray ::-     (MonadPrim s m, Prim e)-  => Count e -- ^ Size in number of bytes-  -> m (MPrimArray 'Pin e s)-allocAlignedMPrimArray = fmap fromMBytesMPrimArray . allocAlignedMBytes-{-# INLINE allocAlignedMPrimArray #-}--freezeMPrimArray :: MonadPrim s m => MPrimArray p e s -> m (PrimArray p e)-freezeMPrimArray = fmap fromBytesPrimArray . freezeMBytes . toMBytesMPrimArray-{-# INLINE freezeMPrimArray #-}--thawPrimArray :: MonadPrim s m => PrimArray p e -> m (MPrimArray p e s)-thawPrimArray = fmap fromMBytesMPrimArray . thawBytes . toBytesPrimArray-{-# INLINE thawPrimArray #-}---- | Shrink mutable bytes to new specified count of elements. The new count must be less--- than or equal to the current count as reported by `getCountMPrimArray`.-shrinkMPrimArray ::-     forall e p m s. (MonadPrim s m, Prim e)-  => MPrimArray p e s-  -> Size-  -> m ()-shrinkMPrimArray mba sz = shrinkMBytes (toMBytesMPrimArray mba) (coerce sz :: Count e)-{-# INLINE shrinkMPrimArray #-}----- | Attempt to resize mutable bytes in place.------ * New bytes might be allocated, with the copy of an old one.--- * Old references should not be kept around to allow GC to claim it--- * Old references should not be used to avoid undefined behavior-resizeMPrimArray ::-     forall e p m s. (MonadPrim s m, Prim e)-  => MPrimArray p e s-  -> Size-  -> m (MPrimArray 'Inc e s)-resizeMPrimArray mba sz =-  fromMBytesMPrimArray <$>-  resizeMBytes (toMBytesMPrimArray mba) (coerce sz :: Count e)-{-# INLINE resizeMPrimArray #-}--reallocMPrimArray ::-     forall e p m s. (MonadPrim s m, Typeable p,  Prim e)-  => MPrimArray p e s-  -> Size-  -> m (MPrimArray p e s)-reallocMPrimArray mba sz =-  fromMBytesMPrimArray <$>-  reallocMBytes (toMBytesMPrimArray mba) (coerce sz :: Count e)-{-# INLINABLE reallocMPrimArray #-}---isPinnedPrimArray :: PrimArray p e -> Bool-isPinnedPrimArray (PrimArray b) = isPinnedBytes b-{-# INLINE isPinnedPrimArray #-}--isPinnedMPrimArray :: MPrimArray p e s -> Bool-isPinnedMPrimArray (MPrimArray mb) = isPinnedMBytes mb-{-# INLINE isPinnedMPrimArray #-}--readMPrimArray :: (MonadPrim s m, Prim e) => MPrimArray p e s -> Int -> m e-readMPrimArray (MPrimArray mb) = readOffMBytes mb . coerce-{-# INLINE readMPrimArray #-}--writeMPrimArray :: (MonadPrim s m, Prim e) => MPrimArray p e s -> Int -> e -> m ()-writeMPrimArray (MPrimArray mb) o = writeOffMBytes mb (coerce o)-{-# INLINE writeMPrimArray #-}----setMPrimArray ::-     forall e p m s. (MonadPrim s m, Prim e)-  => MPrimArray p e s -- ^ Chunk of memory to fill-  -> Int -- ^ Offset in number of elements-  -> Size -- ^ Number of cells to fill-  -> e -- ^ A value to fill the cells with-  -> m ()-setMPrimArray (MPrimArray mb) off sz = setMBytes mb (coerce off) (coerce sz)-{-# INLINE setMPrimArray #-}--copyPrimArrayToMPrimArray ::-     forall e p m s. (MonadPrim s m, Prim e)-  => PrimArray p e-  -> Int-  -> MPrimArray p e s-  -> Int-  -> Size-  -> m ()-copyPrimArrayToMPrimArray ba srcOff mba dstOff sz =-  copyMem ba (coerce srcOff) mba (coerce dstOff) (coerce sz `countForProxyTypeOf` ba)-{-# INLINE copyPrimArrayToMPrimArray #-}--moveMPrimArrayToMPrimArray ::-     forall e p m s. (MonadPrim s m, Prim e)-  => MPrimArray p e s-  -> Int-  -> MPrimArray p e s-  -> Int-  -> Size-  -> m ()-moveMPrimArrayToMPrimArray ba srcOff mba dstOff sz =-  moveMem ba (coerce srcOff) mba (coerce dstOff) (coerce sz :: Count e)-{-# INLINE moveMPrimArrayToMPrimArray #-}------ toPtrPrimArray :: PrimArray Pin e -> Ptr e--- toPtrPrimArray (PrimArray ba#) = Ptr (byteArrayContents# ba#)--- {-# INLINE toPtrPrimArray #-}---- toPtrMPrimArray :: MPrimArray Pin e s -> Ptr e--- toPtrMPrimArray (MPrimArray mba#) = Ptr (mutablePrimArrayContents# mba#)--- {-# INLINE toPtrMPrimArray #-}---- -- | Pointer access to immutable `PrimArray` should be for read only purposes, but it is--- -- not enforced. Any mutation will break referential transparency--- withPtrPrimArray :: MonadPrim s m => PrimArray Pin e -> (Ptr e -> m b) -> m b--- withPtrPrimArray b f = do---   res <- f (toPtrPrimArray b)---   res <$ touch b--- {-# INLINE withPtrPrimArray #-}---- -- | Same as `withPtrPrimArray`, but is suitable for actions that don't terminate--- withNoHaltPtrPrimArray :: MonadUnliftPrim s m => PrimArray Pin e -> (Ptr e -> m b) -> m b--- withNoHaltPtrPrimArray b f = withAliveUnliftPrim b $ f (toPtrPrimArray b)--- {-# INLINE withNoHaltPtrPrimArray #-}---- withPtrMPrimArray :: MonadPrim s m => MPrimArray Pin e s -> (Ptr e -> m b) -> m b--- withPtrMPrimArray mb f = do---   res <- f (toPtrMPrimArray mb)---   res <$ touch mb--- {-# INLINE withPtrMPrimArray #-}---- withNoHaltPtrMPrimArray :: MonadUnliftPrim s m => MPrimArray Pin e s -> (Ptr e -> m b) -> m b--- withNoHaltPtrMPrimArray mb f = withAliveUnliftPrim mb $ f (toPtrMPrimArray mb)--- {-# INLINE withNoHaltPtrMPrimArray #-}----- -- -- | Check if two byte arrays refer to pinned memory and compare their pointers.--- -- isSamePrimArray :: PrimArray p1 e -> PrimArray p2 e -> Bool--- -- isSamePrimArray (PrimArray b1#) (PrimArray b2#) = isTrue# (isSameByteArray# b1# b2#)--- -- {-# INLINE[0] isSamePrimArray #-}--- -- {-# RULES--- -- "isSamePinnedPrimArray" isSamePrimArray = isSamePinnedPrimArray--- --   #-}---- -- -- | Perform pointer equality on pinned `PrimArray`.--- -- isSamePinnedPrimArray :: PrimArray Pin e -> PrimArray Pin e -> Bool--- -- isSamePinnedPrimArray pb e1 pb2 = toPtrPrimArray pb e1 == toPtrPrimArray pb e2--- -- {-# INLINE isSamePinnedPrimArray #-}------ -- byteStringConvertError :: String -> a--- -- byteStringConvertError msg = error $ "Cannot convert 'ByteString'. " ++ msg--- -- {-# NOINLINE byteStringConvertError #-}-
src/Data/Prim/Memory/Text.hs view
@@ -14,10 +14,10 @@   , MText(..)   , Array(..)   , MArray(..)-  , toBytesArray-  , fromBytesArray-  , toMBytesMArray-  , fromMBytesMArray+  , fromArrayBytes+  , toArrayBytes+  , fromMArrayMBytes+  , toMArrayMBytes   ) where  import Data.Text.Array@@ -35,20 +35,32 @@     {-# UNPACK #-}!Int        -- offset (units of Word16, not Char)     {-# UNPACK #-}!Int        -- length (units of Word16, not Char) -toBytesArray :: Array -> Bytes 'Inc-toBytesArray (Array ba#) = Bytes ba#-{-# INLINE toBytesArray #-}+-- | /O(1)/ - Cast an immutable `Data.Text.Array.Array` from @text@ package to immutable `Bytes`+--+-- @since 0.3.0+fromArrayBytes :: Array -> Bytes 'Inc+fromArrayBytes (Array ba#) = Bytes ba#+{-# INLINE fromArrayBytes #-} -fromBytesArray :: Bytes p -> Array-fromBytesArray (Bytes ba#) = Array ba#-{-# INLINE fromBytesArray #-}+-- | /O(1)/ - Cast immutable `Bytes` to an immutable `Data.Text.Array.Array` from @text@ package+--+-- @since 0.3.0+toArrayBytes :: Bytes p -> Array+toArrayBytes (Bytes ba#) = Array ba#+{-# INLINE toArrayBytes #-} -toMBytesMArray :: MArray s -> MBytes 'Inc s-toMBytesMArray (MArray mba#) = MBytes mba#-{-# INLINE toMBytesMArray #-}+-- | /O(1)/ - Cast a mutable `Data.Text.Array.MArray` from @text@ package to mutable `MBytes`+--+-- @since 0.3.0+fromMArrayMBytes :: MArray s -> MBytes 'Inc s+fromMArrayMBytes (MArray mba#) = MBytes mba#+{-# INLINE fromMArrayMBytes #-} -fromMBytesMArray :: MBytes p s -> MArray s-fromMBytesMArray (MBytes ba#) = MArray ba#-{-# INLINE fromMBytesMArray #-}+-- | /O(1)/ - Cast mutable `MBytes` to a mutable `Data.Text.Array.MArray` from @text@ package+--+-- @since 0.3.0+toMArrayMBytes :: MBytes p s -> MArray s+toMArrayMBytes (MBytes ba#) = MArray ba#+{-# INLINE toMArrayMBytes #-}