mcl-1.0.0: src/MCL/Internal/Prim/Unpinned.hs
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE ScopedTypeVariables #-}
module MCL.Internal.Prim.Unpinned where
import Data.Functor.Identity
import Data.Primitive.ByteArray
import Foreign.C.Types
import GHC.Exts
import System.IO.Unsafe
import MCL.Internal.Prim.Class
import MCL.Internal.Utils
{-# INLINABLE withPrim #-}
withPrim :: Prim t => t -> (CC t -> IO r) -> IO r
withPrim fp k = k (prim_unwrap fp)
{-# INLINABLE newPrim #-}
newPrim
:: forall m t r. Prim t
=> (r -> CC t -> m t)
-> (MC t -> IO r)
-> IO (m t)
newPrim = withByteArray1 (prim_size (proxy# :: Proxy# t))
{-# INLINABLE newPrim_ #-}
newPrim_ :: forall t. Prim t => (MC t -> IO ()) -> IO t
newPrim_ = unwrap . newPrim (\_ ba -> Identity (prim_wrap ba))
where
unwrap :: IO (Identity t) -> IO t
unwrap = coerce
{-# INLINABLE maybeNewPrim #-}
maybeNewPrim :: Prim t => (MC t -> IO CInt) -> IO (Maybe t)
maybeNewPrim = newPrim $ \success ba ->
if cintToBool success
then Just (prim_wrap ba)
else Nothing
{-# INLINABLE new2Prim #-}
new2Prim :: forall t. Prim t => (MC t -> MC t -> IO ()) -> IO (t, t)
new2Prim = withByteArray2 (prim_size (proxy# :: Proxy# t)) prim_wrap
----------------------------------------
{-# INLINABLE unsafeOp0 #-}
unsafeOp0 :: IO r -> r
unsafeOp0 = unsafeDupablePerformIO
{-# INLINABLE unsafeOp0_ #-}
unsafeOp0_ :: Prim r => (MC r -> IO ()) -> r
unsafeOp0_ = unsafeOp0 . newPrim_
{-# INLINABLE unsafeOp1 #-}
unsafeOp1
:: Prim t
=> (s -> IO r)
-> (CC t -> s)
-> (t -> r)
unsafeOp1 k c_fun fa =
unsafeOp0 . withPrim fa $ \a -> k (c_fun a)
{-# INLINABLE unsafeOp1_ #-}
unsafeOp1_
:: (Prim t, Prim r)
=> (CC t -> MC r -> IO ())
-> (t -> r)
unsafeOp1_ = unsafeOp1 newPrim_
{-# INLINABLE unsafeOp2 #-}
unsafeOp2
:: (Prim t1, Prim t2)
=> (s -> IO r)
-> (CC t1 -> CC t2 -> s)
-> (t1 -> t2 -> r)
unsafeOp2 k c_fun fa fb =
unsafeOp0 . withPrim fa $ \a -> withPrim fb $ \b -> k (c_fun a b)
{-# INLINABLE unsafeOp2_ #-}
unsafeOp2_
:: (Prim t1, Prim t2, Prim r)
=> (CC t1 -> CC t2 -> MC r -> IO ())
-> (t1 -> t2 -> r)
unsafeOp2_ = unsafeOp2 newPrim_
{-# INLINABLE unsafeOp6 #-}
unsafeOp6
:: (Prim t1, Prim t2, Prim t3, Prim t4, Prim t5, Prim t6)
=> (s -> IO r)
-> (CC t1 -> CC t2 -> CC t3 -> CC t4 -> CC t5 -> CC t6 -> s)
-> (t1 -> t2 -> t3 -> t4 -> t5 -> t6 -> r)
unsafeOp6 k c_fun fa fb fc fd fe ff =
unsafeOp0 . withPrim fa $ \a -> withPrim fb $ \b -> withPrim fc $ \c ->
withPrim fd $ \d -> withPrim fe $ \e -> withPrim ff $ \f ->
k (c_fun a b c d e f)
{-# INLINABLE unsafeOp6_ #-}
unsafeOp6_
:: (Prim t1, Prim t2, Prim t3, Prim t4, Prim t5, Prim t6, Prim r)
=> (CC t1 -> CC t2 -> CC t3 -> CC t4 -> CC t5 -> CC t6 -> MC r -> IO ())
-> (t1 -> t2 -> t3 -> t4 -> t5 -> t6 -> r)
unsafeOp6_ = unsafeOp6 newPrim_
----------------------------------------
-- Utils
{-# INLINABLE withByteArray1 #-}
withByteArray1
:: Int
-> (s -> ByteArray# -> r)
-> (MutableByteArray# RealWorld -> IO s)
-> IO r
withByteArray1 size k c_fun = do
mba@(MutableByteArray umba) <- newByteArray size
r <- c_fun umba
ByteArray uba <- unsafeFreezeByteArray mba
return (k r uba)
{-# INLINABLE withByteArray2 #-}
withByteArray2
:: Int
-> (ByteArray# -> r)
-> (MutableByteArray# RealWorld -> MutableByteArray# RealWorld -> IO ())
-> IO (r, r)
withByteArray2 size k c_fun = do
mba@(MutableByteArray umba) <- newByteArray size
mbb@(MutableByteArray umbb) <- newByteArray size
c_fun umba umbb
ByteArray uba <- unsafeFreezeByteArray mba
ByteArray ubb <- unsafeFreezeByteArray mbb
return (k uba, k ubb)