{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleContexts #-}
-- |various common data-passing conventions
module Foreign.Ptr.Conventions where

-- TODO: make these all exception-safe
-- TODO: reverse order of 'out' returns
-- TODO: bytestring versions?  versions allocating by byte but using vectors?
import Foreign.C.Types
import Foreign.Marshal
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.Storable

import Control.Monad.IO.Class
import Control.Monad.Trans.Control
import Control.Exception.Lifted

import qualified Data.ByteString as BS
import qualified Data.Vector.Storable as SV
import qualified Data.Vector.Storable.Mutable as SVM

class WrappedPtr p where
    wrapPtr         :: Ptr a -> p a
    unwrapPtr       :: p a -> Ptr a
    nullWrappedPtr  :: p a
    nullWrappedPtr = Ptr a -> p a
forall a. Ptr a -> p a
forall (p :: * -> *) a. WrappedPtr p => Ptr a -> p a
wrapPtr Ptr a
forall a. Ptr a
nullPtr
    castWrappedPtr  :: p a -> p b
    castWrappedPtr = Ptr b -> p b
forall a. Ptr a -> p a
forall (p :: * -> *) a. WrappedPtr p => Ptr a -> p a
wrapPtr (Ptr b -> p b) -> (p a -> Ptr b) -> p a -> p b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr (Ptr a -> Ptr b) -> (p a -> Ptr a) -> p a -> Ptr b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p a -> Ptr a
forall a. p a -> Ptr a
forall (p :: * -> *) a. WrappedPtr p => p a -> Ptr a
unwrapPtr

instance WrappedPtr Foreign.Ptr.Ptr where
    wrapPtr :: forall a. Ptr a -> Ptr a
wrapPtr         = Ptr a -> Ptr a
forall a. a -> a
id
    unwrapPtr :: forall a. Ptr a -> Ptr a
unwrapPtr       = Ptr a -> Ptr a
forall a. a -> a
id
    nullWrappedPtr :: forall a. Ptr a
nullWrappedPtr  = Ptr a
forall a. Ptr a
nullPtr
    castWrappedPtr :: forall a b. Ptr a -> Ptr b
castWrappedPtr  = Ptr a -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr

-- * Input pointers

-- |In by-ref parameter; memory is allocated and freed by caller
newtype In       a = In       (Ptr a) deriving (In a -> In a -> Bool
(In a -> In a -> Bool) -> (In a -> In a -> Bool) -> Eq (In a)
forall a. In a -> In a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. In a -> In a -> Bool
== :: In a -> In a -> Bool
$c/= :: forall a. In a -> In a -> Bool
/= :: In a -> In a -> Bool
Eq, Eq (In a)
Eq (In a) =>
(In a -> In a -> Ordering)
-> (In a -> In a -> Bool)
-> (In a -> In a -> Bool)
-> (In a -> In a -> Bool)
-> (In a -> In a -> Bool)
-> (In a -> In a -> In a)
-> (In a -> In a -> In a)
-> Ord (In a)
In a -> In a -> Bool
In a -> In a -> Ordering
In a -> In a -> In a
forall a. Eq (In a)
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. In a -> In a -> Bool
forall a. In a -> In a -> Ordering
forall a. In a -> In a -> In a
$ccompare :: forall a. In a -> In a -> Ordering
compare :: In a -> In a -> Ordering
$c< :: forall a. In a -> In a -> Bool
< :: In a -> In a -> Bool
$c<= :: forall a. In a -> In a -> Bool
<= :: In a -> In a -> Bool
$c> :: forall a. In a -> In a -> Bool
> :: In a -> In a -> Bool
$c>= :: forall a. In a -> In a -> Bool
>= :: In a -> In a -> Bool
$cmax :: forall a. In a -> In a -> In a
max :: In a -> In a -> In a
$cmin :: forall a. In a -> In a -> In a
min :: In a -> In a -> In a
Ord, Int -> In a -> ShowS
[In a] -> ShowS
In a -> String
(Int -> In a -> ShowS)
-> (In a -> String) -> ([In a] -> ShowS) -> Show (In a)
forall a. Int -> In a -> ShowS
forall a. [In a] -> ShowS
forall a. In a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Int -> In a -> ShowS
showsPrec :: Int -> In a -> ShowS
$cshow :: forall a. In a -> String
show :: In a -> String
$cshowList :: forall a. [In a] -> ShowS
showList :: [In a] -> ShowS
Show, Ptr (In a) -> IO (In a)
Ptr (In a) -> Int -> IO (In a)
Ptr (In a) -> Int -> In a -> IO ()
Ptr (In a) -> In a -> IO ()
In a -> Int
(In a -> Int)
-> (In a -> Int)
-> (Ptr (In a) -> Int -> IO (In a))
-> (Ptr (In a) -> Int -> In a -> IO ())
-> (forall b. Ptr b -> Int -> IO (In a))
-> (forall b. Ptr b -> Int -> In a -> IO ())
-> (Ptr (In a) -> IO (In a))
-> (Ptr (In a) -> In a -> IO ())
-> Storable (In a)
forall b. Ptr b -> Int -> IO (In a)
forall b. Ptr b -> Int -> In a -> IO ()
forall a. Ptr (In a) -> IO (In a)
forall a. Ptr (In a) -> Int -> IO (In a)
forall a. Ptr (In a) -> Int -> In a -> IO ()
forall a. Ptr (In a) -> In a -> IO ()
forall a. In a -> Int
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
forall a b. Ptr b -> Int -> IO (In a)
forall a b. Ptr b -> Int -> In a -> IO ()
$csizeOf :: forall a. In a -> Int
sizeOf :: In a -> Int
$calignment :: forall a. In a -> Int
alignment :: In a -> Int
$cpeekElemOff :: forall a. Ptr (In a) -> Int -> IO (In a)
peekElemOff :: Ptr (In a) -> Int -> IO (In a)
$cpokeElemOff :: forall a. Ptr (In a) -> Int -> In a -> IO ()
pokeElemOff :: Ptr (In a) -> Int -> In a -> IO ()
$cpeekByteOff :: forall a b. Ptr b -> Int -> IO (In a)
peekByteOff :: forall b. Ptr b -> Int -> IO (In a)
$cpokeByteOff :: forall a b. Ptr b -> Int -> In a -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> In a -> IO ()
$cpeek :: forall a. Ptr (In a) -> IO (In a)
peek :: Ptr (In a) -> IO (In a)
$cpoke :: forall a. Ptr (In a) -> In a -> IO ()
poke :: Ptr (In a) -> In a -> IO ()
Storable, (forall a. Ptr a -> In a)
-> (forall a. In a -> Ptr a)
-> (forall a. In a)
-> (forall a b. In a -> In b)
-> WrappedPtr In
forall a. In a
forall a. Ptr a -> In a
forall a. In a -> Ptr a
forall a b. In a -> In b
forall (p :: * -> *).
(forall a. Ptr a -> p a)
-> (forall a. p a -> Ptr a)
-> (forall a. p a)
-> (forall a b. p a -> p b)
-> WrappedPtr p
$cwrapPtr :: forall a. Ptr a -> In a
wrapPtr :: forall a. Ptr a -> In a
$cunwrapPtr :: forall a. In a -> Ptr a
unwrapPtr :: forall a. In a -> Ptr a
$cnullWrappedPtr :: forall a. In a
nullWrappedPtr :: forall a. In a
$ccastWrappedPtr :: forall a b. In a -> In b
castWrappedPtr :: forall a b. In a -> In b
WrappedPtr)

-- |In by-ref array; memory is allocated and freed by caller
newtype InArray  a = InArray  (Ptr a) deriving (InArray a -> InArray a -> Bool
(InArray a -> InArray a -> Bool)
-> (InArray a -> InArray a -> Bool) -> Eq (InArray a)
forall a. InArray a -> InArray a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. InArray a -> InArray a -> Bool
== :: InArray a -> InArray a -> Bool
$c/= :: forall a. InArray a -> InArray a -> Bool
/= :: InArray a -> InArray a -> Bool
Eq, Eq (InArray a)
Eq (InArray a) =>
(InArray a -> InArray a -> Ordering)
-> (InArray a -> InArray a -> Bool)
-> (InArray a -> InArray a -> Bool)
-> (InArray a -> InArray a -> Bool)
-> (InArray a -> InArray a -> Bool)
-> (InArray a -> InArray a -> InArray a)
-> (InArray a -> InArray a -> InArray a)
-> Ord (InArray a)
InArray a -> InArray a -> Bool
InArray a -> InArray a -> Ordering
InArray a -> InArray a -> InArray a
forall a. Eq (InArray a)
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. InArray a -> InArray a -> Bool
forall a. InArray a -> InArray a -> Ordering
forall a. InArray a -> InArray a -> InArray a
$ccompare :: forall a. InArray a -> InArray a -> Ordering
compare :: InArray a -> InArray a -> Ordering
$c< :: forall a. InArray a -> InArray a -> Bool
< :: InArray a -> InArray a -> Bool
$c<= :: forall a. InArray a -> InArray a -> Bool
<= :: InArray a -> InArray a -> Bool
$c> :: forall a. InArray a -> InArray a -> Bool
> :: InArray a -> InArray a -> Bool
$c>= :: forall a. InArray a -> InArray a -> Bool
>= :: InArray a -> InArray a -> Bool
$cmax :: forall a. InArray a -> InArray a -> InArray a
max :: InArray a -> InArray a -> InArray a
$cmin :: forall a. InArray a -> InArray a -> InArray a
min :: InArray a -> InArray a -> InArray a
Ord, Int -> InArray a -> ShowS
[InArray a] -> ShowS
InArray a -> String
(Int -> InArray a -> ShowS)
-> (InArray a -> String)
-> ([InArray a] -> ShowS)
-> Show (InArray a)
forall a. Int -> InArray a -> ShowS
forall a. [InArray a] -> ShowS
forall a. InArray a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Int -> InArray a -> ShowS
showsPrec :: Int -> InArray a -> ShowS
$cshow :: forall a. InArray a -> String
show :: InArray a -> String
$cshowList :: forall a. [InArray a] -> ShowS
showList :: [InArray a] -> ShowS
Show, Ptr (InArray a) -> IO (InArray a)
Ptr (InArray a) -> Int -> IO (InArray a)
Ptr (InArray a) -> Int -> InArray a -> IO ()
Ptr (InArray a) -> InArray a -> IO ()
InArray a -> Int
(InArray a -> Int)
-> (InArray a -> Int)
-> (Ptr (InArray a) -> Int -> IO (InArray a))
-> (Ptr (InArray a) -> Int -> InArray a -> IO ())
-> (forall b. Ptr b -> Int -> IO (InArray a))
-> (forall b. Ptr b -> Int -> InArray a -> IO ())
-> (Ptr (InArray a) -> IO (InArray a))
-> (Ptr (InArray a) -> InArray a -> IO ())
-> Storable (InArray a)
forall b. Ptr b -> Int -> IO (InArray a)
forall b. Ptr b -> Int -> InArray a -> IO ()
forall a. Ptr (InArray a) -> IO (InArray a)
forall a. Ptr (InArray a) -> Int -> IO (InArray a)
forall a. Ptr (InArray a) -> Int -> InArray a -> IO ()
forall a. Ptr (InArray a) -> InArray a -> IO ()
forall a. InArray a -> Int
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
forall a b. Ptr b -> Int -> IO (InArray a)
forall a b. Ptr b -> Int -> InArray a -> IO ()
$csizeOf :: forall a. InArray a -> Int
sizeOf :: InArray a -> Int
$calignment :: forall a. InArray a -> Int
alignment :: InArray a -> Int
$cpeekElemOff :: forall a. Ptr (InArray a) -> Int -> IO (InArray a)
peekElemOff :: Ptr (InArray a) -> Int -> IO (InArray a)
$cpokeElemOff :: forall a. Ptr (InArray a) -> Int -> InArray a -> IO ()
pokeElemOff :: Ptr (InArray a) -> Int -> InArray a -> IO ()
$cpeekByteOff :: forall a b. Ptr b -> Int -> IO (InArray a)
peekByteOff :: forall b. Ptr b -> Int -> IO (InArray a)
$cpokeByteOff :: forall a b. Ptr b -> Int -> InArray a -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> InArray a -> IO ()
$cpeek :: forall a. Ptr (InArray a) -> IO (InArray a)
peek :: Ptr (InArray a) -> IO (InArray a)
$cpoke :: forall a. Ptr (InArray a) -> InArray a -> IO ()
poke :: Ptr (InArray a) -> InArray a -> IO ()
Storable, (forall a. Ptr a -> InArray a)
-> (forall a. InArray a -> Ptr a)
-> (forall a. InArray a)
-> (forall a b. InArray a -> InArray b)
-> WrappedPtr InArray
forall a. InArray a
forall a. Ptr a -> InArray a
forall a. InArray a -> Ptr a
forall a b. InArray a -> InArray b
forall (p :: * -> *).
(forall a. Ptr a -> p a)
-> (forall a. p a -> Ptr a)
-> (forall a. p a)
-> (forall a b. p a -> p b)
-> WrappedPtr p
$cwrapPtr :: forall a. Ptr a -> InArray a
wrapPtr :: forall a. Ptr a -> InArray a
$cunwrapPtr :: forall a. InArray a -> Ptr a
unwrapPtr :: forall a. InArray a -> Ptr a
$cnullWrappedPtr :: forall a. InArray a
nullWrappedPtr :: forall a. InArray a
$ccastWrappedPtr :: forall a b. InArray a -> InArray b
castWrappedPtr :: forall a b. InArray a -> InArray b
WrappedPtr)

withIn :: (Storable a, MonadBaseControl IO m) => a -> (In a -> m b) -> m b
withIn :: forall a (m :: * -> *) b.
(Storable a, MonadBaseControl IO m) =>
a -> (In a -> m b) -> m b
withIn a
x In a -> m b
f = ((Ptr a -> IO (StM m b)) -> IO (StM m b)) -> (Ptr a -> m b) -> m b
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (a -> (Ptr a -> IO (StM m b)) -> IO (StM m b)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with a
x) (In a -> m b
f (In a -> m b) -> (Ptr a -> In a) -> Ptr a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> In a
forall a. Ptr a -> In a
In)

withInList :: (Storable a, MonadBaseControl IO m) => [a] -> (InArray a -> m b) -> m b
withInList :: forall a (m :: * -> *) b.
(Storable a, MonadBaseControl IO m) =>
[a] -> (InArray a -> m b) -> m b
withInList [a]
xs InArray a -> m b
f = ((Ptr a -> IO (StM m b)) -> IO (StM m b)) -> (Ptr a -> m b) -> m b
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp ([a] -> (Ptr a -> IO (StM m b)) -> IO (StM m b)
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray [a]
xs) (InArray a -> m b
f (InArray a -> m b) -> (Ptr a -> InArray a) -> Ptr a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> InArray a
forall a. Ptr a -> InArray a
InArray)

withInVector :: (Storable a, MonadBaseControl IO m) => SV.Vector a -> (InArray a -> m b) -> m b
withInVector :: forall a (m :: * -> *) b.
(Storable a, MonadBaseControl IO m) =>
Vector a -> (InArray a -> m b) -> m b
withInVector Vector a
vec InArray a -> m b
f = ((Ptr a -> IO (StM m b)) -> IO (StM m b)) -> (Ptr a -> m b) -> m b
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (Vector a -> (Ptr a -> IO (StM m b)) -> IO (StM m b)
forall a b. Storable a => Vector a -> (Ptr a -> IO b) -> IO b
SV.unsafeWith Vector a
vec) (InArray a -> m b
f (InArray a -> m b) -> (Ptr a -> InArray a) -> Ptr a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> InArray a
forall a. Ptr a -> InArray a
InArray)

withInMVector :: (Storable a, MonadBaseControl IO m) => SVM.IOVector a -> (InArray a -> m b) -> m b
withInMVector :: forall a (m :: * -> *) b.
(Storable a, MonadBaseControl IO m) =>
IOVector a -> (InArray a -> m b) -> m b
withInMVector IOVector a
vec InArray a -> m b
f = ((Ptr a -> IO (StM m b)) -> IO (StM m b)) -> (Ptr a -> m b) -> m b
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (IOVector a -> (Ptr a -> IO (StM m b)) -> IO (StM m b)
forall a b. Storable a => IOVector a -> (Ptr a -> IO b) -> IO b
SVM.unsafeWith IOVector a
vec) (InArray a -> m b
f (InArray a -> m b) -> (Ptr a -> InArray a) -> Ptr a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> InArray a
forall a. Ptr a -> InArray a
InArray)

-- * Output pointers

-- |Out by-ref parameter; memory is allocated and freed by caller
newtype Out      a = Out      (Ptr a) deriving (Out a -> Out a -> Bool
(Out a -> Out a -> Bool) -> (Out a -> Out a -> Bool) -> Eq (Out a)
forall a. Out a -> Out a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Out a -> Out a -> Bool
== :: Out a -> Out a -> Bool
$c/= :: forall a. Out a -> Out a -> Bool
/= :: Out a -> Out a -> Bool
Eq, Eq (Out a)
Eq (Out a) =>
(Out a -> Out a -> Ordering)
-> (Out a -> Out a -> Bool)
-> (Out a -> Out a -> Bool)
-> (Out a -> Out a -> Bool)
-> (Out a -> Out a -> Bool)
-> (Out a -> Out a -> Out a)
-> (Out a -> Out a -> Out a)
-> Ord (Out a)
Out a -> Out a -> Bool
Out a -> Out a -> Ordering
Out a -> Out a -> Out a
forall a. Eq (Out a)
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Out a -> Out a -> Bool
forall a. Out a -> Out a -> Ordering
forall a. Out a -> Out a -> Out a
$ccompare :: forall a. Out a -> Out a -> Ordering
compare :: Out a -> Out a -> Ordering
$c< :: forall a. Out a -> Out a -> Bool
< :: Out a -> Out a -> Bool
$c<= :: forall a. Out a -> Out a -> Bool
<= :: Out a -> Out a -> Bool
$c> :: forall a. Out a -> Out a -> Bool
> :: Out a -> Out a -> Bool
$c>= :: forall a. Out a -> Out a -> Bool
>= :: Out a -> Out a -> Bool
$cmax :: forall a. Out a -> Out a -> Out a
max :: Out a -> Out a -> Out a
$cmin :: forall a. Out a -> Out a -> Out a
min :: Out a -> Out a -> Out a
Ord, Int -> Out a -> ShowS
[Out a] -> ShowS
Out a -> String
(Int -> Out a -> ShowS)
-> (Out a -> String) -> ([Out a] -> ShowS) -> Show (Out a)
forall a. Int -> Out a -> ShowS
forall a. [Out a] -> ShowS
forall a. Out a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Int -> Out a -> ShowS
showsPrec :: Int -> Out a -> ShowS
$cshow :: forall a. Out a -> String
show :: Out a -> String
$cshowList :: forall a. [Out a] -> ShowS
showList :: [Out a] -> ShowS
Show, Ptr (Out a) -> IO (Out a)
Ptr (Out a) -> Int -> IO (Out a)
Ptr (Out a) -> Int -> Out a -> IO ()
Ptr (Out a) -> Out a -> IO ()
Out a -> Int
(Out a -> Int)
-> (Out a -> Int)
-> (Ptr (Out a) -> Int -> IO (Out a))
-> (Ptr (Out a) -> Int -> Out a -> IO ())
-> (forall b. Ptr b -> Int -> IO (Out a))
-> (forall b. Ptr b -> Int -> Out a -> IO ())
-> (Ptr (Out a) -> IO (Out a))
-> (Ptr (Out a) -> Out a -> IO ())
-> Storable (Out a)
forall b. Ptr b -> Int -> IO (Out a)
forall b. Ptr b -> Int -> Out a -> IO ()
forall a. Ptr (Out a) -> IO (Out a)
forall a. Ptr (Out a) -> Int -> IO (Out a)
forall a. Ptr (Out a) -> Int -> Out a -> IO ()
forall a. Ptr (Out a) -> Out a -> IO ()
forall a. Out a -> Int
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
forall a b. Ptr b -> Int -> IO (Out a)
forall a b. Ptr b -> Int -> Out a -> IO ()
$csizeOf :: forall a. Out a -> Int
sizeOf :: Out a -> Int
$calignment :: forall a. Out a -> Int
alignment :: Out a -> Int
$cpeekElemOff :: forall a. Ptr (Out a) -> Int -> IO (Out a)
peekElemOff :: Ptr (Out a) -> Int -> IO (Out a)
$cpokeElemOff :: forall a. Ptr (Out a) -> Int -> Out a -> IO ()
pokeElemOff :: Ptr (Out a) -> Int -> Out a -> IO ()
$cpeekByteOff :: forall a b. Ptr b -> Int -> IO (Out a)
peekByteOff :: forall b. Ptr b -> Int -> IO (Out a)
$cpokeByteOff :: forall a b. Ptr b -> Int -> Out a -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> Out a -> IO ()
$cpeek :: forall a. Ptr (Out a) -> IO (Out a)
peek :: Ptr (Out a) -> IO (Out a)
$cpoke :: forall a. Ptr (Out a) -> Out a -> IO ()
poke :: Ptr (Out a) -> Out a -> IO ()
Storable, (forall a. Ptr a -> Out a)
-> (forall a. Out a -> Ptr a)
-> (forall a. Out a)
-> (forall a b. Out a -> Out b)
-> WrappedPtr Out
forall a. Out a
forall a. Ptr a -> Out a
forall a. Out a -> Ptr a
forall a b. Out a -> Out b
forall (p :: * -> *).
(forall a. Ptr a -> p a)
-> (forall a. p a -> Ptr a)
-> (forall a. p a)
-> (forall a b. p a -> p b)
-> WrappedPtr p
$cwrapPtr :: forall a. Ptr a -> Out a
wrapPtr :: forall a. Ptr a -> Out a
$cunwrapPtr :: forall a. Out a -> Ptr a
unwrapPtr :: forall a. Out a -> Ptr a
$cnullWrappedPtr :: forall a. Out a
nullWrappedPtr :: forall a. Out a
$ccastWrappedPtr :: forall a b. Out a -> Out b
castWrappedPtr :: forall a b. Out a -> Out b
WrappedPtr)

-- |Out by-ref array; length is specified by caller, memory is allocated
-- and freed by caller
newtype OutArray a = OutArray (Ptr a) deriving (OutArray a -> OutArray a -> Bool
(OutArray a -> OutArray a -> Bool)
-> (OutArray a -> OutArray a -> Bool) -> Eq (OutArray a)
forall a. OutArray a -> OutArray a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. OutArray a -> OutArray a -> Bool
== :: OutArray a -> OutArray a -> Bool
$c/= :: forall a. OutArray a -> OutArray a -> Bool
/= :: OutArray a -> OutArray a -> Bool
Eq, Eq (OutArray a)
Eq (OutArray a) =>
(OutArray a -> OutArray a -> Ordering)
-> (OutArray a -> OutArray a -> Bool)
-> (OutArray a -> OutArray a -> Bool)
-> (OutArray a -> OutArray a -> Bool)
-> (OutArray a -> OutArray a -> Bool)
-> (OutArray a -> OutArray a -> OutArray a)
-> (OutArray a -> OutArray a -> OutArray a)
-> Ord (OutArray a)
OutArray a -> OutArray a -> Bool
OutArray a -> OutArray a -> Ordering
OutArray a -> OutArray a -> OutArray a
forall a. Eq (OutArray a)
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. OutArray a -> OutArray a -> Bool
forall a. OutArray a -> OutArray a -> Ordering
forall a. OutArray a -> OutArray a -> OutArray a
$ccompare :: forall a. OutArray a -> OutArray a -> Ordering
compare :: OutArray a -> OutArray a -> Ordering
$c< :: forall a. OutArray a -> OutArray a -> Bool
< :: OutArray a -> OutArray a -> Bool
$c<= :: forall a. OutArray a -> OutArray a -> Bool
<= :: OutArray a -> OutArray a -> Bool
$c> :: forall a. OutArray a -> OutArray a -> Bool
> :: OutArray a -> OutArray a -> Bool
$c>= :: forall a. OutArray a -> OutArray a -> Bool
>= :: OutArray a -> OutArray a -> Bool
$cmax :: forall a. OutArray a -> OutArray a -> OutArray a
max :: OutArray a -> OutArray a -> OutArray a
$cmin :: forall a. OutArray a -> OutArray a -> OutArray a
min :: OutArray a -> OutArray a -> OutArray a
Ord, Int -> OutArray a -> ShowS
[OutArray a] -> ShowS
OutArray a -> String
(Int -> OutArray a -> ShowS)
-> (OutArray a -> String)
-> ([OutArray a] -> ShowS)
-> Show (OutArray a)
forall a. Int -> OutArray a -> ShowS
forall a. [OutArray a] -> ShowS
forall a. OutArray a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Int -> OutArray a -> ShowS
showsPrec :: Int -> OutArray a -> ShowS
$cshow :: forall a. OutArray a -> String
show :: OutArray a -> String
$cshowList :: forall a. [OutArray a] -> ShowS
showList :: [OutArray a] -> ShowS
Show, Ptr (OutArray a) -> IO (OutArray a)
Ptr (OutArray a) -> Int -> IO (OutArray a)
Ptr (OutArray a) -> Int -> OutArray a -> IO ()
Ptr (OutArray a) -> OutArray a -> IO ()
OutArray a -> Int
(OutArray a -> Int)
-> (OutArray a -> Int)
-> (Ptr (OutArray a) -> Int -> IO (OutArray a))
-> (Ptr (OutArray a) -> Int -> OutArray a -> IO ())
-> (forall b. Ptr b -> Int -> IO (OutArray a))
-> (forall b. Ptr b -> Int -> OutArray a -> IO ())
-> (Ptr (OutArray a) -> IO (OutArray a))
-> (Ptr (OutArray a) -> OutArray a -> IO ())
-> Storable (OutArray a)
forall b. Ptr b -> Int -> IO (OutArray a)
forall b. Ptr b -> Int -> OutArray a -> IO ()
forall a. Ptr (OutArray a) -> IO (OutArray a)
forall a. Ptr (OutArray a) -> Int -> IO (OutArray a)
forall a. Ptr (OutArray a) -> Int -> OutArray a -> IO ()
forall a. Ptr (OutArray a) -> OutArray a -> IO ()
forall a. OutArray a -> Int
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
forall a b. Ptr b -> Int -> IO (OutArray a)
forall a b. Ptr b -> Int -> OutArray a -> IO ()
$csizeOf :: forall a. OutArray a -> Int
sizeOf :: OutArray a -> Int
$calignment :: forall a. OutArray a -> Int
alignment :: OutArray a -> Int
$cpeekElemOff :: forall a. Ptr (OutArray a) -> Int -> IO (OutArray a)
peekElemOff :: Ptr (OutArray a) -> Int -> IO (OutArray a)
$cpokeElemOff :: forall a. Ptr (OutArray a) -> Int -> OutArray a -> IO ()
pokeElemOff :: Ptr (OutArray a) -> Int -> OutArray a -> IO ()
$cpeekByteOff :: forall a b. Ptr b -> Int -> IO (OutArray a)
peekByteOff :: forall b. Ptr b -> Int -> IO (OutArray a)
$cpokeByteOff :: forall a b. Ptr b -> Int -> OutArray a -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> OutArray a -> IO ()
$cpeek :: forall a. Ptr (OutArray a) -> IO (OutArray a)
peek :: Ptr (OutArray a) -> IO (OutArray a)
$cpoke :: forall a. Ptr (OutArray a) -> OutArray a -> IO ()
poke :: Ptr (OutArray a) -> OutArray a -> IO ()
Storable, (forall a. Ptr a -> OutArray a)
-> (forall a. OutArray a -> Ptr a)
-> (forall a. OutArray a)
-> (forall a b. OutArray a -> OutArray b)
-> WrappedPtr OutArray
forall a. OutArray a
forall a. Ptr a -> OutArray a
forall a. OutArray a -> Ptr a
forall a b. OutArray a -> OutArray b
forall (p :: * -> *).
(forall a. Ptr a -> p a)
-> (forall a. p a -> Ptr a)
-> (forall a. p a)
-> (forall a b. p a -> p b)
-> WrappedPtr p
$cwrapPtr :: forall a. Ptr a -> OutArray a
wrapPtr :: forall a. Ptr a -> OutArray a
$cunwrapPtr :: forall a. OutArray a -> Ptr a
unwrapPtr :: forall a. OutArray a -> Ptr a
$cnullWrappedPtr :: forall a. OutArray a
nullWrappedPtr :: forall a. OutArray a
$ccastWrappedPtr :: forall a b. OutArray a -> OutArray b
castWrappedPtr :: forall a b. OutArray a -> OutArray b
WrappedPtr)

withOut :: (Storable a, MonadBaseControl IO m, MonadIO m) => (Out a -> m b) -> m (a,b)
withOut :: forall a (m :: * -> *) b.
(Storable a, MonadBaseControl IO m, MonadIO m) =>
(Out a -> m b) -> m (a, b)
withOut Out a -> m b
f = ((Ptr a -> IO (StM m (a, b))) -> IO (StM m (a, b)))
-> (Ptr a -> m (a, b)) -> m (a, b)
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (Ptr a -> IO (StM m (a, b))) -> IO (StM m (a, b))
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr a -> m (a, b)) -> m (a, b))
-> (Ptr a -> m (a, b)) -> m (a, b)
forall a b. (a -> b) -> a -> b
$ \Ptr a
p -> do
    b
b <- Out a -> m b
f (Ptr a -> Out a
forall a. Ptr a -> Out a
Out Ptr a
p)
    a
a <- IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
p)
    (a, b) -> m (a, b)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a,b
b)

withMaybeOut :: (Storable a, MonadBaseControl IO m, MonadIO m) => (Out a -> m Bool) -> m (Maybe a)
withMaybeOut :: forall a (m :: * -> *).
(Storable a, MonadBaseControl IO m, MonadIO m) =>
(Out a -> m Bool) -> m (Maybe a)
withMaybeOut Out a -> m Bool
f = ((Ptr a -> IO (StM m (Maybe a))) -> IO (StM m (Maybe a)))
-> (Ptr a -> m (Maybe a)) -> m (Maybe a)
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (Ptr a -> IO (StM m (Maybe a))) -> IO (StM m (Maybe a))
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr a -> m (Maybe a)) -> m (Maybe a))
-> (Ptr a -> m (Maybe a)) -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ \Ptr a
p -> do
    Bool
success <- Out a -> m Bool
f (Ptr a -> Out a
forall a. Ptr a -> Out a
Out Ptr a
p)
    if Bool
success
        then do
            a
a <- IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
p)
            Maybe a -> m (Maybe a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Maybe a
forall a. a -> Maybe a
Just a
a)
        else Maybe a -> m (Maybe a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing

withOut_ :: (Storable a, MonadBaseControl IO m, MonadIO m) => (Out a -> m b) -> m a
withOut_ :: forall a (m :: * -> *) b.
(Storable a, MonadBaseControl IO m, MonadIO m) =>
(Out a -> m b) -> m a
withOut_ Out a -> m b
f = ((Ptr a -> IO (StM m a)) -> IO (StM m a)) -> (Ptr a -> m a) -> m a
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (Ptr a -> IO (StM m a)) -> IO (StM m a)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr a -> m a) -> m a) -> (Ptr a -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Ptr a
p -> do
    b
_ <- Out a -> m b
f (Ptr a -> Out a
forall a. Ptr a -> Out a
Out Ptr a
p)
    IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
p)

withOutMVector :: (Storable a, MonadBaseControl IO m) => SVM.IOVector a -> (Int -> OutArray a -> m b) -> m b
withOutMVector :: forall a (m :: * -> *) b.
(Storable a, MonadBaseControl IO m) =>
IOVector a -> (Int -> OutArray a -> m b) -> m b
withOutMVector IOVector a
vec Int -> OutArray a -> m b
f =
    ((Ptr a -> IO (StM m b)) -> IO (StM m b)) -> (Ptr a -> m b) -> m b
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (IOVector a -> (Ptr a -> IO (StM m b)) -> IO (StM m b)
forall a b. Storable a => IOVector a -> (Ptr a -> IO b) -> IO b
SVM.unsafeWith IOVector a
vec) (Int -> OutArray a -> m b
f (IOVector a -> Int
forall a s. Storable a => MVector s a -> Int
SVM.length IOVector a
vec) (OutArray a -> m b) -> (Ptr a -> OutArray a) -> Ptr a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> OutArray a
forall a. Ptr a -> OutArray a
OutArray)

withOutVector :: (Storable a, MonadBaseControl IO m, MonadIO m) => Int -> (OutArray a -> m b) -> m (SV.Vector a, b)
withOutVector :: forall a (m :: * -> *) b.
(Storable a, MonadBaseControl IO m, MonadIO m) =>
Int -> (OutArray a -> m b) -> m (Vector a, b)
withOutVector Int
n OutArray a -> m b
f = do
    ForeignPtr a
p <- IO (ForeignPtr a) -> m (ForeignPtr a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> IO (ForeignPtr a)
forall a. Storable a => Int -> IO (ForeignPtr a)
mallocForeignPtrArray Int
n)
    b
b <- ((Ptr a -> IO (StM m b)) -> IO (StM m b)) -> (Ptr a -> m b) -> m b
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (ForeignPtr a -> (Ptr a -> IO (StM m b)) -> IO (StM m b)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
p) (OutArray a -> m b
f (OutArray a -> m b) -> (Ptr a -> OutArray a) -> Ptr a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> OutArray a
forall a. Ptr a -> OutArray a
OutArray)
    (Vector a, b) -> m (Vector a, b)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr a -> Int -> Int -> Vector a
forall a. Storable a => ForeignPtr a -> Int -> Int -> Vector a
SV.unsafeFromForeignPtr ForeignPtr a
p Int
0 Int
n, b
b)


-- NOTE: withOutVector_ and withOutVector' don't typecheck unless you specify the monad type as IO

withOutVector_ :: (Storable a) => Int -> (OutArray a -> IO b) -> IO (SV.Vector a)
withOutVector_ :: forall a b.
Storable a =>
Int -> (OutArray a -> IO b) -> IO (Vector a)
withOutVector_ Int
n OutArray a -> IO b
f = do
    ForeignPtr a
p <- IO (ForeignPtr a) -> IO (ForeignPtr a)
forall a. IO a -> IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> IO (ForeignPtr a)
forall a. Storable a => Int -> IO (ForeignPtr a)
mallocForeignPtrArray Int
n)
    b
_ <- ((Ptr a -> IO (StM IO b)) -> IO (StM IO b))
-> (Ptr a -> IO b) -> IO b
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (ForeignPtr a -> (Ptr a -> IO b) -> IO b
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
p) (OutArray a -> IO b
f (OutArray a -> IO b) -> (Ptr a -> OutArray a) -> Ptr a -> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> OutArray a
forall a. Ptr a -> OutArray a
OutArray)
    Vector a -> IO (Vector a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr a -> Int -> Int -> Vector a
forall a. Storable a => ForeignPtr a -> Int -> Int -> Vector a
SV.unsafeFromForeignPtr ForeignPtr a
p Int
0 Int
n)

withOutVector' :: (Storable a, Integral b) => Int -> (OutArray a -> IO b) -> IO (SV.Vector a)
withOutVector' :: forall a b.
(Storable a, Integral b) =>
Int -> (OutArray a -> IO b) -> IO (Vector a)
withOutVector' Int
sz OutArray a -> IO b
f = do
    ForeignPtr a
p <- IO (ForeignPtr a) -> IO (ForeignPtr a)
forall a. IO a -> IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> IO (ForeignPtr a)
forall a. Storable a => Int -> IO (ForeignPtr a)
mallocForeignPtrArray Int
sz)
    b
n <- ((Ptr a -> IO (StM IO b)) -> IO (StM IO b))
-> (Ptr a -> IO b) -> IO b
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (ForeignPtr a -> (Ptr a -> IO b) -> IO b
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
p) (OutArray a -> IO b
f (OutArray a -> IO b) -> (Ptr a -> OutArray a) -> Ptr a -> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr a -> OutArray a
forall a. Ptr a -> OutArray a
OutArray)
    Vector a -> IO (Vector a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr a -> Int -> Int -> Vector a
forall a. Storable a => ForeignPtr a -> Int -> Int -> Vector a
SV.unsafeFromForeignPtr ForeignPtr a
p Int
0 (b -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
n))

withOutList :: (Storable a, MonadIO m) => Int -> (OutArray a -> m b) -> m ([a],b)
withOutList :: forall a (m :: * -> *) b.
(Storable a, MonadIO m) =>
Int -> (OutArray a -> m b) -> m ([a], b)
withOutList Int
n OutArray a -> m b
f = do
    Ptr a
p <- IO (Ptr a) -> m (Ptr a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> IO (Ptr a)
forall a. Storable a => Int -> IO (Ptr a)
mallocArray Int
n)
    b
b <- OutArray a -> m b
f (Ptr a -> OutArray a
forall a. Ptr a -> OutArray a
OutArray Ptr a
p)
    [a]
a <- IO [a] -> m [a]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> Ptr a -> IO [a]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
n Ptr a
p)
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Ptr a -> IO ()
forall a. Ptr a -> IO ()
free Ptr a
p)
    ([a], b) -> m ([a], b)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a]
a, b
b)

withOutList_ :: (Storable a, MonadIO m) => Int -> (OutArray a -> m b) -> m [a]
withOutList_ :: forall a (m :: * -> *) b.
(Storable a, MonadIO m) =>
Int -> (OutArray a -> m b) -> m [a]
withOutList_ Int
n OutArray a -> m b
f = do
    Ptr a
p <- IO (Ptr a) -> m (Ptr a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> IO (Ptr a)
forall a. Storable a => Int -> IO (Ptr a)
mallocArray Int
n)
    b
_ <- OutArray a -> m b
f (Ptr a -> OutArray a
forall a. Ptr a -> OutArray a
OutArray Ptr a
p)
    [a]
a <- IO [a] -> m [a]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> Ptr a -> IO [a]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
n Ptr a
p)
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Ptr a -> IO ()
forall a. Ptr a -> IO ()
free Ptr a
p)
    [a] -> m [a]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return [a]
a

withOutList' :: (Storable a, MonadIO m) => Int -> (OutArray a -> m Int) -> m ([a], Int)
withOutList' :: forall a (m :: * -> *).
(Storable a, MonadIO m) =>
Int -> (OutArray a -> m Int) -> m ([a], Int)
withOutList' Int
sz OutArray a -> m Int
f = do
    Ptr a
p <- IO (Ptr a) -> m (Ptr a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> IO (Ptr a)
forall a. Storable a => Int -> IO (Ptr a)
mallocArray Int
sz)
    Int
n <- OutArray a -> m Int
f (Ptr a -> OutArray a
forall a. Ptr a -> OutArray a
OutArray Ptr a
p)
    [a]
a <- IO [a] -> m [a]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> Ptr a -> IO [a]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
n Ptr a
p)
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Ptr a -> IO ()
forall a. Ptr a -> IO ()
free Ptr a
p)
    ([a], Int) -> m ([a], Int)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a]
a, Int
n)

-- | @withOutList0 zero n f@: allocate an array large enough to hold @n@ elements,
-- plus one extra spot for a terminator.  Calls @f@ with that buffer, which is
-- expected to fill it with up to @n@ elements, followed by @zero@.  The
-- elements are then read out into a list.
withOutList0 :: (Storable a, Eq a, MonadIO m) => a -> Int -> (OutArray a -> m b) -> m ([a], b)
withOutList0 :: forall a (m :: * -> *) b.
(Storable a, Eq a, MonadIO m) =>
a -> Int -> (OutArray a -> m b) -> m ([a], b)
withOutList0 a
zero Int
n OutArray a -> m b
f = do
    Ptr a
p <- IO (Ptr a) -> m (Ptr a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> IO (Ptr a)
forall a. Storable a => Int -> IO (Ptr a)
mallocArray0 Int
n)
    b
b <- OutArray a -> m b
f (Ptr a -> OutArray a
forall a. Ptr a -> OutArray a
OutArray Ptr a
p)
    [a]
a <- IO [a] -> m [a]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (a -> Ptr a -> IO [a]
forall a. (Storable a, Eq a) => a -> Ptr a -> IO [a]
peekArray0 a
zero Ptr a
p)
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Ptr a -> IO ()
forall a. Ptr a -> IO ()
free Ptr a
p)
    ([a], b) -> m ([a], b)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a]
a, b
b)

-- |Get a 'BS.ByteString' from a function using the common \"buffer and size in,
-- bytes written out\" convention.
--
-- Calls the function twice; once with a null pointer to discover the length
-- needed and once more to actually read out the string.
withOutByteString :: (MonadBaseControl IO m, MonadIO m, Integral a, Integral b) => (OutArray CChar -> a -> m b) -> m BS.ByteString
withOutByteString :: forall (m :: * -> *) a b.
(MonadBaseControl IO m, MonadIO m, Integral a, Integral b) =>
(OutArray CChar -> a -> m b) -> m ByteString
withOutByteString OutArray CChar -> a -> m b
f = do
    b
bufSz <- OutArray CChar -> a -> m b
f OutArray CChar
forall a. OutArray a
forall (p :: * -> *) a. WrappedPtr p => p a
nullWrappedPtr a
0

    m (Ptr CChar)
-> (Ptr CChar -> m ())
-> (Ptr CChar -> m ByteString)
-> m ByteString
forall (m :: * -> *) a b c.
MonadBaseControl IO m =>
m a -> (a -> m b) -> (a -> m c) -> m c
bracket (IO (Ptr CChar) -> m (Ptr CChar)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> IO (Ptr CChar)
forall a. Int -> IO (Ptr a)
mallocBytes (b -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
bufSz))) (IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (Ptr CChar -> IO ()) -> Ptr CChar -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr CChar -> IO ()
forall a. Ptr a -> IO ()
free) ((Ptr CChar -> m ByteString) -> m ByteString)
-> (Ptr CChar -> m ByteString) -> m ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
buf -> do
        b
sz <- OutArray CChar -> a -> m b
f (Ptr CChar -> OutArray CChar
forall a. Ptr a -> OutArray a
OutArray Ptr CChar
buf) (b -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
bufSz)

        IO ByteString -> m ByteString
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
buf, b -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
sz))

-- | Variant of withOutByteString which expects the discovered length to be one byte less than
--   the required buffer size.  As required for H5Fget_name
withOutByteString' :: (MonadBaseControl IO m, MonadIO m, Integral a, Integral b) => (OutArray CChar -> a -> m b) -> m BS.ByteString
withOutByteString' :: forall (m :: * -> *) a b.
(MonadBaseControl IO m, MonadIO m, Integral a, Integral b) =>
(OutArray CChar -> a -> m b) -> m ByteString
withOutByteString' OutArray CChar -> a -> m b
f = do
    b
bufSz <- OutArray CChar -> a -> m b
f OutArray CChar
forall a. OutArray a
forall (p :: * -> *) a. WrappedPtr p => p a
nullWrappedPtr a
0
    -- bufSz should be 1 minus the length of the buffer which needs allocating
    let bufSz' :: b
bufSz' = b
bufSz b -> b -> b
forall a. Num a => a -> a -> a
+ b
1

    m (Ptr CChar)
-> (Ptr CChar -> m ())
-> (Ptr CChar -> m ByteString)
-> m ByteString
forall (m :: * -> *) a b c.
MonadBaseControl IO m =>
m a -> (a -> m b) -> (a -> m c) -> m c
bracket (IO (Ptr CChar) -> m (Ptr CChar)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> IO (Ptr CChar)
forall a. Int -> IO (Ptr a)
mallocBytes (b -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
bufSz'))) (IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (Ptr CChar -> IO ()) -> Ptr CChar -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr CChar -> IO ()
forall a. Ptr a -> IO ()
free) ((Ptr CChar -> m ByteString) -> m ByteString)
-> (Ptr CChar -> m ByteString) -> m ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
buf -> do
        b
sz <- OutArray CChar -> a -> m b
f (Ptr CChar -> OutArray CChar
forall a. Ptr a -> OutArray a
OutArray Ptr CChar
buf) (b -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
bufSz')

        IO ByteString -> m ByteString
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
buf, b -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
sz))


-- * Bidirectional pointers

-- |In-out parameter.  Memory is allocated and freed by caller.
newtype InOut    a = InOut    (Ptr a) deriving (InOut a -> InOut a -> Bool
(InOut a -> InOut a -> Bool)
-> (InOut a -> InOut a -> Bool) -> Eq (InOut a)
forall a. InOut a -> InOut a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. InOut a -> InOut a -> Bool
== :: InOut a -> InOut a -> Bool
$c/= :: forall a. InOut a -> InOut a -> Bool
/= :: InOut a -> InOut a -> Bool
Eq, Eq (InOut a)
Eq (InOut a) =>
(InOut a -> InOut a -> Ordering)
-> (InOut a -> InOut a -> Bool)
-> (InOut a -> InOut a -> Bool)
-> (InOut a -> InOut a -> Bool)
-> (InOut a -> InOut a -> Bool)
-> (InOut a -> InOut a -> InOut a)
-> (InOut a -> InOut a -> InOut a)
-> Ord (InOut a)
InOut a -> InOut a -> Bool
InOut a -> InOut a -> Ordering
InOut a -> InOut a -> InOut a
forall a. Eq (InOut a)
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. InOut a -> InOut a -> Bool
forall a. InOut a -> InOut a -> Ordering
forall a. InOut a -> InOut a -> InOut a
$ccompare :: forall a. InOut a -> InOut a -> Ordering
compare :: InOut a -> InOut a -> Ordering
$c< :: forall a. InOut a -> InOut a -> Bool
< :: InOut a -> InOut a -> Bool
$c<= :: forall a. InOut a -> InOut a -> Bool
<= :: InOut a -> InOut a -> Bool
$c> :: forall a. InOut a -> InOut a -> Bool
> :: InOut a -> InOut a -> Bool
$c>= :: forall a. InOut a -> InOut a -> Bool
>= :: InOut a -> InOut a -> Bool
$cmax :: forall a. InOut a -> InOut a -> InOut a
max :: InOut a -> InOut a -> InOut a
$cmin :: forall a. InOut a -> InOut a -> InOut a
min :: InOut a -> InOut a -> InOut a
Ord, Int -> InOut a -> ShowS
[InOut a] -> ShowS
InOut a -> String
(Int -> InOut a -> ShowS)
-> (InOut a -> String) -> ([InOut a] -> ShowS) -> Show (InOut a)
forall a. Int -> InOut a -> ShowS
forall a. [InOut a] -> ShowS
forall a. InOut a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Int -> InOut a -> ShowS
showsPrec :: Int -> InOut a -> ShowS
$cshow :: forall a. InOut a -> String
show :: InOut a -> String
$cshowList :: forall a. [InOut a] -> ShowS
showList :: [InOut a] -> ShowS
Show, Ptr (InOut a) -> IO (InOut a)
Ptr (InOut a) -> Int -> IO (InOut a)
Ptr (InOut a) -> Int -> InOut a -> IO ()
Ptr (InOut a) -> InOut a -> IO ()
InOut a -> Int
(InOut a -> Int)
-> (InOut a -> Int)
-> (Ptr (InOut a) -> Int -> IO (InOut a))
-> (Ptr (InOut a) -> Int -> InOut a -> IO ())
-> (forall b. Ptr b -> Int -> IO (InOut a))
-> (forall b. Ptr b -> Int -> InOut a -> IO ())
-> (Ptr (InOut a) -> IO (InOut a))
-> (Ptr (InOut a) -> InOut a -> IO ())
-> Storable (InOut a)
forall b. Ptr b -> Int -> IO (InOut a)
forall b. Ptr b -> Int -> InOut a -> IO ()
forall a. Ptr (InOut a) -> IO (InOut a)
forall a. Ptr (InOut a) -> Int -> IO (InOut a)
forall a. Ptr (InOut a) -> Int -> InOut a -> IO ()
forall a. Ptr (InOut a) -> InOut a -> IO ()
forall a. InOut a -> Int
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
forall a b. Ptr b -> Int -> IO (InOut a)
forall a b. Ptr b -> Int -> InOut a -> IO ()
$csizeOf :: forall a. InOut a -> Int
sizeOf :: InOut a -> Int
$calignment :: forall a. InOut a -> Int
alignment :: InOut a -> Int
$cpeekElemOff :: forall a. Ptr (InOut a) -> Int -> IO (InOut a)
peekElemOff :: Ptr (InOut a) -> Int -> IO (InOut a)
$cpokeElemOff :: forall a. Ptr (InOut a) -> Int -> InOut a -> IO ()
pokeElemOff :: Ptr (InOut a) -> Int -> InOut a -> IO ()
$cpeekByteOff :: forall a b. Ptr b -> Int -> IO (InOut a)
peekByteOff :: forall b. Ptr b -> Int -> IO (InOut a)
$cpokeByteOff :: forall a b. Ptr b -> Int -> InOut a -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> InOut a -> IO ()
$cpeek :: forall a. Ptr (InOut a) -> IO (InOut a)
peek :: Ptr (InOut a) -> IO (InOut a)
$cpoke :: forall a. Ptr (InOut a) -> InOut a -> IO ()
poke :: Ptr (InOut a) -> InOut a -> IO ()
Storable, (forall a. Ptr a -> InOut a)
-> (forall a. InOut a -> Ptr a)
-> (forall a. InOut a)
-> (forall a b. InOut a -> InOut b)
-> WrappedPtr InOut
forall a. InOut a
forall a. Ptr a -> InOut a
forall a. InOut a -> Ptr a
forall a b. InOut a -> InOut b
forall (p :: * -> *).
(forall a. Ptr a -> p a)
-> (forall a. p a -> Ptr a)
-> (forall a. p a)
-> (forall a b. p a -> p b)
-> WrappedPtr p
$cwrapPtr :: forall a. Ptr a -> InOut a
wrapPtr :: forall a. Ptr a -> InOut a
$cunwrapPtr :: forall a. InOut a -> Ptr a
unwrapPtr :: forall a. InOut a -> Ptr a
$cnullWrappedPtr :: forall a. InOut a
nullWrappedPtr :: forall a. InOut a
$ccastWrappedPtr :: forall a b. InOut a -> InOut b
castWrappedPtr :: forall a b. InOut a -> InOut b
WrappedPtr)

newtype InOutArray a = InOutArray (Ptr a) deriving (InOutArray a -> InOutArray a -> Bool
(InOutArray a -> InOutArray a -> Bool)
-> (InOutArray a -> InOutArray a -> Bool) -> Eq (InOutArray a)
forall a. InOutArray a -> InOutArray a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. InOutArray a -> InOutArray a -> Bool
== :: InOutArray a -> InOutArray a -> Bool
$c/= :: forall a. InOutArray a -> InOutArray a -> Bool
/= :: InOutArray a -> InOutArray a -> Bool
Eq, Eq (InOutArray a)
Eq (InOutArray a) =>
(InOutArray a -> InOutArray a -> Ordering)
-> (InOutArray a -> InOutArray a -> Bool)
-> (InOutArray a -> InOutArray a -> Bool)
-> (InOutArray a -> InOutArray a -> Bool)
-> (InOutArray a -> InOutArray a -> Bool)
-> (InOutArray a -> InOutArray a -> InOutArray a)
-> (InOutArray a -> InOutArray a -> InOutArray a)
-> Ord (InOutArray a)
InOutArray a -> InOutArray a -> Bool
InOutArray a -> InOutArray a -> Ordering
InOutArray a -> InOutArray a -> InOutArray a
forall a. Eq (InOutArray a)
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. InOutArray a -> InOutArray a -> Bool
forall a. InOutArray a -> InOutArray a -> Ordering
forall a. InOutArray a -> InOutArray a -> InOutArray a
$ccompare :: forall a. InOutArray a -> InOutArray a -> Ordering
compare :: InOutArray a -> InOutArray a -> Ordering
$c< :: forall a. InOutArray a -> InOutArray a -> Bool
< :: InOutArray a -> InOutArray a -> Bool
$c<= :: forall a. InOutArray a -> InOutArray a -> Bool
<= :: InOutArray a -> InOutArray a -> Bool
$c> :: forall a. InOutArray a -> InOutArray a -> Bool
> :: InOutArray a -> InOutArray a -> Bool
$c>= :: forall a. InOutArray a -> InOutArray a -> Bool
>= :: InOutArray a -> InOutArray a -> Bool
$cmax :: forall a. InOutArray a -> InOutArray a -> InOutArray a
max :: InOutArray a -> InOutArray a -> InOutArray a
$cmin :: forall a. InOutArray a -> InOutArray a -> InOutArray a
min :: InOutArray a -> InOutArray a -> InOutArray a
Ord, Int -> InOutArray a -> ShowS
[InOutArray a] -> ShowS
InOutArray a -> String
(Int -> InOutArray a -> ShowS)
-> (InOutArray a -> String)
-> ([InOutArray a] -> ShowS)
-> Show (InOutArray a)
forall a. Int -> InOutArray a -> ShowS
forall a. [InOutArray a] -> ShowS
forall a. InOutArray a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Int -> InOutArray a -> ShowS
showsPrec :: Int -> InOutArray a -> ShowS
$cshow :: forall a. InOutArray a -> String
show :: InOutArray a -> String
$cshowList :: forall a. [InOutArray a] -> ShowS
showList :: [InOutArray a] -> ShowS
Show, Ptr (InOutArray a) -> IO (InOutArray a)
Ptr (InOutArray a) -> Int -> IO (InOutArray a)
Ptr (InOutArray a) -> Int -> InOutArray a -> IO ()
Ptr (InOutArray a) -> InOutArray a -> IO ()
InOutArray a -> Int
(InOutArray a -> Int)
-> (InOutArray a -> Int)
-> (Ptr (InOutArray a) -> Int -> IO (InOutArray a))
-> (Ptr (InOutArray a) -> Int -> InOutArray a -> IO ())
-> (forall b. Ptr b -> Int -> IO (InOutArray a))
-> (forall b. Ptr b -> Int -> InOutArray a -> IO ())
-> (Ptr (InOutArray a) -> IO (InOutArray a))
-> (Ptr (InOutArray a) -> InOutArray a -> IO ())
-> Storable (InOutArray a)
forall b. Ptr b -> Int -> IO (InOutArray a)
forall b. Ptr b -> Int -> InOutArray a -> IO ()
forall a. Ptr (InOutArray a) -> IO (InOutArray a)
forall a. Ptr (InOutArray a) -> Int -> IO (InOutArray a)
forall a. Ptr (InOutArray a) -> Int -> InOutArray a -> IO ()
forall a. Ptr (InOutArray a) -> InOutArray a -> IO ()
forall a. InOutArray a -> Int
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
forall a b. Ptr b -> Int -> IO (InOutArray a)
forall a b. Ptr b -> Int -> InOutArray a -> IO ()
$csizeOf :: forall a. InOutArray a -> Int
sizeOf :: InOutArray a -> Int
$calignment :: forall a. InOutArray a -> Int
alignment :: InOutArray a -> Int
$cpeekElemOff :: forall a. Ptr (InOutArray a) -> Int -> IO (InOutArray a)
peekElemOff :: Ptr (InOutArray a) -> Int -> IO (InOutArray a)
$cpokeElemOff :: forall a. Ptr (InOutArray a) -> Int -> InOutArray a -> IO ()
pokeElemOff :: Ptr (InOutArray a) -> Int -> InOutArray a -> IO ()
$cpeekByteOff :: forall a b. Ptr b -> Int -> IO (InOutArray a)
peekByteOff :: forall b. Ptr b -> Int -> IO (InOutArray a)
$cpokeByteOff :: forall a b. Ptr b -> Int -> InOutArray a -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> InOutArray a -> IO ()
$cpeek :: forall a. Ptr (InOutArray a) -> IO (InOutArray a)
peek :: Ptr (InOutArray a) -> IO (InOutArray a)
$cpoke :: forall a. Ptr (InOutArray a) -> InOutArray a -> IO ()
poke :: Ptr (InOutArray a) -> InOutArray a -> IO ()
Storable, (forall a. Ptr a -> InOutArray a)
-> (forall a. InOutArray a -> Ptr a)
-> (forall a. InOutArray a)
-> (forall a b. InOutArray a -> InOutArray b)
-> WrappedPtr InOutArray
forall a. InOutArray a
forall a. Ptr a -> InOutArray a
forall a. InOutArray a -> Ptr a
forall a b. InOutArray a -> InOutArray b
forall (p :: * -> *).
(forall a. Ptr a -> p a)
-> (forall a. p a -> Ptr a)
-> (forall a. p a)
-> (forall a b. p a -> p b)
-> WrappedPtr p
$cwrapPtr :: forall a. Ptr a -> InOutArray a
wrapPtr :: forall a. Ptr a -> InOutArray a
$cunwrapPtr :: forall a. InOutArray a -> Ptr a
unwrapPtr :: forall a. InOutArray a -> Ptr a
$cnullWrappedPtr :: forall a. InOutArray a
nullWrappedPtr :: forall a. InOutArray a
$ccastWrappedPtr :: forall a b. InOutArray a -> InOutArray b
castWrappedPtr :: forall a b. InOutArray a -> InOutArray b
WrappedPtr)

withInOut :: (Storable a, MonadBaseControl IO m, MonadIO m) => a -> (InOut a -> m b) -> m (a,b)
withInOut :: forall a (m :: * -> *) b.
(Storable a, MonadBaseControl IO m, MonadIO m) =>
a -> (InOut a -> m b) -> m (a, b)
withInOut a
a InOut a -> m b
f = ((Ptr a -> IO (StM m (a, b))) -> IO (StM m (a, b)))
-> (Ptr a -> m (a, b)) -> m (a, b)
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (Ptr a -> IO (StM m (a, b))) -> IO (StM m (a, b))
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr a -> m (a, b)) -> m (a, b))
-> (Ptr a -> m (a, b)) -> m (a, b)
forall a b. (a -> b) -> a -> b
$ \Ptr a
p -> do
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
p a
a)
    b
b <- InOut a -> m b
f (Ptr a -> InOut a
forall a. Ptr a -> InOut a
InOut Ptr a
p)
    a
a_ <- IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
p)
    (a, b) -> m (a, b)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a_,b
b)

withInOut_ :: (Storable a, MonadBaseControl IO m, MonadIO m) => a -> (InOut a -> m b) -> m a
withInOut_ :: forall a (m :: * -> *) b.
(Storable a, MonadBaseControl IO m, MonadIO m) =>
a -> (InOut a -> m b) -> m a
withInOut_ a
a InOut a -> m b
f = ((Ptr a -> IO (StM m a)) -> IO (StM m a)) -> (Ptr a -> m a) -> m a
forall (b :: * -> *) (m :: * -> *) a c d.
MonadBaseControl b m =>
((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d
liftBaseOp (Ptr a -> IO (StM m a)) -> IO (StM m a)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr a -> m a) -> m a) -> (Ptr a -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Ptr a
p -> do
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
p a
a)
    b
_ <- InOut a -> m b
f (Ptr a -> InOut a
forall a. Ptr a -> InOut a
InOut Ptr a
p)
    IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
p)

withInOutList :: (Storable a, MonadIO m) => Int -> [a] -> (InOutArray a -> m (Int, b)) -> m ([a], b)
withInOutList :: forall a (m :: * -> *) b.
(Storable a, MonadIO m) =>
Int -> [a] -> (InOutArray a -> m (Int, b)) -> m ([a], b)
withInOutList Int
sz [a]
xs InOutArray a -> m (Int, b)
f = do
    Ptr a
p <- IO (Ptr a) -> m (Ptr a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> IO (Ptr a)
forall a. Storable a => Int -> IO (Ptr a)
mallocArray Int
sz)
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ [IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_
        [ Ptr a -> Int -> a -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr a
p Int
i a
x
        | (Int
i,a
x) <- [Int] -> [a] -> [(Int, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] (Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
sz [a]
xs)
        ]

    (Int
n, b
y) <- InOutArray a -> m (Int, b)
f (Ptr a -> InOutArray a
forall a. Ptr a -> InOutArray a
InOutArray Ptr a
p)

    [a]
xs' <- IO [a] -> m [a]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [a] -> m [a]) -> IO [a] -> m [a]
forall a b. (a -> b) -> a -> b
$ [IO a] -> IO [a]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence
        [ Ptr a -> Int -> IO a
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr a
p Int
i
        | Int
i <- [Int
0..Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]
        ]

    ([a], b) -> m ([a], b)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a]
xs', b
y)

withInOutList_ :: (Storable a, MonadIO m) => Int -> [a] -> (InOutArray a -> m Int) -> m [a]
withInOutList_ :: forall a (m :: * -> *).
(Storable a, MonadIO m) =>
Int -> [a] -> (InOutArray a -> m Int) -> m [a]
withInOutList_ Int
sz [a]
xs InOutArray a -> m Int
f = do
    Ptr a
p <- IO (Ptr a) -> m (Ptr a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Int -> IO (Ptr a)
forall a. Storable a => Int -> IO (Ptr a)
mallocArray Int
sz)
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ [IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_
        [ Ptr a -> Int -> a -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr a
p Int
i a
x
        | (Int
i,a
x) <- [Int] -> [a] -> [(Int, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] (Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
sz [a]
xs)
        ]

    Int
n <- InOutArray a -> m Int
f (Ptr a -> InOutArray a
forall a. Ptr a -> InOutArray a
InOutArray Ptr a
p)

    IO [a] -> m [a]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [a] -> m [a]) -> IO [a] -> m [a]
forall a b. (a -> b) -> a -> b
$ [IO a] -> IO [a]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence
        [ Ptr a -> Int -> IO a
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr a
p Int
i
        | Int
i <- [Int
0..Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]
        ]