regional-pointers 0.3 → 0.4
raw patch · 8 files changed
+83/−60 lines, 8 files
Files
- Foreign/C/String/Region.hs +4/−4
- Foreign/Marshal/Alloc/Region.hs +3/−2
- Foreign/Marshal/Array/Region.hs +2/−2
- Foreign/Marshal/Utils/Region.hs +2/−2
- Foreign/Ptr/Region.hs +17/−35
- Foreign/Ptr/Region/Internal.hs +37/−7
- Foreign/Ptr/Region/Unsafe.hs +17/−7
- regional-pointers.cabal +1/−1
Foreign/C/String/Region.hs view
@@ -255,7 +255,7 @@ → (∀ s. RegionalCStringLen (RegionT s pr) → RegionT s pr α) → pr α withCAStringLen str f = withArrayLen (charsToCChars str)- $ \len ptr → f (ptr, len)+ $ \len rPtr → f (rPtr, len) --------------------------------------------------------------------------------@@ -335,7 +335,7 @@ → (∀ s. RegionalCWStringLen (RegionT s pr) → RegionT s pr α) → pr α withCWStringLen str f = withArrayLen (charsToCWchars str)- $ \len ptr → f (ptr, len)+ $ \len rPtr → f (rPtr, len) --------------------------------------------------------------------------------@@ -352,8 +352,8 @@ newArrayLen ∷ (Storable α, MonadCatchIO pr) ⇒ [α] → RegionT s pr (RegionalPtr α (RegionT s pr), Int) newArrayLen xs = do- a <- newArray xs- return (a, length xs)+ rPtr ← newArray xs+ return (rPtr, length xs) charsToCChars ∷ [Char] → [CChar] charsToCChars = map FCS.castCharToCChar
Foreign/Marshal/Alloc/Region.hs view
@@ -58,7 +58,8 @@ import Control.Monad.Trans.Region ( RegionT, runRegionT ) -- from ourselves:-import Foreign.Ptr.Region ( RegionalPtr, regionalPtr )+import Foreign.Ptr.Region ( RegionalPtr )+import Foreign.Ptr.Region.Unsafe ( unsafeRegionalPtr ) --------------------------------------------------------------------------------@@ -121,7 +122,7 @@ → RegionT s pr (RegionalPtr α (RegionT s pr)) mallocBytes size = block $ do ptr ← liftIO $ FMA.mallocBytes size- regionalPtr ptr $ free ptr+ unsafeRegionalPtr ptr $ free ptr -- TODO: -- realloc ∷ (Storable β, pr `ParentOf` cr, MonadIO cr)
Foreign/Marshal/Array/Region.hs view
@@ -264,7 +264,7 @@ → RegionalPtr α pr2 -- ^ Source → Int -- ^ Number of /elements/ to copy. → cr ()-copyArray rp1 rp2 = liftIO ∘ FMA.copyArray (unsafePtr rp1) (unsafePtr rp2)+copyArray rPtr1 rPtr2 = liftIO ∘ FMA.copyArray (unsafePtr rPtr1) (unsafePtr rPtr2) -- | Copy the given number of elements from the second array (source) into the -- first array (destination); the copied areas /may/ overlap.@@ -279,7 +279,7 @@ → RegionalPtr α pr1 -- ^ Source → Int -- ^ Number of /elements/ to move. → cr ()-moveArray rp1 rp2 = liftIO ∘ FMA.moveArray (unsafePtr rp1) (unsafePtr rp2)+moveArray rPtr1 rPtr2 = liftIO ∘ FMA.moveArray (unsafePtr rPtr1) (unsafePtr rPtr2) --------------------------------------------------------------------------------
Foreign/Marshal/Utils/Region.hs view
@@ -126,7 +126,7 @@ → RegionalPtr α pr2 -- ^ Source → Int -- ^ Number of bytes to copy → cr ()-copyBytes rp1 rp2 = liftIO ∘ FMU.copyBytes (unsafePtr rp1) (unsafePtr rp2)+copyBytes rPtr1 rPtr2 = liftIO ∘ FMU.copyBytes (unsafePtr rPtr1) (unsafePtr rPtr2) -- | Copies the given number of bytes from the second area (source) into the -- first (destination); the copied areas /may/ overlap@@ -140,7 +140,7 @@ → RegionalPtr α pr2 -- ^ Source → Int -- ^ Number of bytes to move → cr ()-moveBytes rp1 rp2 = liftIO ∘ FMU.moveBytes (unsafePtr rp1) (unsafePtr rp2)+moveBytes rPtr1 rPtr2 = liftIO ∘ FMU.moveBytes (unsafePtr rPtr1) (unsafePtr rPtr2) -- The End ---------------------------------------------------------------------
Foreign/Ptr/Region.hs view
@@ -13,6 +13,8 @@ ( -- * Regional pointers RegionalPtr + , nullPtr+ {-| Note that this module re-exports the @Control.Monad.Trans.Region@ module from the @regions@ package which allows you to: @@ -24,10 +26,6 @@ -} , module Control.Monad.Trans.Region - -- * Constructing regional pointers- , regionalPtr- , nullPtr- -- * Pure functions on regional pointers , mapRegionalPtr @@ -43,48 +41,32 @@ -------------------------------------------------------------------------------- -- from base:-import Control.Monad ( return, (>>=), fail )-import Data.Function ( ($) )-import Data.Int ( Int )-import Data.Maybe ( Maybe(Nothing, Just) )-import Foreign.Ptr ( Ptr )-import qualified Foreign.Ptr as FP ( nullPtr- , castPtr, plusPtr, alignPtr, minusPtr- )---- from transformers:-import Control.Monad.IO.Class ( MonadIO )+import Data.Int ( Int ) +import Foreign.Ptr ( Ptr )+import qualified Foreign.Ptr as FP ( nullPtr+ , castPtr, plusPtr, alignPtr, minusPtr+ ) -- from regions:-import Control.Monad.Trans.Region -- (re-exported entirely)-import Control.Monad.Trans.Region.OnExit ( CloseAction, onExit )+import Control.Monad.Trans.Region -- (re-exported entirely) -- from ourselves:-import Foreign.Ptr.Region.Internal ( RegionalPtr(RegionalPtr) )-import Foreign.Ptr.Region.Unsafe ( unsafePtr )+import Foreign.Ptr.Region.Internal ( RegionalPtr(RegionalPtr) )+import Foreign.Ptr.Region.Unsafe ( unsafePureRegionalPtr, unsafePtr ) ----------------------------------------------------------------------------------- * Constructing regional pointers+-- * Regional pointers -------------------------------------------------------------------------------- --- | Construct a regional pointer from a native pointer and an @IO@ computation--- that frees the pointer which is executed when the region exits.-regionalPtr ∷ MonadIO pr- ⇒ Ptr α- → CloseAction- → RegionT s pr (RegionalPtr α (RegionT s pr))-regionalPtr ptr freePtr = do ch ← onExit freePtr- return $ RegionalPtr ptr $ Just ch- -- | The constant @nullPtr@ contains a distinguished value of 'RegionalPtr' -- that is not associated with a valid memory location. -- -- Note that @nullPtr@ is a pure value. This means it does not perform the--- side-effect of registering a 'CloseAction' like @free nullPtr@ in the--- 'RegionT' monad.+-- side-effect of registering a finalizer like @free nullPtr@+-- in the 'RegionT' monad. nullPtr ∷ RegionalPtr α r-nullPtr = RegionalPtr FP.nullPtr Nothing+nullPtr = unsafePureRegionalPtr FP.nullPtr --------------------------------------------------------------------------------@@ -105,7 +87,7 @@ -- -- Wraps: @Foreign.Ptr.@'FP.plusPtr' plusPtr ∷ RegionalPtr α r → Int → RegionalPtr β r-plusPtr rp n = mapRegionalPtr (\p → FP.plusPtr p n) rp+plusPtr rPtr n = mapRegionalPtr (\ptr → FP.plusPtr ptr n) rPtr -- | Given an arbitrary address and an alignment constraint, @alignPtr@ yields -- the next higher address that fulfills the alignment constraint. An alignment@@ -114,7 +96,7 @@ -- -- Wraps: @Foreign.Ptr.@'FP.alignPtr' alignPtr ∷ RegionalPtr α r → Int → RegionalPtr α r-alignPtr rp n = mapRegionalPtr (\p → FP.alignPtr p n) rp+alignPtr rPtr n = mapRegionalPtr (\ptr → FP.alignPtr ptr n) rPtr -- | Computes the offset required to get from the second to the first -- argument. We have@@ -123,7 +105,7 @@ -- -- Wraps: @Foreign.Ptr.@'FP.minusPtr' minusPtr ∷ RegionalPtr α r1 → RegionalPtr β r2 → Int-minusPtr rp1 rp2 = FP.minusPtr (unsafePtr rp1) (unsafePtr rp2)+minusPtr rPtr1 rPtr2 = FP.minusPtr (unsafePtr rPtr1) (unsafePtr rPtr2) -- The End ---------------------------------------------------------------------
Foreign/Ptr/Region/Internal.hs view
@@ -16,7 +16,11 @@ ( -- * Regional pointers RegionalPtr(RegionalPtr) - -- * Utility functions for lifting operations on Ptrs to RegionalPtrs+ -- * Unsafely constructing regional pointers+ , unsafeRegionalPtr+ , unsafePureRegionalPtr++ -- * Unsafe utility functions for lifting operations on @Ptrs@ to @RegionalPtrs@ , unsafePtr , unsafeWrap, unsafeWrap2, unsafeWrap3 ) where@@ -37,8 +41,8 @@ import Control.Monad.IO.Class ( MonadIO, liftIO ) -- from regions:-import Control.Monad.Trans.Region.OnExit ( CloseHandle )-import Control.Monad.Trans.Region ( Dup(dup) )+import Control.Monad.Trans.Region.OnExit ( CloseHandle, CloseAction, onExit )+import Control.Monad.Trans.Region ( RegionT, Dup(dup) ) --------------------------------------------------------------------------------@@ -47,14 +51,40 @@ -- | A regional handle to memory. This should provide a safer replacement for -- @Foreign.Ptr.'Ptr'@-data RegionalPtr α (r ∷ * → *) = RegionalPtr (Ptr α) (Maybe (CloseHandle r))+data RegionalPtr α (r ∷ * → *) = RegionalPtr !(Ptr α) !(Maybe (CloseHandle r)) instance Dup (RegionalPtr α) where dup (RegionalPtr ptr Nothing) = return $ RegionalPtr ptr Nothing dup (RegionalPtr ptr (Just ch)) = do ch' ← dup ch return $ RegionalPtr ptr $ Just ch' +--------------------------------------------------------------------------------+-- * Constructing regional pointers+-------------------------------------------------------------------------------- +-- | Construct a regional pointer from a native pointer+-- and an @IO@ computation that finalizes the pointer (like @free ptr@)+-- which is executed when the region exits.+--+-- This function is considered unsafe because this library can't guarantee that+-- the finalizer will actually finalize the pointer (suppose having @return ()@+-- as the finalizer). You have to verify the correct finalisation yourself.+unsafeRegionalPtr ∷ MonadIO pr+ ⇒ Ptr α+ → CloseAction+ → RegionT s pr (RegionalPtr α (RegionT s pr))+unsafeRegionalPtr ptr finalize = do ch ← onExit finalize+ return $ RegionalPtr ptr $ Just ch++-- | Construct a regional pointer from a native pointer+-- without registering a finalizer like @free ptr@.+--+-- This function is considered unsafe because this library can't guarantee the+-- finalisation of the pointer, you have to do that yourself.+unsafePureRegionalPtr ∷ Ptr α → RegionalPtr α r+unsafePureRegionalPtr ptr = RegionalPtr ptr Nothing++ -------------------------------------------------------------------------------- -- * Utility functions for lifting operations on Ptrs to RegionalPtrs --------------------------------------------------------------------------------@@ -65,17 +95,17 @@ unsafeWrap ∷ MonadIO m ⇒ (Ptr α → IO β) → (RegionalPtr α r → m β)-unsafeWrap f rp = liftIO $ f $ unsafePtr rp+unsafeWrap f rPtr = liftIO $ f (unsafePtr rPtr) unsafeWrap2 ∷ MonadIO m ⇒ (Ptr α → γ → IO β) → (RegionalPtr α r → γ → m β)-unsafeWrap2 f rp x = liftIO $ f (unsafePtr rp) x+unsafeWrap2 f rPtr x = liftIO $ f (unsafePtr rPtr) x unsafeWrap3 ∷ MonadIO m ⇒ (Ptr α → γ → δ → IO β) → (RegionalPtr α r → γ → δ → m β)-unsafeWrap3 f rp x y = liftIO $ f (unsafePtr rp) x y+unsafeWrap3 f rPtr x y = liftIO $ f (unsafePtr rPtr) x y -- The End ---------------------------------------------------------------------
Foreign/Ptr/Region/Unsafe.hs view
@@ -7,20 +7,30 @@ -- License : BSD3 (see the file LICENSE) -- Maintainer : Bas van Dijk <v.dijk.bas@gmail.com> ----- /Unsafe/ functions for retrieving the actual @Ptr@ from a regional pointer--- and for lifting operations on @Ptrs@ to @RegionalPtrs@.+-- /Unsafe/ functions for constructing regional pointers, retrieving the native+-- @Ptr@ from a regional pointer and for lifting operations on @Ptrs@ to+-- @RegionalPtrs@. ----- These operations are unsafe because they allow you to @free@ the regional--- pointer before exiting their region. So they enable you to perform @IO@ with--- already freed pointers. -- ------------------------------------------------------------------------------- module Foreign.Ptr.Region.Unsafe- ( unsafePtr+ ( -- * Unsafely constructing regional pointers+ unsafeRegionalPtr+ , unsafePureRegionalPtr++ -- * Unsafe utility functions for lifting operations on @Ptrs@ to @RegionalPtrs@++ -- | These operations are unsafe because they allow you to @free@ the+ -- regional pointer before exiting their region. So they enable you to+ -- perform @IO@ with already freed pointers.+ , unsafePtr , unsafeWrap, unsafeWrap2, unsafeWrap3 ) where -import Foreign.Ptr.Region.Internal ( unsafePtr+import Foreign.Ptr.Region.Internal ( unsafeRegionalPtr+ , unsafePureRegionalPtr++ , unsafePtr , unsafeWrap, unsafeWrap2, unsafeWrap3 )
regional-pointers.cabal view
@@ -1,5 +1,5 @@ name: regional-pointers-version: 0.3+version: 0.4 cabal-version: >=1.6 build-type: Custom license: BSD3