-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Unified interface for memory managemenet. -- -- Please see the README on GitHub at -- https://github.com/lehins/primal#readme @package primal-memory @version 0.3.0.0 module Data.Prim.Memory.Ptr copyPtrToMBytes :: (MonadPrim s m, Prim e) => Ptr e -> Off e -> MBytes p s -> Off e -> Count e -> m () movePtrToMBytes :: (MonadPrim s m, Prim e) => Ptr e -> Off e -> MBytes p s -> Off e -> Count e -> m () copyBytesToPtr :: (MonadPrim s m, Prim e) => Bytes p -> Off e -> Ptr e -> Off e -> Count e -> m () copyMBytesToPtr :: (MonadPrim s m, Prim e) => MBytes p s -> Off e -> Ptr e -> Off e -> Count e -> m () moveMBytesToPtr :: (MonadPrim s m, Prim e) => MBytes p s -> Off e -> Ptr e -> Off e -> Count e -> m () copyByteOffPtrToMBytes :: (MonadPrim s m, Prim e) => Ptr e -> Off Word8 -> MBytes p s -> Off Word8 -> Count e -> m () moveByteOffPtrToMBytes :: (MonadPrim s m, Prim e) => Ptr e -> Off Word8 -> MBytes p s -> Off Word8 -> Count e -> m () copyByteOffBytesToPtr :: (MonadPrim s m, Prim e) => Bytes p -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m () copyByteOffMBytesToPtr :: (MonadPrim s m, Prim e) => MBytes p s -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m () moveByteOffMBytesToPtr :: (MonadPrim s m, Prim e) => MBytes p s -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m () compareByteOffBytesToPtr :: Prim e => Bytes p -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> Ordering compareByteOffPtrToBytes :: Prim e => Ptr e -> Off Word8 -> Bytes p -> Off Word8 -> Count e -> Ordering module Data.Prim.Memory.ByteString -- | Mutable version of a ByteString newtype MByteString s MByteString :: ByteString -> MByteString s -- | Builders denote sequences of bytes. They are Monoids -- where mempty is the zero-length sequence and mappend is -- concatenation, which runs in O(1). data Builder -- | Convert Bytes into a bytestring Builder toBuilderBytes :: Bytes p -> Builder -- | O(n) - Allocate Bytes and fill them using the supplied -- Builder fromBuilderBytes :: Builder -> Bytes 'Pin -- | A space-efficient representation of a Word8 vector, supporting -- many efficient operations. -- -- A ByteString contains 8-bit bytes, or by using the operations -- from Data.ByteString.Char8 it can be interpreted as containing -- 8-bit characters. data ByteString PS :: {-# UNPACK #-} !ForeignPtr Word8 -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> ByteString -- | O(1) - Cast immutable Bytes to an immutable -- ByteString toByteStringBytes :: Bytes 'Pin -> ByteString -- | O(n) - Convert a strict ByteString to Bytes. fromByteStringBytes :: Typeable p => ByteString -> Bytes p -- | O(n) - Allocate Bytes and fill them with the contents of -- a lazy ByteString fromLazyByteStringBytes :: ByteString -> Bytes 'Pin withPtrByteString :: MonadPrim s m => ByteString -> (Ptr a -> m b) -> m b withNoHaltPtrByteString :: MonadUnliftPrim s m => ByteString -> (Ptr a -> m b) -> m b -- | A compact representation of a Word8 vector. -- -- It has a lower memory overhead than a ByteString and and does -- not contribute to heap fragmentation. It can be converted to or from a -- ByteString (at the cost of copying the string data). It -- supports very few other operations. -- -- It is suitable for use as an internal representation for code that -- needs to keep many short strings in memory, but it should not -- be used as an interchange type. That is, it should not generally be -- used in public APIs. The ByteString type is usually more -- suitable for use in interfaces; it is more flexible and it supports a -- wide range of operations. data ShortByteString SBS :: ByteArray# -> ShortByteString -- | O(1) - Cast an immutable Bytes to an immutable -- ShortByteString toShortByteStringBytes :: Bytes p -> ShortByteString -- | O(1) - Cast an immutable ShortByteString to an immutable -- Bytes fromShortByteStringBytes :: ShortByteString -> Bytes 'Inc byteStringConvertError :: String -> a module Data.Prim.Memory.ForeignPtr -- | For memory allocated as pinned it is possible to operate on it with a -- Ptr. Any data type that is backed by such memory can have a -- PtrAccess instance. The simplest way is to convert it to a -- ForeignPtr and other functions will come for free. class PtrAccess s p -- | Convert to ForeignPtr. toForeignPtr :: (PtrAccess s p, MonadPrim s m) => p -> m (ForeignPtr a) -- | Apply an action to the raw memory Ptr to which the data type -- point to. Type of data stored in memory is left ambiguous -- intentionaly, so that the user can choose how to treat the memory -- content. withPtrAccess :: (PtrAccess s p, MonadPrim s m) => p -> (Ptr a -> m b) -> m b -- | See this GHC issue #17746 and related to it in order to get -- more insight why this is needed. withNoHaltPtrAccess :: (PtrAccess s p, MonadUnliftPrim s m) => p -> (Ptr a -> m b) -> m b -- | The type ForeignPtr represents references to objects that are -- maintained in a foreign language, i.e., that are not part of the data -- structures usually managed by the Haskell storage manager. The -- essential difference between ForeignPtrs and vanilla memory -- references of type Ptr a is that the former may be associated -- with finalizers. A finalizer is a routine that is invoked when -- the Haskell storage manager detects that - within the Haskell heap and -- stack - there are no more references left that are pointing to the -- ForeignPtr. Typically, the finalizer will, then, invoke -- routines in the foreign language that free the resources bound by the -- foreign object. -- -- The ForeignPtr is parameterised in the same way as Ptr. -- The type argument of ForeignPtr should normally be an instance -- of class Storable. data ForeignPtr a ForeignPtr :: Addr# -> ForeignPtrContents -> ForeignPtr a -- | This function casts a ForeignPtr parameterised by one type into -- another type. castForeignPtr :: ForeignPtr a -> ForeignPtr b -- | This function extracts the pointer component of a foreign pointer. -- This is a potentially dangerous operations, as if the argument to -- unsafeForeignPtrToPtr is the last usage occurrence of the given -- foreign pointer, then its finalizer(s) will be run, which potentially -- invalidates the plain pointer just obtained. Hence, -- touchForeignPtr must be used wherever it has to be guaranteed -- that the pointer lives on - i.e., has another usage occurrence. -- -- To avoid subtle coding errors, hand written marshalling code should -- preferably use withForeignPtr rather than combinations of -- unsafeForeignPtrToPtr and touchForeignPtr. However, the -- latter routines are occasionally preferred in tool generated -- marshalling code. unsafeForeignPtrToPtr :: ForeignPtr a -> Ptr a data ForeignPtrContents PlainForeignPtr :: !IORef Finalizers -> ForeignPtrContents MallocPtr :: MutableByteArray# RealWorld -> !IORef Finalizers -> ForeignPtrContents PlainPtr :: MutableByteArray# RealWorld -> ForeignPtrContents -- | Advances the given address by the given offset in number of elemeents. -- This operation does not affect associated finalizers in any way. plusOffForeignPtr :: Prim e => ForeignPtr e -> Off e -> ForeignPtr e -- | Advances the given address by the given offset in bytes. This -- operation does not affect associated finalizers in any way. plusByteOffForeignPtr :: ForeignPtr e -> Off Word8 -> ForeignPtr e -- | Find the offset in number of elements that is between the two pointers -- by subtracting one address from another and dividing the result by the -- size of an element. minusOffForeignPtr :: Prim e => ForeignPtr e -> ForeignPtr e -> Off e -- | Same as minusOffForeignPtr, but will also return the remainder -- in bytes that is left over. minusOffRemForeignPtr :: Prim e => ForeignPtr e -> ForeignPtr e -> (Off e, Off Word8) -- | Find the offset in bytes that is between the two pointers by -- subtracting one address from another. minusByteOffForeignPtr :: ForeignPtr e -> ForeignPtr e -> Off Word8 -- | 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. -- -- It is also important not to run non-terminating actions, because GHC -- can optimize away the logic that runs after the action and GC will -- happen before the action get's a chance to finish resulting in corrupt -- memory. Whenever you have an action that runs an infinite loop or ends -- in an exception throwing, make sure to use withNoHaltForeignPtr -- instead. withForeignPtr :: MonadPrim s m => ForeignPtr e -> (Ptr e -> m b) -> m b -- | Same thing as withForeignPtr except it should be used for never -- ending actions. See withNoHaltPtrAccess for more information on -- how this differes from withForeignPtr. withNoHaltForeignPtr :: MonadUnliftPrim s m => ForeignPtr e -> (Ptr e -> m b) -> m b -- | Similar to mallocPlainForeignPtr, except instead of -- Storable we use Prim and we are not restricted to -- IO, since finalizers are not possible with PlaintPtr mallocPlainForeignPtr :: forall e m s. (MonadPrim s m, Prim e) => m (ForeignPtr e) -- | Similar to mallocPlainForeignPtrArray, except instead of -- Storable we use Prim. mallocCountPlainForeignPtr :: (MonadPrim s m, Prim e) => Count e -> m (ForeignPtr e) -- | Just like mallocCountForeignPtr, but memory is also aligned -- according to Prim instance mallocCountPlainForeignPtrAligned :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (ForeignPtr e) -- | Lifted version of mallocForeignPtrBytes. mallocByteCountPlainForeignPtr :: MonadPrim s m => Count Word8 -> m (ForeignPtr e) -- | Lifted version of mallocForeignPtrAlignedBytes. mallocByteCountPlainForeignPtrAligned :: MonadPrim s m => Count Word8 -> Int -> m (ForeignPtr e) -- | Lifted version of finalizeForeignPtr. finalizeForeignPtr :: MonadPrim RW m => ForeignPtr e -> m () -- | A finalizer is represented as a pointer to a foreign function that, at -- finalisation time, gets as an argument a plain pointer variant of the -- foreign pointer that the finalizer is associated with. -- -- Note that the foreign function must use the ccall -- calling convention. type FinalizerPtr a = FunPtr Ptr a -> IO () -- | Lifted version of newForeignPtr. newForeignPtr :: MonadPrim RW m => FinalizerPtr e -> Ptr e -> m (ForeignPtr e) -- | Lifted version of newForeignPtr_. newForeignPtr_ :: MonadPrim RW m => Ptr e -> m (ForeignPtr e) -- | Lifted version of touchForeignPtr. touchForeignPtr :: MonadPrim s m => ForeignPtr e -> m () -- | Simila to mallocForeignPtr, except it operates on Prim, -- instead of Storable. mallocForeignPtr :: forall e m. (MonadPrim RW m, Prim e) => m (ForeignPtr e) -- | Similar to mallocForeignPtrArray, except instead of -- Storable we use Prim. mallocCountForeignPtr :: (MonadPrim RW m, Prim e) => Count e -> m (ForeignPtr e) -- | Just like mallocCountForeignPtr, but memory is also aligned -- according to Prim instance mallocCountForeignPtrAligned :: (MonadPrim RW m, Prim e) => Count e -> m (ForeignPtr e) -- | Lifted version of mallocForeignPtrBytes. mallocByteCountForeignPtr :: MonadPrim RW m => Count Word8 -> m (ForeignPtr e) -- | Lifted version of mallocForeignPtrAlignedBytes. mallocByteCountForeignPtrAligned :: MonadPrim RW m => Count Word8 -> Int -> m (ForeignPtr e) -- | Lifted version of addForeignPtrFinalizer addForeignPtrFinalizer :: MonadPrim RW m => FinalizerPtr e -> ForeignPtr e -> m () type FinalizerEnvPtr env a = FunPtr Ptr env -> Ptr a -> IO () -- | Lifted version of newForeignPtrEnv. newForeignPtrEnv :: MonadPrim RW m => FinalizerEnvPtr env e -> Ptr env -> Ptr e -> m (ForeignPtr e) -- | Lifted version of addForeignPtrFinalizerEnv addForeignPtrFinalizerEnv :: MonadPrim RW m => FinalizerEnvPtr env e -> Ptr env -> ForeignPtr e -> m () -- | Unlifted version of newConcForeignPtr newConcForeignPtr :: MonadUnliftPrim RW m => Ptr e -> m () -> m (ForeignPtr e) -- | Unlifted version of addForeignPtrConcFinalizer addForeignPtrConcFinalizer :: MonadUnliftPrim RW m => ForeignPtr a -> m () -> m () toForeignPtrBytes :: Bytes 'Pin -> ForeignPtr e toForeignPtrMBytes :: MBytes 'Pin s -> ForeignPtr e instance Data.Prim.Memory.ForeignPtr.PtrAccess GHC.Prim.RealWorld (GHC.ForeignPtr.ForeignPtr a) instance Data.Prim.Memory.ForeignPtr.PtrAccess s Data.ByteString.Internal.ByteString instance Data.Prim.Memory.ForeignPtr.PtrAccess s (Data.Prim.Memory.ByteString.MByteString s) instance Data.Prim.Memory.ForeignPtr.PtrAccess s (Data.Prim.Memory.Bytes.Internal.Bytes 'Data.Prim.Memory.Bytes.Internal.Pin) instance Data.Prim.Memory.ForeignPtr.PtrAccess s (Data.Prim.Memory.Bytes.Internal.MBytes 'Data.Prim.Memory.Bytes.Internal.Pin s) module Data.Prim.Memory.Text -- | A space efficient, packed, unboxed Unicode text type. data Text Text :: {-# UNPACK #-} !Array -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> Text -- | Mutable version of a Text data MText s MText :: {-# UNPACK #-} !MArray s -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> MText s -- | Immutable array type. -- -- The Array constructor is exposed since text-1.1.1.3 data Array Array :: ByteArray# -> Array [aBA] :: Array -> ByteArray# -- | Mutable array type, for use in the ST monad. -- -- The MArray constructor is exposed since text-1.1.1.3 data MArray s MArray :: MutableByteArray# s -> MArray s [maBA] :: MArray s -> MutableByteArray# s -- | O(1) - Cast an immutable Array from text -- package to immutable Bytes fromArrayBytes :: Array -> Bytes 'Inc -- | O(1) - Cast immutable Bytes to an immutable Array -- from text package toArrayBytes :: Bytes p -> Array -- | O(1) - Cast a mutable MArray from text package -- to mutable MBytes fromMArrayMBytes :: MArray s -> MBytes 'Inc s -- | O(1) - Cast mutable MBytes to a mutable MArray -- from text package toMArrayMBytes :: MBytes p s -> MArray s module Data.Prim.Memory.Fold foldlMem :: forall e a mr. (Prim e, MemRead mr) => (a -> e -> a) -> a -> mr -> a ifoldlMem :: forall e a mr. (Prim e, MemRead mr) => (a -> Off e -> e -> a) -> a -> mr -> a ifoldlOffMem :: forall e a mr. (Prim e, MemRead mr) => Off e -> Count e -> (a -> Off e -> e -> a) -> a -> mr -> a foldlLazyMem :: forall e a mr. (Prim e, MemRead mr) => (a -> e -> a) -> a -> mr -> a ifoldlLazyMem :: forall e a mr. (Prim e, MemRead mr) => (a -> Off e -> e -> a) -> a -> mr -> a ifoldlLazyOffMem :: forall e a mr. (Prim e, MemRead mr) => Off e -> Count e -> (a -> Off e -> e -> a) -> a -> mr -> a foldrMem :: forall e a mr. (Prim e, MemRead mr) => (e -> a -> a) -> a -> mr -> a ifoldrMem :: forall e a mr. (Prim e, MemRead mr) => (Off e -> e -> a -> a) -> a -> mr -> a ifoldrOffMem :: forall e a mr. (Prim e, MemRead mr) => Off e -> Count e -> (Off e -> e -> a -> a) -> a -> mr -> a -- | Right fold with a lazy accumulator foldrLazyMem :: forall e a mr. (Prim e, MemRead mr) => (e -> a -> a) -> a -> mr -> a -- | Right fold with a lazy accumulator using an offset aware function ifoldrLazyMem :: forall e a mr. (Prim e, MemRead mr) => (Off e -> e -> a -> a) -> a -> mr -> a ifoldrLazyOffMem :: forall e a mr. (Prim e, MemRead mr) => Off e -> Count e -> (Off e -> e -> a -> a) -> a -> mr -> a foldMapOffMem :: forall e m mr. (Prim e, MemRead mr, Monoid m) => Off e -> Count e -> (e -> m) -> mr -> m ifoldMapOffMem :: forall e m mr. (Prim e, MemRead mr, Monoid m) => Off e -> Count e -> (Off e -> e -> m) -> mr -> m anyOffMem :: forall e mr. (Prim e, MemRead mr) => Off e -> Count e -> (e -> Bool) -> mr -> Bool ianyOffMem :: forall e mr. (Prim e, MemRead mr) => Off e -> Count e -> (Off e -> e -> Bool) -> mr -> Bool anyMem :: forall e mr. (Prim e, MemRead mr) => (e -> Bool) -> mr -> Bool ianyMem :: forall e mr. (Prim e, MemRead mr) => (Off e -> e -> Bool) -> mr -> Bool allOffMem :: forall e mr. (Prim e, MemRead mr) => Off e -> Count e -> (e -> Bool) -> mr -> Bool iallOffMem :: forall e mr. (Prim e, MemRead mr) => Off e -> Count e -> (Off e -> e -> Bool) -> mr -> Bool allMem :: forall e mr. (Prim e, MemRead mr) => (e -> Bool) -> mr -> Bool iallMem :: forall e mr. (Prim e, MemRead mr) => (Off e -> e -> Bool) -> mr -> Bool eqMem :: forall e mr. (Prim e, Eq e, MemRead mr) => mr -> mr -> Bool -- | 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. -- -- eqOffMem :: (Prim e, Eq e, MemRead mr1, MemRead mr2) => mr1 -> Off e -> mr2 -> Off e -> Count e -> Bool eqOffMemBinary :: forall e mr1 mr2. (Prim e, MemRead mr1, MemRead mr2) => mr1 -> Off e -> mr2 -> Off e -> Count e -> Bool 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 -- | 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 -- | 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. compareMem :: forall e mr. (Prim e, Ord e, MemRead mr) => mr -> mr -> Ordering -- | 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. -- -- compareOffMem :: (Prim e, Ord e, MemRead mr1, MemRead mr2) => mr1 -> Off e -> mr2 -> Off e -> Count e -> Ordering module Data.Prim.Memory.Bytes -- | An immutable region of memory which was allocated either as pinned or -- unpinned. -- -- Constructor is not exported for safety. Violating type level -- Pinned kind is very dangerous. Type safe constructor -- fromByteArray# and unwrapper toByteArray# should be used -- instead. As a backdoor, of course, the actual constructor is available -- from Data.Prim.Memory.Internal data Bytes (p :: Pinned) -- | Unwrap Bytes to get the underlying ByteArray#. toByteArray# :: Bytes p -> ByteArray# -- | Wrap ByteArray# into Bytes fromByteArray# :: ByteArray# -> Bytes 'Inc cloneBytes :: Typeable p => Bytes p -> Bytes p emptyBytes :: Bytes p eqBytes :: Bytes p1 -> Bytes p2 -> Bool singletonBytes :: forall e p. (Prim e, Typeable p) => e -> Bytes p isEmptyBytes :: Bytes p -> Bool -- | Allocated memory is not cleared, so make sure to fill it in properly, -- otherwise you might find some garbage there. createBytes :: forall p e b s m. (Prim e, Typeable p, MonadPrim s m) => Count e -> (MBytes p s -> m b) -> m (b, Bytes p) createBytes_ :: forall p e b s m. (Prim e, Typeable p, MonadPrim s m) => Count e -> (MBytes p s -> m b) -> m (Bytes p) createBytesST :: forall p e b. (Prim e, Typeable p) => Count e -> (forall s. MBytes p s -> ST s b) -> (b, Bytes p) createBytesST_ :: forall p e b. (Prim e, Typeable p) => Count e -> (forall s. MBytes p s -> ST s b) -> Bytes p -- | In GHC there is a distinction between pinned and unpinned memory. -- -- Pinned memory is such that when allocated, it is guaranteed not to -- move throughout the lifetime of a program. In other words the address -- pointer that refers to allocated bytes will not change until the -- associated ByteArray# or MutableByteArray# is no longer -- referenced anywhere in the program at which point it gets garbage -- collected. On the other hand unpinned memory can be moved around -- during GC, which helps to reduce memory fragmentation. -- -- Pinned/unpinnned choice during allocation is a bit of a lie, because -- when attempt is made to allocate memory as unpinned, but requested -- size is a bit more than a certain threshold (somewhere around 3KiB) it -- might still be allocated as pinned. Because of that fact through out -- the "primal" universe there is a distinction between memory that is -- either Pinned or Inconclusive. -- -- It is possible to use one of toPinnedBytes or -- toPinnedMBytes to get a conclusive type. data Pinned -- | Pinned, which indicates that allocated memory will not move Pin :: Pinned -- | Inconclusive, thus memory could be pinned or unpinned Inc :: Pinned isPinnedBytes :: Bytes p -> Bool isPinnedMBytes :: MBytes p d -> Bool toPinnedBytes :: Bytes p -> Maybe (Bytes 'Pin) toPinnedMBytes :: MBytes p s -> Maybe (MBytes 'Pin s) toInconclusiveBytes :: Bytes p -> Bytes 'Inc toInconclusiveMBytes :: MBytes p e -> MBytes 'Inc e relaxPinnedBytes :: Bytes 'Pin -> Bytes p relaxPinnedMBytes :: MBytes 'Pin e -> MBytes p e ensurePinnedBytes :: Bytes p -> Bytes 'Pin ensurePinnedMBytes :: MonadPrim s m => MBytes p s -> m (MBytes 'Pin s) -- | Mutable region of memory which was allocated either as pinned or -- unpinned. -- -- Constructor is not exported for safety. Violating type level -- Pinned kind is very dangerous. Type safe constructor -- fromMutableByteArray# and unwrapper toMutableByteArray# -- should be used instead. As a backdoor, of course, the actual -- constructor is available in Data.Prim.Memory.Internal module -- and specially unsafe function castPinnedMBytes was crafted. data MBytes (p :: Pinned) s -- | Unwrap MBytes to get the underlying MutableByteArray#. toMutableByteArray# :: MBytes p s -> MutableByteArray# s -- | Wrap MutableByteArray# into MBytes fromMutableByteArray# :: MutableByteArray# s -> MBytes 'Inc s -- | Check if two byte arrays refer to pinned memory and compare their -- pointers. isSameBytes :: Bytes p1 -> Bytes p2 -> Bool -- | Perform pointer equality on pinned Bytes. isSamePinnedBytes :: Bytes 'Pin -> Bytes 'Pin -> Bool -- | Check if two mutable bytes pointers refer to the same memory isSameMBytes :: MBytes p1 s -> MBytes p2 s -> Bool indexOffBytes :: Prim e => Bytes p -> Off e -> e indexByteOffBytes :: Prim e => Bytes p -> Off Word8 -> e byteCountBytes :: Bytes p -> Count Word8 -- | How many elements of type a fits into bytes completely. In -- order to get a possible count of leftover bytes use -- countRemBytes countBytes :: Prim e => Bytes p -> Count e -- | Get the count of elements of type a that can fit into bytes -- as well as the slack number of bytes that would be leftover in case -- when total number of bytes available is not exactly divisable by the -- size of the element that will be stored in the memory chunk. countRemBytes :: forall e p. Prim e => Bytes p -> (Count e, Count Word8) compareBytes :: Prim e => Bytes p1 -> Off e -> Bytes p2 -> Off e -> Count e -> Ordering compareByteOffBytes :: Prim e => Bytes p1 -> Off Word8 -> Bytes p2 -> Off Word8 -> Count e -> Ordering thawBytes :: MonadPrim s m => Bytes p -> m (MBytes p s) freezeMBytes :: MonadPrim s m => MBytes p s -> m (Bytes p) allocMBytes :: forall p e s m. (Typeable p, Prim e, MonadPrim s m) => Count e -> m (MBytes p s) singletonMBytes :: forall e p m s. (Prim e, Typeable p, MonadPrim s m) => e -> m (MBytes p s) allocPinnedMBytes :: (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Pin s) allocAlignedMBytes :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Pin s) allocUnpinnedMBytes :: (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Inc s) allocZeroMBytes :: (MonadPrim s m, Prim e, Typeable p) => Count e -> m (MBytes p s) allocZeroPinnedMBytes :: (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Pin s) allocZeroAlignedMBytes :: (MonadPrim s m, Prim e) => Count e -> m (MBytes 'Pin s) -- | 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 -- getCountMBytes. shrinkMBytes :: (MonadPrim s m, Prim e) => MBytes p s -> Count e -> m () -- | Attempt to resize mutable bytes in place. -- -- resizeMBytes :: (MonadPrim s m, Prim e) => MBytes p s -> Count e -> m (MBytes 'Inc s) reallocMBytes :: forall e p m s. (MonadPrim s m, Typeable p, Prim e) => MBytes p s -> Count e -> m (MBytes p s) -- | This function allows the change of state token. Use with care, because -- it can allow mutation to escape the ST monad. coerceStateMBytes :: MBytes p s' -> MBytes p s cloneMBytes :: (MonadPrim s m, Typeable p) => MBytes p s -> m (MBytes p s) withCloneMBytes :: (MonadPrim s m, Typeable p) => Bytes p -> (MBytes p s -> m a) -> m (a, Bytes p) withCloneMBytes_ :: (MonadPrim s m, Typeable p) => Bytes p -> (MBytes p s -> m a) -> m (Bytes p) withCloneMBytesST :: Typeable p => Bytes p -> (forall s. MBytes p s -> ST s a) -> (a, Bytes p) withCloneMBytesST_ :: Typeable p => Bytes p -> (forall s. MBytes p s -> ST s a) -> Bytes p -- | Same as loadListMutMem loadListMBytes :: (Prim e, Typeable p, MonadPrim s m) => [e] -> MBytes p s -> m ([e], Count e) -- | Same as loadListMutMem_ loadListMBytes_ :: (Prim e, Typeable p, MonadPrim s m) => [e] -> MBytes p s -> m () copyBytesToMBytes :: (MonadPrim s m, Prim e) => Bytes ps -> Off e -> MBytes pd s -> Off e -> Count e -> m () moveMBytesToMBytes :: (MonadPrim s m, Prim e) => MBytes ps s -> Off e -> MBytes pd s -> Off e -> Count e -> m () getByteCountMBytes :: MonadPrim s m => MBytes p s -> m (Count Word8) -- | How many elements of type a fits into bytes completely. In -- order to get any number of leftover bytes use countRemBytes getCountMBytes :: (MonadPrim s m, Prim e) => MBytes p s -> m (Count e) -- | Get the number of elements of type a that can fit into bytes -- as well as the slack number of bytes that would be leftover in case -- when total number of bytes available is not exactly divisable by the -- size of the element that will be stored in the memory chunk. getCountRemOfMBytes :: forall e p s m. (MonadPrim s m, Prim e) => MBytes p s -> m (Count e, Count Word8) readOffMBytes :: (MonadPrim s m, Prim e) => MBytes p s -> Off e -> m e readByteOffMBytes :: (MonadPrim s m, Prim e) => MBytes p s -> Off Word8 -> m e writeOffMBytes :: (MonadPrim s m, Prim e) => MBytes p s -> Off e -> e -> m () writeByteOffMBytes :: (MonadPrim s m, Prim e) => MBytes p s -> Off Word8 -> e -> m () setMBytes :: (MonadPrim s m, Prim e) => MBytes p s -> Off e -> Count e -> e -> m () -- | Fill the mutable array with zeros efficiently. zeroMBytes :: MonadPrim s m => MBytes p s -> m () -- | Pointer access to immutable Bytes should be for read only -- purposes, but it is not enforced. Any mutation will break referential -- transparency withPtrBytes :: MonadPrim s m => Bytes 'Pin -> (Ptr e -> m b) -> m b -- | Same as withPtrBytes, but is suitable for actions that don't -- terminate withNoHaltPtrBytes :: MonadUnliftPrim s m => Bytes 'Pin -> (Ptr e -> m b) -> m b withPtrMBytes :: MonadPrim s m => MBytes 'Pin s -> (Ptr e -> m b) -> m b withNoHaltPtrMBytes :: MonadUnliftPrim s m => MBytes 'Pin s -> (Ptr e -> m b) -> m b toPtrBytes :: Bytes 'Pin -> Ptr e toPtrMBytes :: MBytes 'Pin s -> Ptr e toForeignPtrBytes :: Bytes 'Pin -> ForeignPtr e toForeignPtrMBytes :: MBytes 'Pin s -> ForeignPtr e -- | O(1) - Cast Bytes into an unboxed array toUArrayBytes :: Bytes p -> UArray e -- | O(1) - Cast an unboxed array into Bytes fromUArrayBytes :: UArray e -> Bytes 'Inc -- | O(1) - Cast MBytes into a mutable unboxed array toUMArrayMBytes :: MBytes p s -> UMArray e s -- | O(1) - Cast a mutable unboxed array into MBytes fromUMArrayMBytes :: UMArray e s -> MBytes 'Inc s fromListBytes :: forall e p. (Prim e, Typeable p) => [e] -> Bytes p -- | Exactly like fromListMemN, but restricted to Bytes. fromListBytesN :: (Prim e, Typeable p) => Count e -> [e] -> (Either [e] (Count e), Bytes p) -- | Same as fromListZeroMemN_ fromListZeroBytesN_ :: (Prim e, Typeable p) => Count e -> [e] -> Bytes p -- | Allocate new memory region and append second bytes region after the -- first one appendBytes :: Typeable p => Bytes p1 -> Bytes p2 -> Bytes p concatBytes :: Typeable p => [Bytes p'] -> Bytes p -- | It is only guaranteed to convert the whole memory to a list whenever -- the size of allocated memory is exactly divisible by the size of the -- element, otherwise there will be some slack left unaccounted for. toListBytes :: Prim e => Bytes p -> [e] toListSlackBytes :: Prim e => Bytes p -> ([e], [Word8]) -- | Perform atomic modification of an element in the MBytes at the -- supplied index. Returns the actual value. Offset is in number of -- elements, rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. casMBytes :: (MonadPrim s m, Atomic e) => MBytes p s -> Off e -> e -> e -> m e -- | Perform atomic modification of an element in the MBytes at the -- supplied index. Returns True if swap was successfull and false -- otherwise. Offset is in number of elements, rather than bytes. Implies -- a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. casBoolMBytes :: (MonadPrim s m, Atomic e) => MBytes p s -> Off e -> e -> e -> m Bool -- | Just like casBoolMBytes, but also returns the actual value, -- which will match the supplied expected value if the returned flag is -- True -- -- Note - Bounds are not checked, therefore this function is -- unsafe. casBoolFetchMBytes :: (MonadPrim s m, Atomic e) => MBytes p s -> Off e -> e -> e -> m (Bool, e) -- | Perform atomic read of MBytes at the supplied index. Offset is -- in number of elements, rather than bytes. Implies a full memory -- barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicReadMBytes :: (MonadPrim s m, Atomic e) => MBytes p s -> Off e -> m e -- | Perform a write into MBytes at the supplied index atomically. -- Offset is in number of elements, rather than bytes. Implies a full -- memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicWriteMBytes :: (MonadPrim s m, Atomic e) => MBytes p s -> Off e -> e -> m () -- | Perform atomic modification of an element in the MBytes at the -- supplied index. Returns the artifact of computation b. -- Offset is in number of elements, rather than bytes. Implies a full -- memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicModifyMBytes :: (MonadPrim s m, Atomic e) => MBytes p s -> Off e -> (e -> (e, b)) -> m b -- | Perform atomic modification of an element in the MBytes at the -- supplied index. Offset is in number of elements, rather than bytes. -- Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicModifyMBytes_ :: (MonadPrim s m, Atomic e) => MBytes p s -> Off e -> (e -> e) -> m () -- | Perform atomic modification of an element in the MBytes at the -- supplied index. Returns the previous value. Offset is in number of -- elements, rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicBoolModifyFetchOldMBytes :: (MonadPrim s m, Atomic e) => MBytes p s -> Off e -> (e -> e) -> m e -- | Perform atomic modification of an element in the MBytes at the -- supplied index. Returns the previous value. Offset is in number of -- elements, rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicModifyFetchOldMBytes :: (MonadPrim s m, Atomic e) => MBytes p s -> Off e -> (e -> e) -> m e -- | Perform atomic modification of an element in the MBytes at the -- supplied index. Offset is in number of elements, rather than bytes. -- Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicModifyFetchNewMBytes :: (MonadPrim s m, Atomic e) => MBytes p s -> Off e -> (e -> e) -> m e -- | Add a numeric value to an element of a MBytes, corresponds to -- (+) done atomically. Returns the previous value. -- Offset is in number of elements, rather than bytes. Implies a full -- memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicAddFetchOldMBytes :: (MonadPrim s m, AtomicCount e) => MBytes p s -> Off e -> e -> m e -- | Add a numeric value to an element of a MBytes, corresponds to -- (+) done atomically. Returns the new value. Offset is -- in number of elements, rather than bytes. Implies a full memory -- barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicAddFetchNewMBytes :: (MonadPrim s m, AtomicCount e) => MBytes p s -> Off e -> e -> m e -- | Subtract a numeric value from an element of a MBytes, -- corresponds to (-) done atomically. Returns the -- previous value. Offset is in number of elements, rather than bytes. -- Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicSubFetchOldMBytes :: (MonadPrim s m, AtomicCount e) => MBytes p s -> Off e -> e -> m e -- | Subtract a numeric value from an element of a MBytes, -- corresponds to (-) done atomically. Returns the new -- value. Offset is in number of elements, rather than bytes. Implies a -- full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicSubFetchNewMBytes :: (MonadPrim s m, AtomicCount e) => MBytes p s -> Off e -> e -> m e -- | Binary conjunction (AND) of an element of a MBytes with the -- supplied value, corresponds to (.&.) done -- atomically. Returns the previous value. Offset is in number of -- elements, rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicAndFetchOldMBytes :: (MonadPrim s m, AtomicBits e) => MBytes p s -> Off e -> e -> m e -- | Binary conjunction (AND) of an element of a MBytes with the -- supplied value, corresponds to (.&.) done -- atomically. Returns the new value. Offset is in number of elements, -- rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicAndFetchNewMBytes :: (MonadPrim s m, AtomicBits e) => MBytes p s -> Off e -> e -> m e -- | Negation of binary conjunction (NAND) of an element of a MBytes -- with the supplied value, corresponds to \x y -> -- complement (x .&. y) done atomically. Returns -- the previous value. Offset is in number of elements, rather than -- bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicNandFetchOldMBytes :: (MonadPrim s m, AtomicBits e) => MBytes p s -> Off e -> e -> m e -- | Negation of binary conjunction (NAND) of an element of a MBytes -- with the supplied value, corresponds to \x y -> -- complement (x .&. y) done atomically. Returns -- the new value. Offset is in number of elements, rather than bytes. -- Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicNandFetchNewMBytes :: (MonadPrim s m, AtomicBits e) => MBytes p s -> Off e -> e -> m e -- | Binary disjunction (OR) of an element of a MBytes with the -- supplied value, corresponds to (.|.) done atomically. -- Returns the previous value. Offset is in number of elements, rather -- than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicOrFetchOldMBytes :: (MonadPrim s m, AtomicBits e) => MBytes p s -> Off e -> e -> m e -- | Binary disjunction (OR) of an element of a MBytes with the -- supplied value, corresponds to (.|.) done atomically. -- Returns the new value. Offset is in number of elements, rather than -- bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicOrFetchNewMBytes :: (MonadPrim s m, AtomicBits e) => MBytes p s -> Off e -> e -> m e -- | Binary exclusive disjunction (XOR) of an element of a MBytes -- with the supplied value, corresponds to xor done -- atomically. Returns the previous value. Offset is in number of -- elements, rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicXorFetchOldMBytes :: (MonadPrim s m, AtomicBits e) => MBytes p s -> Off e -> e -> m e -- | Binary exclusive disjunction (XOR) of an element of a MBytes -- with the supplied value, corresponds to xor done -- atomically. Returns the new value. Offset is in number of elements, -- rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicXorFetchNewMBytes :: (MonadPrim s m, AtomicBits e) => MBytes p s -> Off e -> e -> m e -- | Binary negation (NOT) of an element of a MBytes, corresponds to -- (complement) done atomically. Returns the previous -- value. Offset is in number of elements, rather than bytes. Implies a -- full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicNotFetchOldMBytes :: (MonadPrim s m, AtomicBits e) => MBytes p s -> Off e -> m e -- | Binary negation (NOT) of an element of a MBytes, corresponds to -- (complement) done atomically. Returns the new value. -- Offset is in number of elements, rather than bytes. Implies a full -- memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicNotFetchNewMBytes :: (MonadPrim s m, AtomicBits e) => MBytes p s -> Off e -> m e prefetchBytes0 :: (MonadPrim s m, Prim e) => Bytes p -> Off e -> m () prefetchMBytes0 :: (MonadPrim s m, Prim e) => MBytes p s -> Off e -> m () prefetchBytes1 :: (MonadPrim s m, Prim e) => Bytes p -> Off e -> m () prefetchMBytes1 :: (MonadPrim s m, Prim e) => MBytes p s -> Off e -> m () prefetchBytes2 :: (MonadPrim s m, Prim e) => Bytes p -> Off e -> m () prefetchMBytes2 :: (MonadPrim s m, Prim e) => MBytes p s -> Off e -> m () prefetchBytes3 :: (MonadPrim s m, Prim e) => Bytes p -> Off e -> m () prefetchMBytes3 :: (MonadPrim s m, Prim e) => MBytes p s -> Off e -> m () module Data.Prim.Memory.PArray -- | An immutable array with elements of type e newtype PArray (p :: Pinned) e PArray :: Bytes p -> PArray (p :: Pinned) e -- | A mutable array with elements of type e newtype PMArray (p :: Pinned) e s PMArray :: MBytes p s -> PMArray (p :: Pinned) e s -- | In GHC there is a distinction between pinned and unpinned memory. -- -- Pinned memory is such that when allocated, it is guaranteed not to -- move throughout the lifetime of a program. In other words the address -- pointer that refers to allocated bytes will not change until the -- associated ByteArray# or MutableByteArray# is no longer -- referenced anywhere in the program at which point it gets garbage -- collected. On the other hand unpinned memory can be moved around -- during GC, which helps to reduce memory fragmentation. -- -- Pinned/unpinnned choice during allocation is a bit of a lie, because -- when attempt is made to allocate memory as unpinned, but requested -- size is a bit more than a certain threshold (somewhere around 3KiB) it -- might still be allocated as pinned. Because of that fact through out -- the "primal" universe there is a distinction between memory that is -- either Pinned or Inconclusive. -- -- It is possible to use one of toPinnedBytes or -- toPinnedMBytes to get a conclusive type. data Pinned -- | Pinned, which indicates that allocated memory will not move Pin :: Pinned -- | Inconclusive, thus memory could be pinned or unpinned Inc :: Pinned fromBytesPArray :: Bytes p -> PArray p e toBytesPArray :: PArray p e -> Bytes p -- | O(1) - Cast UArray to PArray fromUArrayPArray :: UArray e -> PArray 'Inc e -- | O(1) - Cast PArray to UArray toUArrayPArray :: PArray p e -> UArray e castPArray :: PArray p e' -> PArray p e fromMBytesPMArray :: MBytes p s -> PMArray p e s toMBytesPMArray :: PMArray p e s -> MBytes p s -- | O(1) - Cast UMArray to PMArray fromUMArrayPMArray :: UMArray e s -> PMArray 'Inc e s -- | O(1) - Cast PMArray to UMArray toUMArrayPMArray :: PMArray p e s -> UMArray e s castPMArray :: PMArray p e' s -> PMArray p e s allocPMArray :: forall e p m s. (Typeable p, Prim e, MonadPrim s m) => Size -> m (PMArray p e s) allocPinnedPMArray :: forall e m s. (MonadPrim s m, Prim e) => Size -> m (PMArray 'Pin e s) allocAlignedPMArray :: (MonadPrim s m, Prim e) => Count e -> m (PMArray 'Pin e s) allocUnpinnedPMArray :: forall e m s. (MonadPrim s m, Prim e) => Size -> m (PMArray 'Inc e s) -- | 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 () -- | Attempt to resize mutable bytes in place. -- -- resizePMArray :: forall e p m s. (MonadPrim s m, Prim e) => PMArray p e s -> Size -> m (PMArray 'Inc e s) reallocPMArray :: forall e p m s. (MonadPrim s m, Typeable p, Prim e) => PMArray p e s -> Size -> m (PMArray p e s) isPinnedPArray :: PArray p e -> Bool isPinnedPMArray :: PMArray p e s -> Bool thawPArray :: MonadPrim s m => PArray p e -> m (PMArray p e s) freezePMArray :: MonadPrim s m => PMArray p e s -> m (PArray p e) sizePArray :: forall e p. Prim e => PArray p e -> Size getSizePMArray :: forall e p m s. (MonadPrim s m, Prim e) => PMArray p e s -> m Size readPMArray :: (MonadPrim s m, Prim e) => PMArray p e s -> Int -> m e writePMArray :: (MonadPrim s m, Prim e) => PMArray p e s -> Int -> e -> m () setPMArray :: forall e p m s. (MonadPrim s m, Prim e) => PMArray p e s -> Int -> Size -> e -> m () copyPArrayToPMArray :: forall e p m s. (MonadPrim s m, Prim e) => PArray p e -> Int -> PMArray p e s -> Int -> Size -> m () movePMArrayToPMArray :: forall e p m s. (MonadPrim s m, Prim e) => PMArray p e s -> Int -> PMArray p e s -> Int -> Size -> m () instance Data.Prim.Memory.Internal.MemRead (Data.Prim.Memory.PArray.PArray p e) instance Data.Typeable.Internal.Typeable p => GHC.Base.Monoid (Data.Prim.Memory.PArray.PArray p e) instance Data.Typeable.Internal.Typeable p => GHC.Base.Semigroup (Data.Prim.Memory.PArray.PArray p e) instance Control.DeepSeq.NFData (Data.Prim.Memory.PArray.PArray p e) instance Data.Prim.Memory.Internal.MemWrite (Data.Prim.Memory.PArray.PMArray p e) instance Control.DeepSeq.NFData (Data.Prim.Memory.PArray.PMArray p e s) instance Data.Prim.Memory.ForeignPtr.PtrAccess s (Data.Prim.Memory.PArray.PMArray 'Data.Prim.Memory.Bytes.Internal.Pin e s) instance Data.Typeable.Internal.Typeable p => Data.Prim.Memory.Internal.MemAlloc (Data.Prim.Memory.PArray.PMArray p e) instance (Data.Prim.Class.Prim e, GHC.Classes.Eq e) => GHC.Classes.Eq (Data.Prim.Memory.PArray.PArray p e) instance (Data.Prim.Class.Prim e, GHC.Classes.Ord e) => GHC.Classes.Ord (Data.Prim.Memory.PArray.PArray p e) instance Data.Prim.Memory.ForeignPtr.PtrAccess s (Data.Prim.Memory.PArray.PArray 'Data.Prim.Memory.Bytes.Internal.Pin e) instance (Data.Typeable.Internal.Typeable p, Data.Prim.Class.Prim e) => GHC.Exts.IsList (Data.Prim.Memory.PArray.PArray p e) instance Data.Typeable.Internal.Typeable p => Data.String.IsString (Data.Prim.Memory.PArray.PArray p GHC.Types.Char) instance (GHC.Show.Show e, Data.Prim.Class.Prim e) => GHC.Show.Show (Data.Prim.Memory.PArray.PArray p e) module Data.Prim.Memory.Addr -- | Immutable read-only address data Addr e Addr :: Addr# -> Bytes 'Pin -> Addr e [addrAddr#] :: Addr e -> Addr# [addrBytes] :: Addr e -> Bytes 'Pin castAddr :: Addr e -> Addr b fromBytesAddr :: Bytes 'Pin -> Addr e curOffAddr :: Prim e => Addr e -> Off e byteCountAddr :: Addr e -> Count Word8 countAddr :: forall e. Prim e => Addr e -> Count e plusOffAddr :: Prim e => Addr e -> Off e -> Addr e plusByteOffAddr :: Addr e -> Off Word8 -> Addr e indexAddr :: Prim e => Addr e -> e indexOffAddr :: Prim e => Addr e -> Off e -> e indexByteOffAddr :: Prim e => Addr e -> Off Word8 -> e readAddr :: (MonadPrim s m, Prim e) => Addr e -> m e readOffAddr :: (MonadPrim s m, Prim e) => Addr e -> Off e -> m e readByteOffAddr :: (MonadPrim s m, Prim e) => Addr e -> Off Word8 -> m e thawAddr :: MonadPrim s m => Addr e -> m (MAddr e s) freezeMAddr :: MonadPrim s m => MAddr e s -> m (Addr e) withPtrAddr :: MonadPrim s m => Addr e -> (Ptr e -> m b) -> m b withAddrAddr# :: MonadPrim s m => Addr e -> (Addr# -> m b) -> m b withNoHaltPtrAddr :: MonadUnliftPrim s m => Addr e -> (Ptr e -> m b) -> m b -- | Mutable address data MAddr e s MAddr :: Addr# -> MBytes 'Pin s -> MAddr e s [mAddrAddr#] :: MAddr e s -> Addr# [mAddrMBytes] :: MAddr e s -> MBytes 'Pin s castMAddr :: MAddr e s -> MAddr b s newMAddr :: forall e m s. (MonadPrim s m, Prim e) => e -> m (MAddr e s) allocMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s) allocAlignedMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s) allocZeroMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s) allocZeroAlignedMAddr :: forall e m s. (MonadPrim s m, Prim e) => Count e -> m (MAddr e s) reallocMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> Count e -> m (MAddr e s) -- | 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 () -- | Shrink mutable address to new specified size in bytes. The new count -- must be less than or equal to the current as reported by -- getByteCountMAddr. shrinkByteCountMAddr :: MonadPrim s m => MAddr e s -> Count Word8 -> m () setMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> Off e -> Count e -> e -> m () curOffMAddr :: forall e s. Prim e => MAddr e s -> Off e getByteCountMAddr :: MonadPrim s m => MAddr e s -> m (Count Word8) getCountMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> m (Count e) plusOffMAddr :: Prim e => MAddr e s -> Off e -> MAddr e s plusByteOffMAddr :: MAddr e s -> Off Word8 -> MAddr e s readMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> m e readOffMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> Off e -> m e readByteOffMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> Off Word8 -> m e writeMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> e -> m () writeOffMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> Off e -> e -> m () writeByteOffMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> Off Word8 -> e -> m () copyAddrToMAddr :: (MonadPrim s m, Prim e) => Addr e -> Off e -> MAddr e s -> Off e -> Count e -> m () moveMAddrToMAddr :: (MonadPrim s m, Prim e) => MAddr e s -> Off e -> MAddr e s -> Off e -> Count e -> m () -- | Apply a pure function to the contents of a mutable variable. Returns -- the artifact of computation. modifyMAddr :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> (a, b)) -> m b -- | Apply a pure function to the contents of a mutable variable. modifyMAddr_ :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> a) -> m () -- | Apply a pure function to the contents of a mutable variable. Returns -- the old value. modifyFetchOldMAddr :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> a) -> m a -- | Apply a pure function to the contents of a mutable variable. Returns -- the new value. modifyFetchNewMAddr :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> a) -> m a -- | Apply a monadic action to the contents of a mutable variable. Returns -- the artifact of computation. modifyMAddrM :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m (a, b)) -> m b -- | Apply a monadic action to the contents of a mutable variable. modifyMAddrM_ :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m a) -> m () -- | Apply a monadic action to the contents of a mutable variable. Returns -- the old value. modifyFetchOldMAddrM :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m a) -> m a -- | Apply a monadic action to the contents of a mutable variable. Returns -- the new value. modifyFetchNewMAddrM :: (MonadPrim s m, Prim a) => MAddr a s -> (a -> m a) -> m a -- | Swap contents of two mutable variables. swapMAddrs_ :: (MonadPrim s m, Prim a) => MAddr a s -> MAddr a s -> m () -- | Swap contents of two mutable variables. Returns their old values. swapMAddrs :: (MonadPrim s m, Prim a) => MAddr a s -> MAddr a s -> m (a, a) withPtrMAddr :: MonadPrim s m => MAddr e s -> (Ptr e -> m b) -> m b withAddrMAddr# :: MonadPrim s m => MAddr e s -> (Addr# -> m b) -> m b withNoHaltPtrMAddr :: MonadUnliftPrim s m => MAddr e s -> (Ptr e -> m b) -> m b toForeignPtrAddr :: Addr e -> ForeignPtr e toForeignPtrMAddr :: MAddr e s -> ForeignPtr e -- | This is a unsafe cast therefore modification of ForeignPtr will -- be reflected in resulting immutable Addr. Pointer created with -- malloc cannot be converted to Addr and will result in -- Nothing fromForeignPtrAddr :: ForeignPtr e -> Maybe (Addr e) -- | Discarding the original ForeignPtr will trigger finalizers that were -- attached to it, because MAddr does not retain any finalizers. -- Pointer created with malloc cannot be converted to -- MAddr and will result in Nothing fromForeignPtrMAddr :: ForeignPtr e -> Maybe (MAddr e s) -- | O(1) - Cast an immutable Addr to an immutable -- ByteString toByteStringAddr :: Addr Word8 -> ByteString -- | O(1) - Cast an immutable Addr to an immutable -- ShortByteString toShortByteStringAddr :: Addr Word8 -> (ShortByteString, Off Word8) -- | O(n) - Convert an immutable ShortByteString to an -- immutable Addr. In a most common case when -- ShortByteString is not backed by pinned memory, this function -- will return Nothing. fromShortByteStringAddr :: ShortByteString -> Addr Word8 -- | O(1) - Cast an immutable ByteString to Addr. Also -- returns the original length of ByteString, which will be less or equal -- to countOfAddr in the produced Addr. fromByteStringAddr :: ByteString -> (Addr Word8, Count Word8) -- | O(1) - Cast an immutable ByteString to a mutable -- MAddr. Also returns the original length of ByteString, which -- will be less or equal to getCountOfMAddr in the produced -- MAddr. -- -- Unsafe - Further modification of MAddr will affect the -- source ByteString fromByteStringMAddr :: ByteString -> (MAddr Word8 s, Count Word8) -- | Perform atomic modification of an element in the MAddr at the -- supplied index. Returns the artifact of computation b. -- Offset is in number of elements, rather than bytes. Implies a full -- memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. casOffMAddr :: (MonadPrim s m, Atomic e) => MAddr e s -> Off e -> e -> e -> m e -- | Perform atomic modification of an element in the MAddr at the -- supplied index. Returns True if swap was successfull and false -- otherwise. Offset is in number of elements, rather than bytes. Implies -- a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. casBoolOffMAddr :: (MonadPrim s m, Atomic e) => MAddr e s -> Off e -> e -> e -> m Bool -- | Just like casBoolOffMAddr, but also returns the actual value, -- which will match the supplied expected value if the returned flag is -- True -- -- Note - Bounds are not checked, therefore this function is -- unsafe. casBoolFetchOffMAddr :: (MonadPrim s m, Atomic e) => MAddr e s -> Off e -> e -> e -> m (Bool, e) -- | Perform atomic read of an element in the MAddr at the supplied -- offset. Offset is in number of elements, rather than bytes. Implies a -- full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicReadOffMAddr :: (MonadPrim s m, Atomic e) => MAddr e s -> Off e -> m e -- | Perform atomic write of an element in the MAddr at the supplied -- offset. Offset is in number of elements, rather than bytes. Implies a -- full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicWriteOffMAddr :: (MonadPrim s m, Atomic e) => MAddr e s -> Off e -> e -> m () -- | Perform atomic modification of an element in the MAddr at the -- supplied index. Returns the artifact of computation b. -- Offset is in number of elements, rather than bytes. Implies a full -- memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicModifyOffMAddr :: (MonadPrim s m, Atomic e) => MAddr e s -> Off e -> (e -> (e, b)) -> m b -- | Perform atomic modification of an element in the MAddr at the -- supplied index. Offset is in number of elements, rather than bytes. -- Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicModifyOffMAddr_ :: (MonadPrim s m, Atomic e) => MAddr e s -> Off e -> (e -> e) -> m () -- | Perform atomic modification of an element in the MAddr at the -- supplied index. Returns the previous value. Offset is in number of -- elements, rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicModifyFetchOldOffMAddr :: (MonadPrim s m, Atomic e) => MAddr e s -> Off e -> (e -> e) -> m e -- | Perform atomic modification of an element in the MAddr at the -- supplied index. Offset is in number of elements, rather than bytes. -- Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicModifyFetchNewOffMAddr :: (MonadPrim s m, Atomic e) => MAddr e s -> Off e -> (e -> e) -> m e -- | Add a numeric value to an element of a MAddr, corresponds to -- (+) done atomically. Returns the previous value. -- Offset is in number of elements, rather than bytes. Implies a full -- memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicAddFetchOldOffMAddr :: (MonadPrim s m, AtomicCount e) => MAddr e s -> Off e -> e -> m e -- | Add a numeric value to an element of a MAddr, corresponds to -- (+) done atomically. Returns the new value. Offset is -- in number of elements, rather than bytes. Implies a full memory -- barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicAddFetchNewOffMAddr :: (MonadPrim s m, AtomicCount e) => MAddr e s -> Off e -> e -> m e -- | Subtract a numeric value from an element of a MAddr, -- corresponds to (-) done atomically. Returns the -- previous value. Offset is in number of elements, rather than bytes. -- Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicSubFetchOldOffMAddr :: (MonadPrim s m, AtomicCount e) => MAddr e s -> Off e -> e -> m e -- | Subtract a numeric value from an element of a MAddr, -- corresponds to (-) done atomically. Returns the new -- value. Offset is in number of elements, rather than bytes. Implies a -- full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicSubFetchNewOffMAddr :: (MonadPrim s m, AtomicCount e) => MAddr e s -> Off e -> e -> m e -- | Binary conjunction (AND) of an element of a MAddr with the -- supplied value, corresponds to (.&.) done -- atomically. Returns the previous value. Offset is in number of -- elements, rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicAndFetchOldOffMAddr :: (MonadPrim s m, AtomicBits e) => MAddr e s -> Off e -> e -> m e -- | Binary conjunction (AND) of an element of a MAddr with the -- supplied value, corresponds to (.&.) done -- atomically. Returns the new value. Offset is in number of elements, -- rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicAndFetchNewOffMAddr :: (MonadPrim s m, AtomicBits e) => MAddr e s -> Off e -> e -> m e -- | Negation of binary conjunction (NAND) of an element of a MAddr -- with the supplied value, corresponds to \x y -> -- complement (x .&. y) done atomically. Returns -- the previous value. Offset is in number of elements, rather than -- bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicNandFetchOldOffMAddr :: (MonadPrim s m, AtomicBits e) => MAddr e s -> Off e -> e -> m e -- | Negation of binary conjunction (NAND) of an element of a MAddr -- with the supplied value, corresponds to \x y -> -- complement (x .&. y) done atomically. Returns -- the new value. Offset is in number of elements, rather than bytes. -- Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicNandFetchNewOffMAddr :: (MonadPrim s m, AtomicBits e) => MAddr e s -> Off e -> e -> m e -- | Binary disjunction (OR) of an element of a MAddr with the -- supplied value, corresponds to (.|.) done atomically. -- Returns the previous value. Offset is in number of elements, rather -- than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicOrFetchOldOffMAddr :: (MonadPrim s m, AtomicBits e) => MAddr e s -> Off e -> e -> m e -- | Binary disjunction (OR) of an element of a MAddr with the -- supplied value, corresponds to (.|.) done atomically. -- Returns the new value. Offset is in number of elements, rather than -- bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicOrFetchNewOffMAddr :: (MonadPrim s m, AtomicBits e) => MAddr e s -> Off e -> e -> m e -- | Binary exclusive disjunction (XOR) of an element of a MAddr -- with the supplied value, corresponds to xor done -- atomically. Returns the previous value. Offset is in number of -- elements, rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicXorFetchOldOffMAddr :: (MonadPrim s m, AtomicBits e) => MAddr e s -> Off e -> e -> m e -- | Binary exclusive disjunction (XOR) of an element of a MAddr -- with the supplied value, corresponds to xor done -- atomically. Returns the new value. Offset is in number of elements, -- rather than bytes. Implies a full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicXorFetchNewOffMAddr :: (MonadPrim s m, AtomicBits e) => MAddr e s -> Off e -> e -> m e -- | Binary negation (NOT) of an element of a MAddr, corresponds to -- (complement) done atomically. Returns the previous -- value. Offset is in number of elements, rather than bytes. Implies a -- full memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicNotFetchOldOffMAddr :: (MonadPrim s m, AtomicBits e) => MAddr e s -> Off e -> m e -- | Binary negation (NOT) of an element of a MAddr, corresponds to -- (complement) done atomically. Returns the new value. -- Offset is in number of elements, rather than bytes. Implies a full -- memory barrier. -- -- Note - Bounds are not checked, therefore this function is -- unsafe. atomicNotFetchNewOffMAddr :: (MonadPrim s m, AtomicBits e) => MAddr e s -> Off e -> m e prefetchAddr0 :: MonadPrim s m => Addr e -> m () prefetchMAddr0 :: MonadPrim s m => MAddr e s -> m () prefetchAddr1 :: MonadPrim s m => Addr e -> m () prefetchMAddr1 :: MonadPrim s m => MAddr e s -> m () prefetchAddr2 :: MonadPrim s m => Addr e -> m () prefetchMAddr2 :: MonadPrim s m => MAddr e s -> m () prefetchAddr3 :: MonadPrim s m => Addr e -> m () prefetchMAddr3 :: MonadPrim s m => MAddr e s -> m () prefetchOffAddr0 :: (MonadPrim s m, Prim e) => Addr e -> Off e -> m () prefetchOffMAddr0 :: (MonadPrim s m, Prim e) => MAddr e s -> Off e -> m () prefetchOffAddr1 :: (MonadPrim s m, Prim e) => Addr e -> Off e -> m () prefetchOffMAddr1 :: (MonadPrim s m, Prim e) => MAddr e s -> Off e -> m () prefetchOffAddr2 :: (MonadPrim s m, Prim e) => Addr e -> Off e -> m () prefetchOffMAddr2 :: (MonadPrim s m, Prim e) => MAddr e s -> Off e -> m () prefetchOffAddr3 :: (MonadPrim s m, Prim e) => Addr e -> Off e -> m () prefetchOffMAddr3 :: (MonadPrim s m, Prim e) => MAddr e s -> Off e -> m () instance Control.DeepSeq.NFData (Data.Prim.Memory.Addr.MAddr e s) instance Data.Prim.Memory.ForeignPtr.PtrAccess s (Data.Prim.Memory.Addr.MAddr e s) instance Data.Prim.Memory.Internal.MemAlloc (Data.Prim.Memory.Addr.MAddr e) instance Data.Prim.Memory.Internal.MemWrite (Data.Prim.Memory.Addr.MAddr e) instance (GHC.Classes.Eq e, Data.Prim.Class.Prim e) => GHC.Classes.Eq (Data.Prim.Memory.Addr.Addr e) instance (Data.Prim.Class.Prim e, GHC.Classes.Ord e) => GHC.Classes.Ord (Data.Prim.Memory.Addr.Addr e) instance (GHC.Show.Show e, Data.Prim.Class.Prim e) => GHC.Show.Show (Data.Prim.Memory.Addr.Addr e) instance Data.String.IsString (Data.Prim.Memory.Addr.Addr GHC.Types.Char) instance Data.Prim.Class.Prim e => GHC.Exts.IsList (Data.Prim.Memory.Addr.Addr e) instance GHC.Base.Semigroup (Data.Prim.Memory.Addr.Addr e) instance GHC.Base.Monoid (Data.Prim.Memory.Addr.Addr e) instance Control.DeepSeq.NFData (Data.Prim.Memory.Addr.Addr e) instance Data.Prim.Memory.ForeignPtr.PtrAccess s (Data.Prim.Memory.Addr.Addr e) instance Data.Prim.Memory.Internal.MemRead (Data.Prim.Memory.Addr.Addr e) module Data.Prim.Memory -- | In GHC there is a distinction between pinned and unpinned memory. -- -- Pinned memory is such that when allocated, it is guaranteed not to -- move throughout the lifetime of a program. In other words the address -- pointer that refers to allocated bytes will not change until the -- associated ByteArray# or MutableByteArray# is no longer -- referenced anywhere in the program at which point it gets garbage -- collected. On the other hand unpinned memory can be moved around -- during GC, which helps to reduce memory fragmentation. -- -- Pinned/unpinnned choice during allocation is a bit of a lie, because -- when attempt is made to allocate memory as unpinned, but requested -- size is a bit more than a certain threshold (somewhere around 3KiB) it -- might still be allocated as pinned. Because of that fact through out -- the "primal" universe there is a distinction between memory that is -- either Pinned or Inconclusive. -- -- It is possible to use one of toPinnedBytes or -- toPinnedMBytes to get a conclusive type. data Pinned -- | Pinned, which indicates that allocated memory will not move Pin :: Pinned -- | Inconclusive, thus memory could be pinned or unpinned Inc :: Pinned -- | An immutable region of memory which was allocated either as pinned or -- unpinned. -- -- Constructor is not exported for safety. Violating type level -- Pinned kind is very dangerous. Type safe constructor -- fromByteArray# and unwrapper toByteArray# should be used -- instead. As a backdoor, of course, the actual constructor is available -- from Data.Prim.Memory.Internal data Bytes (p :: Pinned) -- | Type class that can be implemented for an immutable data type that -- provides read-only direct access to memory class MemRead mr -- | 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}
--   
countMem :: forall e mr. (MemRead mr, Prim e) => mr -> Count e -- | 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})
--   
countRemMem :: forall e mr. (MemRead mr, Prim e) => mr -> (Count e, Count Word8) -- | 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}
--   
byteCountMem :: MemRead mr => mr -> Count Word8 -- | Read an element with an offset in number of elements, rather than -- bytes as is the case with indexByteOffMem. -- -- indexOffMem :: (MemRead mr, Prim e) => mr -> Off e -> e -- | Read an element with an offset in number of bytes. Bounds are not -- checked. -- -- indexByteOffMem :: (MemRead mr, Prim e) => mr -> Off Word8 -> e -- | 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]
--   []
--   
emptyMem :: forall ma. MemAlloc ma => FrozenMem ma -- | 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]
--   
singletonMem :: forall e ma. (MemAlloc ma, Prim e) => e -> FrozenMem ma -- | 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]
--   
cycleMemN :: forall ma mr. (MemAlloc ma, MemRead mr) => Int -> mr -> FrozenMem ma -- | 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. -- -- createMemST :: forall e b ma. (MemAlloc ma, Prim e) => Count e -> (forall s. ma s -> ST s b) -> (b, FrozenMem ma) createMemST_ :: (MemAlloc ma, Prim e) => Count e -> (forall s. ma s -> ST s b) -> FrozenMem ma -- | Same as createMemST, except it in ensures that the memory is -- reset to zeros right after allocation -- -- createZeroMemST :: forall e ma b. (MemAlloc ma, Prim e) => Count e -> (forall s. ma s -> ST s b) -> (b, FrozenMem ma) -- | Same as createMemST_, except it ensures that the memory gets -- reset with zeros right after allocation and prior applying the -- ST filling action fillAction. -- -- -- --

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"
--   
createZeroMemST_ :: forall e ma b. (MemAlloc ma, Prim e) => Count e -> (forall s. ma s -> ST s b) -> FrozenMem ma -- | 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"
--   
cloneMem :: forall ma. MemAlloc ma => FrozenMem ma -> FrozenMem ma -- | 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. -- -- copyMem :: (MonadPrim s m, MemRead mr, MemWrite mw, Prim e) => mr -> Off e -> mw s -> Off e -> Count 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. -- -- copyByteOffMem :: (MemWrite mw, MonadPrim s m, MemRead mr, Prim e) => mr -> Off Word8 -> mw s -> Off Word8 -> Count e -> m () -- | 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. -- -- copyByteOffToMBytesMem :: (MemRead mr, MonadPrim s m, Prim e) => mr -> Off Word8 -> MBytes p s -> Off Word8 -> Count 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. -- -- copyByteOffToPtrMem :: (MemRead mr, MonadPrim s m, Prim e) => mr -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m () eqMem :: forall e mr. (Prim e, Eq e, MemRead mr) => mr -> mr -> Bool -- | 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. -- -- eqOffMem :: (Prim e, Eq e, MemRead mr1, MemRead mr2) => mr1 -> Off e -> mr2 -> Off e -> Count e -> Bool -- | Compare two memory regions for equality byte-by-byte. False is -- returned immediately when sizes reported by byteCountMem do not -- match. eqByteMem :: (MemRead mr1, MemRead mr2) => mr1 -> mr2 -> Bool -- | Compare two memory regions byte-by-byte. Computation may be -- short-circuited on the first mismatch, but it is MemRead -- implementation specific. eqByteOffMem :: (MemRead mr1, MemRead mr2) => mr1 -> Off Word8 -> mr2 -> Off Word8 -> Count Word8 -> Bool -- | 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. compareMem :: forall e mr. (Prim e, Ord e, MemRead mr) => mr -> mr -> Ordering -- | 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. -- -- compareOffMem :: (Prim e, Ord e, MemRead mr1, MemRead mr2) => mr1 -> Off e -> mr2 -> Off e -> Count e -> Ordering -- | Compare two memory regions byte-by-byte. compareByteMem :: (MemRead mr1, MemRead mr2) => mr1 -> mr2 -> 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. -- -- compareByteOffMem :: (MemRead mr, MemRead mr', Prim e) => mr' -> Off Word8 -> mr -> Off Word8 -> Count e -> Ordering -- | Same as compareByteOffMem, but compare the read-only memory -- region to a region addressed by a Ptr inside of a -- MonadPrim. -- -- compareByteOffToPtrMem :: (MemRead mr, MonadPrim s m, Prim e) => mr -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m Ordering -- | Same as compareByteOffMem, but compare the read-only memory -- region to Bytes. -- -- compareByteOffToBytesMem :: (MemRead mr, Prim e) => mr -> Off Word8 -> Bytes p -> Off Word8 -> Count e -> Ordering -- | 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]
--   
convertMem :: (MemRead mr, MemAlloc ma) => mr -> FrozenMem ma -- | 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"
--   
toListMem :: forall e mr. (MemRead mr, Prim e) => mr -> [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])
--   
toListSlackMem :: forall e mr. (MemRead mr, Prim e) => mr -> ([e], [Word8]) -- | Convert a memory region to a list of bytes. Equivalent to -- unpack for ByteString -- --

Example

-- --
--   >>> toByteListMem (fromByteListMem [0..10] :: Bytes 'Pin)
--   [0,1,2,3,4,5,6,7,8,9,10]
--   
toByteListMem :: forall ma. MemAlloc ma => FrozenMem ma -> [Word8] -- | Right fold that is useful for converting to a list while tapping into -- list fusion. -- -- foldrCountMem :: forall e b mr. (MemRead mr, Prim e) => Count e -> (e -> b -> b) -> b -> mr -> b -- | 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 "
--   
showsHexMem :: MemRead mr => mr -> [ShowS] -- | 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]
--   
fromListMem :: forall e ma. (Prim e, MemAlloc ma) => [e] -> FrozenMem ma -- | Same as fromListMem but restricted to a list of Word8. -- Load a list of bytes into a newly allocated memory region. Equivalent -- to pack for ByteString -- --

Examples

-- --
--   >>> fromByteListMem [0..10] :: Bytes 'Pin
--   [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a]
--   
fromByteListMem :: forall ma. MemAlloc ma => [Word8] -> FrozenMem ma -- | 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: -- -- -- -- 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. -- -- -- --

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})
--   
fromListMemN :: forall e ma. (Prim e, MemAlloc ma) => Count e -> [e] -> (Either [e] (Count e), FrozenMem ma) -- | 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])
--   
fromListZeroMemN :: forall e ma. (Prim e, MemAlloc ma) => Count e -> [e] -> (Either [e] (Count e), FrozenMem ma) -- | 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]
--   
fromListZeroMemN_ :: forall e ma. (Prim e, MemAlloc ma) => Count e -> [e] -> FrozenMem ma -- | Mutable region of memory which was allocated either as pinned or -- unpinned. -- -- Constructor is not exported for safety. Violating type level -- Pinned kind is very dangerous. Type safe constructor -- fromMutableByteArray# and unwrapper toMutableByteArray# -- should be used instead. As a backdoor, of course, the actual -- constructor is available in Data.Prim.Memory.Internal module -- and specially unsafe function castPinnedMBytes was crafted. data MBytes (p :: Pinned) s -- | Type class that can be implemented for a mutable data type that -- provides direct read and write access to memory class MemWrite mw -- | 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 family FrozenMem ma = (fm :: Type) | fm -> ma; } -- | 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 :: a -> MemState a s [unMemState] :: MemState a s -> a -- | 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}
--   
getCountMutMem :: forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e) => ma s -> m (Count e) -- | 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})
--   
getCountRemMutMem :: forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e) => ma s -> m (Count e, Count Word8) -- | 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}
--   
getByteCountMutMem :: (MemAlloc ma, MonadPrim s m) => ma s -> m (Count Word8) -- | Read an element with an offset in number of elements, rather than -- bytes as it is the case with readByteOffMutMem. -- -- readOffMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> m e -- | Read an element with an offset in number of bytes. -- -- readByteOffMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> m e -- | Write an element with an offset in number of elements, rather than -- bytes as it is the case with writeByteOffMutMem. -- -- writeOffMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> e -> m () -- | Write an element with an offset in number of bytes. -- -- writeByteOffMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> e -> m () -- | Write the same value memCount times into each cell of -- memTarget starting at an offset memTargetOff. -- -- setMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> Count e -> e -> m () modifyFetchOldMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> e) -> m e modifyFetchOldMutMemM :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> m e) -> m e modifyFetchNewMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> e) -> m e modifyFetchNewMutMemM :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> (e -> m e) -> m e -- | 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. -- -- allocMutMem :: (MemAlloc ma, Prim e, MonadPrim s m) => Count e -> m (ma s) -- | Same as allocMutMem, but also use setMutMem to reset all -- of newly allocated memory to zeros. -- -- -- --

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]
--   
allocZeroMutMem :: forall e ma m s. (MemAlloc ma, MonadPrim s m, Prim e) => Count e -> m (ma s) -- | 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 -- -- reallocMutMem :: (MemAlloc ma, MonadPrim s m, Prim e) => ma s -> Count e -> m (ma s) -- | 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. 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 -- | 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. -- -- defaultReallocMutMem :: (Prim e, MemAlloc ma, MonadPrim s m) => ma s -> Count e -> m (ma s) -- | 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]
--   
thawCloneMem :: forall ma m s. (MemAlloc ma, MonadPrim s m) => FrozenMem ma -> m (ma s) -- | Similar to thawCloneMem, except it is possible to specify which -- portion of the frozen region will be copied over and thawed. -- -- -- --

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]
--   
thawCopyMem :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => FrozenMem ma -> Off e -> Count e -> 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. -- -- thawMem :: (MemAlloc ma, MonadPrim s m) => FrozenMem ma -> m (ma s) -- | 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. freezeCloneMutMem :: forall ma m s. (MemAlloc ma, MonadPrim s m) => ma s -> m (FrozenMem ma) freezeCopyMutMem :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => ma s -> Off e -> Count e -> m (FrozenMem ma) -- | 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. -- -- freezeMutMem :: (MemAlloc ma, MonadPrim s m) => ma s -> m (FrozenMem ma) -- | Allocate the same amount of memory as the source memory region and -- copy all of its data over. cloneMutMem :: forall ma m s. (MemAlloc ma, MonadPrim s m) => ma s -> m (ma s) moveMutMem :: (MonadPrim s m, MemWrite mw1, MemWrite mw2, Prim e) => mw1 s -> Off e -> mw2 s -> Off e -> Count 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. -- -- moveByteOffMutMem :: (MemWrite mw, MonadPrim s m, MemWrite mw', Prim e) => mw' s -> Off Word8 -> mw s -> Off Word8 -> Count 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. -- -- moveByteOffToMBytesMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> MBytes p s -> Off Word8 -> Count 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. -- -- moveByteOffToPtrMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m () -- | 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]
--   
loadListMutMem :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => [e] -> ma s -> m ([e], Count e) -- | Same as loadListMutMem, but ignores the result. Equivalence as -- property: -- --
--   let c = fromInteger (abs i) :: Count Int in (createZeroMemST_ c (loadListMutMem_ (xs :: [Int])) :: Bytes 'Inc) == createZeroMemST_ c (void . loadListMutMem xs)
--   
loadListMutMem_ :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => [e] -> ma s -> m () -- | Same as loadListOffMutMemN, but start loading at 0 -- offset. -- -- loadListMutMemN :: forall e mw m s. (MemWrite mw, MonadPrim s m, Prim e) => Count e -> [e] -> mw s -> m ([e], Count e) -- | Same as loadListMutMemN, but ignores the result. -- -- loadListMutMemN_ :: forall e mw m s. (Prim e, MemWrite mw, MonadPrim s m) => Count e -> [e] -> mw s -> m () -- | Same as loadListOffMutMemN, but infer the count from number of -- bytes that is available in the target memory region. -- -- loadListOffMutMem :: forall e ma m s. (Prim e, MemAlloc ma, MonadPrim s m) => [e] -> ma s -> Off e -> m ([e], Count e) -- | Same as loadListByteOffMutMemN, but works with offset in number -- of elements instead of bytes. -- -- loadListOffMutMemN :: (MemWrite mw, MonadPrim s m, Prim e) => Count e -> [e] -> mw s -> Off e -> m ([e], Count e) -- | Same as loadListByteOffMutMemN, but infer the count from number -- of bytes that is available in the target memory region. -- -- -- --

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]
--   
loadListByteOffMutMem :: (MemAlloc ma, MonadPrim s m, Prim e) => [e] -> ma s -> Off Word8 -> m ([e], Count e) -- | 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. -- -- -- --

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]
--   
loadListByteOffMutMemN :: (MemWrite mw, MonadPrim s m, Prim e) => Count e -> [e] -> mw s -> Off Word8 -> m ([e], Count e)