regional-pointers-0.6: Foreign/Marshal/Alloc/Region.hs
{-# LANGUAGE UnicodeSyntax
, NoImplicitPrelude
, RankNTypes
, ScopedTypeVariables
, CPP
#-}
-------------------------------------------------------------------------------
-- |
-- Module : Foreign.Marshal.Alloc.Region
-- Copyright : (c) 2010 Bas van Dijk
-- License : BSD3 (see the file LICENSE)
-- Maintainer : Bas van Dijk <v.dijk.bas@gmail.com>
--
-------------------------------------------------------------------------------
module Foreign.Marshal.Alloc.Region
( -- * Local allocation
LocalPtr
, alloca
, allocaBytes
#if MIN_VERSION_base(4,3,0)
, allocaBytesAligned
#endif
-- * Dynamic allocation
, malloc
, mallocBytes
) where
--------------------------------------------------------------------------------
-- Imports
--------------------------------------------------------------------------------
-- from base:
import Data.Int ( Int )
import Foreign.Storable ( Storable )
import qualified Foreign.Marshal.Alloc as FMA ( alloca, allocaBytes
, malloc, mallocBytes
)
#if MIN_VERSION_base(4,3,0)
import qualified Foreign.Marshal.Alloc as FMA ( allocaBytesAligned )
#endif
#if __HADDOCK__
import Foreign.Storable ( sizeOf )
#endif
-- from monad-control:
import Control.Monad.IO.Control ( MonadControlIO )
-- from regions:
import Control.Monad.Trans.Region ( RegionT, LocalRegion, Local )
-- from ourselves:
import Foreign.Ptr.Region ( RegionalPtr, )
import Foreign.Ptr.Region.Internal ( LocalPtr )
import Foreign.Ptr.Region.Unsafe ( wrapAlloca, wrapMalloc )
--------------------------------------------------------------------------------
-- * Local allocation
--------------------------------------------------------------------------------
{-|
@'alloca' f@ executes the computation @f@, passing as argument a pointer to
a temporarily allocated block of memory sufficient to hold values of type @α@.
The memory is freed when @f@ terminates (either normally or via an exception).
This should provide a safer replacement for:
@Foreign.Marshal.Alloc.'FMA.alloca'@.
-}
alloca ∷ (Storable α, MonadControlIO pr)
⇒ (∀ sl. LocalPtr α (LocalRegion sl s) → RegionT (Local s) pr β)
→ RegionT s pr β
alloca = wrapAlloca FMA.alloca
{-|
@'allocaBytes' n f@ executes the computation @f@, passing as argument a
pointer to a temporarily allocated block of memory of @n@ bytes.
The block of memory is sufficiently aligned for any of the basic foreign types
that fits into a memory block of the allocated size.
The memory is freed when @f@ terminates (either normally or via an exception).
This should provide a safer replacement for:
@Foreign.Marshal.Alloc.'FMA.allocaBytes'@.
-}
allocaBytes ∷ MonadControlIO pr
⇒ Int
→ (∀ sl. LocalPtr α (LocalRegion sl s) → RegionT (Local s) pr β)
→ RegionT s pr β
allocaBytes size = wrapAlloca (FMA.allocaBytes size)
#if MIN_VERSION_base(4,3,0)
-- | This should provide a safer replacement for:
-- @Foreign.Marshal.Alloc.'FMA.allocaBytesAligned'@.
allocaBytesAligned ∷
MonadControlIO pr
⇒ Int → Int
→ (∀ sl. LocalPtr α (LocalRegion sl s) → RegionT (Local s) pr β)
→ RegionT s pr β
allocaBytesAligned size align = wrapAlloca (FMA.allocaBytesAligned size align)
#endif
--------------------------------------------------------------------------------
-- * Dynamic allocation
--------------------------------------------------------------------------------
{-|
Allocate a block of memory that is sufficient to hold values of type @α@.
Note that: @malloc = 'mallocBytes' $ 'sizeOf' (undefined :: α)@
This should provide a safer replacement for:
@Foreign.Marshal.Alloc.'FMA.malloc'@.
-}
malloc ∷ ∀ α pr s. (Storable α, MonadControlIO pr)
⇒ RegionT s pr (RegionalPtr α (RegionT s pr))
malloc = wrapMalloc FMA.malloc
{-|
Allocate a block of memory of the given number of bytes.
The block of memory is sufficiently aligned for any of the basic foreign types
that fits into a memory block of the allocated size.
This should provide a safer replacement for:
@Foreign.Marshal.Alloc.'FMA.mallocBytes'@.
-}
mallocBytes ∷ MonadControlIO pr
⇒ Int
→ RegionT s pr (RegionalPtr α (RegionT s pr))
mallocBytes size = wrapMalloc (FMA.mallocBytes size)
-- TODO:
-- realloc ∷ (Storable β, pr `AncestorRegion` cr, MonadIO cr)
-- ⇒ RegionalPtr α pr → cr (RegionalPtr β pr)
-- realloc = ...
-- reallocBytes ∷ (pr `AncestorRegion` cr, MonadIO cr)
-- ⇒ RegionalPtr α pr → Int → cr (RegionalPtr α pr)
-- reallocBytes = ...
-- The End ---------------------------------------------------------------------