{-# 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 -- ------------------------------------------------------------------------------- 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 ---------------------------------------------------------------------