module Foreign.Ptr.Region.Internal
(
RegionalPtr(RegionalPtr)
, unsafeRegionalPtr
, wrapMalloc
, nullPtr, NullPtr
, LocalPtr
, wrapAlloca, wrapAlloca2
, wrapPeekStringLen
, wrapNewStringLen
, wrapWithStringLen
, Pointer(unsafePtr, mapPointer)
, unsafeWrap, unsafeWrap2, unsafeWrap3
, unsafeWrap2flp
, AllocatedPointer
) where
import Control.Monad ( return, liftM )
import Control.Arrow ( first )
import Data.Function ( ($), flip )
import Data.Int ( Int )
import Data.Char ( String )
import System.IO ( IO )
import Foreign.Ptr ( Ptr )
import qualified Foreign.Ptr as FP ( nullPtr )
import Foreign.Marshal.Alloc ( free )
#if __GLASGOW_HASKELL__ < 700
import Control.Monad ( (>>=), fail )
#endif
import Data.Function.Unicode ( (∘) )
import Control.Monad.IO.Class ( MonadIO, liftIO )
import Control.Monad.Trans.Region.OnExit ( FinalizerHandle, Finalizer, onExit )
import Control.Monad.Trans.Region ( RegionT
, AncestorRegion
, RootRegion
, LocalRegion, Local
, Dup(dup)
)
import Control.Monad.Trans.Region.Unsafe ( unsafeStripLocal )
import Control.Monad.IO.Control ( MonadControlIO, controlIO, liftIOOp )
#if MIN_VERSION_base(4,3,0)
import Control.Exception.Control ( mask_ )
#else
import Control.Exception.Control ( block )
mask_ ∷ MonadControlIO m ⇒ m a → m a
mask_ = block
#endif
data RegionalPtr α (r ∷ * → *) = RegionalPtr !(Ptr α) !(FinalizerHandle r)
instance Dup (RegionalPtr α) where
dup (RegionalPtr ptr ch) = liftM (RegionalPtr ptr) (dup ch)
unsafeRegionalPtr ∷ MonadIO pr
⇒ Ptr α
→ Finalizer
→ RegionT s pr (RegionalPtr α (RegionT s pr))
unsafeRegionalPtr ptr finalize = liftM (RegionalPtr ptr) (onExit finalize)
wrapMalloc ∷ MonadControlIO pr
⇒ IO (Ptr α) → RegionT s pr (RegionalPtr α (RegionT s pr))
wrapMalloc doMalloc = mask_ $ do
ptr ← liftIO doMalloc
unsafeRegionalPtr ptr (free ptr)
nullPtr ∷ NullPtr α RootRegion
nullPtr = NullPtr FP.nullPtr
newtype NullPtr α (r ∷ * → *) = NullPtr (Ptr α)
newtype LocalPtr α (r ∷ * → *) = LocalPtr (Ptr α)
wrapAlloca ∷ MonadControlIO pr
⇒ ((Ptr α → IO (RegionT s pr β)) → IO (RegionT s pr β))
→ (∀ sl. LocalPtr α (LocalRegion sl s) → RegionT (Local s) pr β)
→ RegionT s pr β
wrapAlloca doAlloca f = liftIOOp doAlloca $
unsafeStripLocal ∘ f ∘ LocalPtr
wrapAlloca2 ∷ MonadControlIO pr
⇒ ((γ → Ptr α → IO (RegionT s pr β)) → IO (RegionT s pr β))
→ (∀ sl. γ → LocalPtr α (LocalRegion sl s) → RegionT (Local s) pr β)
→ RegionT s pr β
wrapAlloca2 doAlloca f = controlIO $ \runInIO →
doAlloca $ \s →
runInIO ∘ unsafeStripLocal ∘ f s ∘ LocalPtr
wrapPeekStringLen ∷ (Pointer pointer, pr `AncestorRegion` cr, MonadIO cr)
⇒ ((Ptr α, Int) → IO String)
→ (pointer α pr, Int) → cr String
wrapPeekStringLen peekStringLen = liftIO ∘ peekStringLen ∘ first unsafePtr
wrapNewStringLen ∷ MonadControlIO pr
⇒ IO (Ptr α, Int)
→ RegionT s pr (RegionalPtr α (RegionT s pr), Int)
wrapNewStringLen newStringLen = mask_ $ do
(ptr, len) ← liftIO newStringLen
rPtr ← unsafeRegionalPtr ptr (free ptr)
return (rPtr, len)
wrapWithStringLen ∷ MonadControlIO pr
⇒ (((Ptr α, Int) → IO (RegionT s pr β)) → IO (RegionT s pr β))
→ (∀ sl. (LocalPtr α (LocalRegion sl s), Int) → RegionT (Local s) pr β)
→ RegionT s pr β
wrapWithStringLen withStringLen f = liftIOOp withStringLen $
unsafeStripLocal ∘ f ∘ first LocalPtr
class Pointer (pointer ∷ * → (* → *) → *) where
unsafePtr ∷ pointer α r → Ptr α
mapPointer ∷ (Ptr α → Ptr β) → (pointer α r → pointer β r)
instance Pointer RegionalPtr where
unsafePtr (RegionalPtr ptr _) = ptr
mapPointer f (RegionalPtr ptr ch) = RegionalPtr (f ptr) ch
instance Pointer NullPtr where
unsafePtr (NullPtr ptr) = ptr
mapPointer f (NullPtr ptr) = NullPtr (f ptr)
instance Pointer LocalPtr where
unsafePtr (LocalPtr ptr) = ptr
mapPointer f (LocalPtr ptr) = LocalPtr (f ptr)
unsafeWrap ∷ (MonadIO m, Pointer pointer)
⇒ (Ptr α → IO β)
→ (pointer α r → m β)
unsafeWrap f pointer = liftIO $ f (unsafePtr pointer)
unsafeWrap2 ∷ (MonadIO m, Pointer pointer)
⇒ (Ptr α → γ → IO β)
→ (pointer α r → γ → m β)
unsafeWrap2 f pointer x = liftIO $ f (unsafePtr pointer) x
unsafeWrap3 ∷ (MonadIO m, Pointer pointer)
⇒ (Ptr α → γ → δ → IO β)
→ (pointer α r → γ → δ → m β)
unsafeWrap3 f pointer x y = liftIO $ f (unsafePtr pointer) x y
unsafeWrap2flp ∷ (MonadIO m, Pointer pointer)
⇒ (γ → Ptr α → IO β)
→ (γ → pointer α r → m β)
unsafeWrap2flp = flip ∘ unsafeWrap2 ∘ flip
class Pointer pointer ⇒ PrivateAllocatedPointer pointer
class PrivateAllocatedPointer pointer ⇒ AllocatedPointer pointer
instance PrivateAllocatedPointer RegionalPtr; instance AllocatedPointer RegionalPtr
instance PrivateAllocatedPointer LocalPtr; instance AllocatedPointer LocalPtr