-- 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.
--
--
-- - Unsafe When any precondition for either of the offsets
-- memOff1, memOff2 or the element count
-- memCount is violated the result is either unpredictable
-- output or failure with a segfault.
--
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.
--
--
-- - Unsafe When any precondition for either of the offsets
-- memOff1, memOff2 or the element count
-- memCount is violated the result is either unpredictable
-- output or failure with a segfault.
--
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.
--
--
-- - New bytes might be allocated, with the copy of an old one.
-- - Old references should not be kept around to allow GC to claim
-- it
-- - Old references should not be used to avoid undefined behavior
--
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.
--
--
-- - New bytes might be allocated, with the copy of an old one.
-- - Old references should not be kept around to allow GC to claim
-- it
-- - Old references should not be used to avoid undefined behavior
--
resizePMArray :: forall e p m s. (MonadPrim s m, Prim e) => PMArray p e s -> Size -> m (PMArray 'Inc e s)
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.
--
--
-- - Unsafe Bounds are not checked. When precondition for
-- off argument is violated the result is either unpredictable
-- output or failure with a segfault.
--
indexOffMem :: (MemRead mr, Prim e) => mr -> Off e -> e
-- | Read an element with an offset in number of bytes. Bounds are not
-- checked.
--
--
-- - Unsafe When precondition for off argument is
-- violated the result is either unpredictable output or failure with a
-- segfault.
--
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
--
--
-- - Unsafe Same caviats as in allocZeroMutMem: violation
-- of precondition for memCount may result in undefined behavior
-- or HeapOverflow async exception.
--
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.
--
--
-- - Unsafe Same reasons as allocZeroMutMem: violation of
-- precondition for memCount may result in undefined behavior or
-- HeapOverflow async exception.
--
--
-- Example
--
-- Note that this example will work correctly only on little-endian
-- machines:
--
--
-- >>> :set -XTypeApplications
--
-- >>> import Data.Prim
--
-- >>> import Control.Monad
--
-- >>> let ibs = zip [0, 4 ..] [0x48,0x61,0x73,0x6b,0x65,0x6c,0x6c] :: [(Off Word8, Word8)]
--
-- >>> let c = Count (length ibs) :: Count Char
--
-- >>> let bc = createZeroMemST_ @_ @(MBytes 'Inc) c $ \m -> forM_ ibs $ \(i, b) -> writeByteOffMutMem m i b
--
-- >>> toListMem bc :: String
-- "Haskell"
--
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.
--
--
-- - Unsafe When any precondition for one of the offsets
-- memSourceOff, memTargetOff or the element count
-- memCount is violated a call to this function can result in:
-- copy of data that doesn't belong to memSourceRead, heap
-- corruption or failure with a segfault.
--
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.
--
--
-- - Unsafe When any precondition for one of the offsets
-- memSourceOff, memTargetOff or the element count
-- memCount is violated a call to this function can result in:
-- copy of data that doesn't belong to memSourceRead, heap
-- corruption or failure with a segfault.
--
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.
--
--
-- - Unsafe When a precondition for either of the offsets
-- memSourceOff, memTargetOff or the element count
-- memCount is violated the result is either unpredictable
-- output or failure with a segfault.
--
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.
--
--
-- - Unsafe When any precondition for one of the offsets
-- memSourceOff, memTargetOff or the element count
-- memCount is violated a call to this function can result in:
-- copy of data that doesn't belong to memSourceRead, heap
-- corruption or failure with a segfault.
--
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.
--
--
-- - Unsafe When any precondition for either of the offsets
-- memOff1, memOff2 or the element count
-- memCount is violated the result is either unpredictable
-- output or failure with a segfault.
--
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.
--
--
-- - Unsafe When any precondition for either of the offsets
-- memOff1, memOff2 or the element count
-- memCount is violated the result is either unpredictable
-- output or failure with a segfault.
--
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.
--
--
-- - Unsafe When any precondition for either of the offsets
-- memOff1, memOff2 or the element count
-- memCount is violated the result is either unpredictable
-- output or failure with a segfault.
--
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.
--
--
-- - Unsafe When any precondition for either of the offsets
-- memOff1, memOff2, the pointer memRead2 or
-- the element count memCount is violated the result is either
-- unpredictable output or failure with a segfault.
--
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.
--
--
-- - Unsafe When any precondition for either of the offsets
-- memOff1, memOff2 or the element count
-- memCount is violated the result is either unpredictable
-- output or failure with a segfault.
--
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.
--
--
-- - Unsafe Supplying Count larger than memory holds will result
-- in reading out of bounds and a potential segfault.
--
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.
--
--
-- - Unsafe Whenever memCount precodition is violated,
-- because on each call with the same input it can produce different
-- output therefore it will break referential transparency.
--
--
-- Examples
--
--
-- >>> :set -XTypeApplications
--
-- >>> fromListMemN @Char @(MBytes 'Inc) 3 "Hello"
-- (Left "lo",[0x48,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00])
--
-- >>> fromListMemN @Char @(MBytes 'Inc) 2 "Hi"
-- (Left "",[0x48,0x00,0x00,0x00,0x69,0x00,0x00,0x00])
--
-- >>> fst $ fromListMemN @Char @(MBytes 'Inc) 5 "Hi"
-- Right (Count {unCount = 2})
--
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.
--
--
-- - Unsafe Bounds are not checked. When precondition for
-- off argument is violated the result is either unpredictable
-- output or failure with a segfault.
--
readOffMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> m e
-- | Read an element with an offset in number of bytes.
--
--
-- - Unsafe Bounds are not checked. When precondition for
-- off argument is violated the result is either unpredictable
-- output or failure with a segfault.
--
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.
--
--
-- - Unsafe Bounds are not checked. When precondition for
-- off argument is violated the outcome is either heap
-- corruption or failure with a segfault.
--
writeOffMutMem :: (MemWrite mw, MonadPrim s m, Prim e) => mw s -> Off e -> e -> m ()
-- | Write an element with an offset in number of bytes.
--
--
-- - Unsafe Bounds are not checked. When precondition for
-- off argument is violated the outcome is either heap
-- corruption or failure with a segfault.
--
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.
--
--
-- - Unsafe Bounds are not checked. When precondition for
-- memTargetOff argument is violated the outcome is either heap
-- corruption or failure with a segfault.
--
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.
--
--
-- - Unsafe When any of preconditions for memCount
-- argument is violated the outcome is unpredictable. One possible
-- outcome is termination with HeapOverflow async exception. In a
-- pure setting, such as when executed within runST, if allocated
-- memory is not fully overwritten it can lead to violation of
-- referential transparency, because contents of newly allocated region
-- is non-determinstic.
--
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.
--
--
-- - Unsafe When precondition for memCount argument is
-- violated the outcome is unpredictable. One possible outcome is
-- termination with HeapOverflow async exception.
--
--
-- Example
--
--
-- >>> :set -XTypeApplications
--
-- >>> :set -XDataKinds
--
-- >>> import Data.Prim.Memory
--
-- >>> mb <- allocZeroMutMem @Int @(MBytes 'Inc) 10
--
-- >>> b <- freezeMutMem mb
--
-- >>> toListMem b :: [Int]
-- [0,0,0,0,0,0,0,0,0,0]
--
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
--
--
-- - Unsafe Undefined behavior when memSource is used
-- afterwards. The same unsafety notice from allocMutMem with
-- regards to memCount is applicable here as well.
--
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.
--
--
-- - Unsafe When any precondition for eihter an offset
-- memSourceOff or the element count memCount is
-- violated a call to this function can result in: copy of data that
-- doesn't belong to memSource or failure with a segfault.
--
--
-- Examples
--
--
-- >>> :set -XTypeApplications
--
-- >>> :set -XDataKinds
--
-- >>> import Data.Prim.Memory
--
-- >>> let fm = fromListMem @Word8 @(MBytes 'Inc) [1,2,3,4,5]
--
-- >>> mm <- thawCopyMem fm 1 (3 :: Count Word8)
--
-- >>> writeOffMutMem mm 1 (0 :: Word8)
--
-- >>> freezeMutMem mm
-- [0x02,0x00,0x04]
--
-- >>> fm
-- [0x01,0x02,0x03,0x04,0x05]
--
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.
--
--
-- - Unsafe This function makes it possible to break referential
-- transparency, because any subsequent destructive operation to the
-- mutable region of memory will also be reflected in the frozen
-- immutable type as well.
--
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.
--
--
-- - Unsafe It makes it possible to break referential
-- transparency, because any subsequent destructive operation to the
-- mutable region of memory will also be reflected in the frozen
-- immutable type as well.
--
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.
--
--
-- - Unsafe When any precondition for one of the offsets
-- memSourceOff, memTargetOff or the element count
-- memCount is violated a call to this function can result in:
-- copy of data that doesn't belong to memSourceRead, heap
-- corruption or failure with a segfault.
--
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.
--
--
-- - Unsafe When any precondition for one of the offsets
-- memSourceOff, memTargetOff or the element count
-- memCount is violated a call to this function can result in:
-- copy of data that doesn't belong to memSource, heap
-- corruption or failure with a segfault.
--
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.
--
--
-- - Unsafe When any precondition for one of the offsets
-- memSourceOff or memTargetOff, a target pointer
-- memTarget or the element count memCount is violated
-- a call to this function can result in: copy of data that doesn't
-- belong to memSource, heap corruption or failure with a
-- segfault.
--
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.
--
--
-- - Unsafe When any precondition for the element count
-- memCount is violated then a call to this function can result
-- in heap corruption or failure with a segfault.
--
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.
--
--
-- - Unsafe When any precondition for the element count
-- memCount is violated then a call to this function can result
-- in heap corruption or failure with a segfault.
--
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.
--
--
-- - Unsafe When a precondition for the element count
-- memCount is violated then a call to this function can result
-- in heap corruption or failure with a segfault.
--
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.
--
--
-- - Unsafe When preconditions for either the offset
-- memTargetOff or the element count memCount is
-- violated then a call to this function can result in heap corruption or
-- failure with a segfault.
--
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.
--
--
-- - Unsafe When a precondition for the element count
-- memCount is violated then a call to this function can result
-- in heap corruption or failure with a segfault.
--
--
-- Examples
--
--
-- >>> :set -XDataKinds
--
-- >>> import Data.Prim.Memory
--
-- >>> ma <- allocZeroMutMem (5 :: Count Char) :: IO (MBytes 'Inc RW)
--
-- >>> freezeMutMem ma
-- [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
--
-- >>> loadListByteOffMutMem "Hello World" ma 0
-- (" World",Count {unCount = 5})
--
-- >>> freezeMutMem ma
-- [0x48,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6f,0x00,0x00,0x00]
--
-- >>> loadListByteOffMutMem ([0xff,0xff,0xff] :: [Word8]) ma 1
-- ([],Count {unCount = 3})
--
-- >>> freezeMutMem ma
-- [0x48,0xff,0xff,0xff,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6f,0x00,0x00,0x00]
--
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.
--
--
-- - Unsafe When any precondition for either the offset
-- memTargetOff or the element count memCount is
-- violated then a call to this function can result in heap corruption or
-- failure with a segfault.
--
--
-- Examples
--
-- For example load the Hell somewhere in the middle of
-- MBytes:
--
--
-- >>> ma <- allocZeroMutMem (6 :: Count Char) :: IO (MBytes 'Inc RW)
--
-- >>> loadListByteOffMutMemN 4 "Hello!" ma (toByteOff (1 :: Off Char))
-- ("o!",Count {unCount = 4})
--
-- >>> freezeMutMem ma
-- [0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
--
--
-- Or something more useful like loading prefixes from nested lists:
--
--
-- >>> import Control.Monad
--
-- >>> foldM_ (\o xs -> (+ o) . countToByteOff . snd <$> loadListByteOffMutMemN 4 xs ma o) 2 [[x..] | x <- [1..5] :: [Word8]]
--
-- >>> freezeMutMem ma
-- [0x00,0x00,0x01,0x02,0x03,0x04,0x02,0x03,0x04,0x05,0x03,0x04,0x05,0x06,0x04,0x05,0x06,0x07,0x05,0x06,0x07,0x08,0x00,0x00]
--
loadListByteOffMutMemN :: (MemWrite mw, MonadPrim s m, Prim e) => Count e -> [e] -> mw s -> Off Word8 -> m ([e], Count e)