{-# LANGUAGE CPP #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE FlexibleContexts #-}

#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Safe #-}
#endif

{- |
Module      :  Foreign.Marshal.Utils.Lifted
Copyright   :  Bas van Dijk, Anders Kaseorg, Michael Steele
License     :  BSD-style

Maintainer  :  Bas van Dijk <v.dijk.bas@gmail.com>
Stability   :  experimental
Portability :  non-portable (extended exceptions)

This is a wrapped version of "Foreign.Marshal.Utils" with types generalized
from 'IO' to all monads in either 'MonadBase' or 'MonadBaseControl'.
-}

module Foreign.Marshal.Utils.Lifted
  ( with
  ) where

-- from base:
import qualified Foreign as F
import System.IO     ( IO )
import Prelude ( (.) )

-- from monad-control:
import Control.Monad.Trans.Control ( MonadBaseControl
                                   , liftBaseOp )

-- |Generalized version of 'F.with'.
--
-- Note, when the given function throws an exception any monadic side
-- effects in @m@ will be discarded.
with :: (MonadBaseControl IO m, F.Storable a)
     => a                -- ^ value to be poked
     -> (F.Ptr a -> m b) -- ^ computation to run
     -> m b
with = liftBaseOp . F.with
{-# INLINEABLE with #-}

{-# LANGUAGE CPP #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE FlexibleContexts #-}

#if __GLASGOW_HASKELL__ >= 710
{-# LANGUAGE Safe #-}
#elif __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif

{- |
Module      :  Foreign.Marshal.Utils.Lifted
Copyright   :  Bas van Dijk, Anders Kaseorg, Michael Steele
License     :  BSD-style

Maintainer  :  Bas van Dijk <v.dijk.bas@gmail.com>
Stability   :  experimental
Portability :  non-portable (extended exceptions)

This is a wrapped version of "Foreign.Marshal.Utils" with types generalized
from 'IO' to all monads in either 'MonadBase' or 'MonadBaseControl'.
-}

module Foreign.Marshal.Utils.Lifted
  ( with
  ) where

-- from base:
import qualified Foreign as F
import System.IO     ( IO )
import Prelude ( (.) )

-- from monad-control:
import Control.Monad.Trans.Control ( MonadBaseControl
                                   , liftBaseOp )

-- |Generalized version of 'F.with'.
--
-- Note, when the given function throws an exception any monadic side
-- effects in @m@ will be discarded.
with :: (MonadBaseControl IO m, F.Storable a)
     => a                -- ^ value to be poked
     -> (F.Ptr a -> m b) -- ^ computation to run
     -> m b
with = liftBaseOp . F.with
{-# INLINEABLE with #-}

Fix build with ghc 7.8
Fix build with ghc 7.8

Building with ghc-7.8 results in:

    Foreign: Can't be safely imported! The module itself isn't safe.

Keep `Safe` for ghc 7.10 and above but switch back to `Trustworthy` for
earlier versions. Tested with 7.8.4, 7.10.3 and 8.0.1

Closes: https://github.com/basvandijk/lifted-base/issues/31

h '#' will be ignored, and an empty message aborts the commit.
