    {-# 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 <- Out a -> m b
    f (Ptr a -> Out a
    forall a. Ptr a -> Out a
    Out Ptr a
    p)
        a <- liftIO (peek p)
        return (a,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
        success <- Out a -> m Bool
    f (Ptr a -> Out a
    forall a. Ptr a -> Out a
    Out Ptr a
    p)
        if success
            then do
                a <- liftIO (peek p)
                return (Just a)
            else return 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
        _ <- Out a -> m b
    f (Ptr a -> Out a
    forall a. Ptr a -> Out a
    Out Ptr a
    p)
        liftIO (peek 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
        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 <- liftBaseOp (withForeignPtr p) (f . OutArray)
        return (SV.unsafeFromForeignPtr p 0 n, 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
        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)
        _ <- liftBaseOp (withForeignPtr p) (f . OutArray)
        return (SV.unsafeFromForeignPtr p 0 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
        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)
        n <- liftBaseOp (withForeignPtr p) (f . OutArray)
        return (SV.unsafeFromForeignPtr p 0 (fromIntegral 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
        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 <- f (OutArray p)
        a <- liftIO (peekArray n p)
        liftIO (free p)
        return (a, 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
        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)
        _ <- f (OutArray p)
        a <- liftIO (peekArray n p)
        liftIO (free p)
        return 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
        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)
        n <- f (OutArray p)
        a <- liftIO (peekArray n p)
        liftIO (free p)
        return (a, 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
        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 <- f (OutArray p)
        a <- liftIO (peekArray0 zero p)
        liftIO (free p)
        return (a, 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
        bufSz <- OutArray CChar -> a -> m b
    f OutArray CChar
    forall a. OutArray a
    forall (p :: * -> *) a. WrappedPtr p => p a
    nullWrappedPtr a
    0

        bracket (liftIO (mallocBytes (fromIntegral bufSz))) (liftIO . free) $ \Ptr CChar
    buf -> do
            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)

            liftIO (BS.packCStringLen (buf, fromIntegral 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
        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 -> b -> b
    forall a. Num a => a -> a -> a
    + b
    1

        bracket (liftIO (mallocBytes (fromIntegral bufSz'))) (liftIO . free) $ \Ptr CChar
    buf -> do
            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')

            liftIO (BS.packCStringLen (buf, fromIntegral 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 <- InOut a -> m b
    f (Ptr a -> InOut a
    forall a. Ptr a -> InOut a
    InOut Ptr a
    p)
        a_ <- liftIO (peek p)
        return (a_,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)
        _ <- InOut a -> m b
    f (Ptr a -> InOut a
    forall a. Ptr a -> InOut a
    InOut Ptr a
    p)
        liftIO (peek 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
        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)
        liftIO $ sequence_
            [ pokeElemOff p i x
            | (i,x) <- zip [0..] (take sz xs)
            ]

        (n, y) <- f (InOutArray p)

        xs' <- liftIO $ sequence
            [ peekElemOff p i
            | i <- [0..n-1]
            ]

        return (xs', 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
        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)
        liftIO $ sequence_
            [ pokeElemOff p i x
            | (i,x) <- zip [0..] (take sz xs)
            ]

        n <- f (InOutArray p)

        liftIO $ sequence
            [ peekElemOff p i
            | i <- [0..n-1]
            ]