regional-pointers-0.1: Foreign/Ptr/Region/Internal.hs
{-# LANGUAGE UnicodeSyntax
, NoImplicitPrelude
, TypeFamilies
, CPP
#-}
-------------------------------------------------------------------------------
-- |
-- Module : Foreign.Ptr.Region.Internal
-- Copyright : (c) 2010 Bas van Dijk
-- License : BSD3 (see the file LICENSE)
-- Maintainer : Bas van Dijk <v.dijk.bas@gmail.com>
--
-------------------------------------------------------------------------------
module Foreign.Ptr.Region.Internal
( -- * Memory as a scarce resource
Memory(..)
, RegionalPtr
-- * Utility functions for lifting operations on Ptrs to RegionalPtrs
, mapRegionalPtr
, unsafePtr
, unsafeWrap, unsafeWrap2, unsafeWrap3
) where
--------------------------------------------------------------------------------
-- Imports
--------------------------------------------------------------------------------
-- from base:
import Data.Function ( ($) )
import Data.Int ( Int )
import Control.Monad ( liftM )
import System.IO ( IO )
import Foreign.Ptr ( Ptr )
import qualified Foreign.Marshal.Alloc as FMA ( mallocBytes, free )
-- from base-unicode-symbols:
import Data.Function.Unicode ( (∘) )
-- from transformers:
import Control.Monad.Trans ( MonadIO, liftIO )
-- from regions:
import Control.Monad.Trans.Region ( RegionalHandle )
import Control.Monad.Trans.Region.Unsafe ( Resource
, Handle
, openResource
, closeResource
, internalHandle
, mapInternalHandle
)
#ifdef __HADDOCK__
import Control.Monad.Trans.Region ( open )
#endif
--------------------------------------------------------------------------------
-- Memory as a scarce resource
--------------------------------------------------------------------------------
{-| Represents memory of 'size' number of bytes which may be marshalled to or
from Haskell values of type @α@. Before you can use the memory you have to
allocate it using 'open'.
-}
newtype Memory α = Memory { size ∷ Int }
instance Resource (Memory α) where
newtype Handle (Memory α) = Pointer { ptr ∷ Ptr α }
openResource = liftM Pointer ∘ FMA.mallocBytes ∘ size
closeResource = FMA.free ∘ ptr
-- | Handy type synonym for a regional handle to memory. This should provide a
-- safer replacement for @Foreign.Ptr.@'Ptr'
type RegionalPtr α r = RegionalHandle (Memory α) r
--------------------------------------------------------------------------------
-- Utility functions for lifting operations on Ptrs to RegionalPtrs
--------------------------------------------------------------------------------
mapRegionalPtr ∷ (Ptr α → Ptr β) → (RegionalPtr α r → RegionalPtr β r)
mapRegionalPtr f = mapInternalHandle $ Pointer ∘ f ∘ ptr
unsafePtr ∷ RegionalPtr α r → Ptr α
unsafePtr = ptr ∘ internalHandle
unsafeWrap ∷ MonadIO m
⇒ (Ptr α → IO β)
→ (RegionalPtr α r → m β)
unsafeWrap f rp = liftIO $ f $ unsafePtr rp
unsafeWrap2 ∷ MonadIO m
⇒ (Ptr α → γ → IO β)
→ (RegionalPtr α r → γ → m β)
unsafeWrap2 f rp x = liftIO $ f (unsafePtr rp) x
unsafeWrap3 ∷ MonadIO m
⇒ (Ptr α → γ → δ → IO β)
→ (RegionalPtr α r → γ → δ → m β)
unsafeWrap3 f rp x y = liftIO $ f (unsafePtr rp) x y
-- The End ---------------------------------------------------------------------