    module Bindings.Utilities (
    	storableCast,
    	storableCastArray,
      ) where

    import Foreign.C
    import Foreign.Marshal
    import Foreign.Ptr
    import Foreign.Storable

    -- |'storableCast' works like 'storableCastArray', except that it
    -- takes a single value and returns a single value.

    storableCast :: (Storable a, Storable b) => a -> IO b
    storableCast :: forall a b. (Storable a, Storable b) => a -> IO b
    storableCast a
    a = [a] -> IO [b]
    forall a b. (Storable a, Storable b) => [a] -> IO [b]
    storableCastArray [a
    a] IO [b] -> ([b] -> IO b) -> IO b
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (b -> IO b
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (b -> IO b) -> ([b] -> b) -> [b] -> IO b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [b] -> b
    forall a. HasCallStack => [a] -> a
    head)

    -- |'storableCastArray' takes a list of values of a first type, stores it
    -- at a contiguous memory area (that is first blanked with 0s), and then
    -- reads it as if it was a list of a second type, with enough elements to
    -- fill at least the same space.
    --
    -- @
    -- ghci
    -- :m + Bindings.Sandbox Data.Int
    -- storableCastArray (replicate 13 (1::Int8)) :: IO [Int32]
    --         ==> [16843009,16843009,16843009,1]
    -- @

    storableCastArray :: (Storable a, Storable b) => [a] -> IO [b]
    storableCastArray :: forall a b. (Storable a, Storable b) => [a] -> IO [b]
    storableCastArray [] = [b] -> IO [b]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
    storableCastArray [a]
    a = do
    	u <- b -> IO b
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return b
    forall a. HasCallStack => a
    undefined
    	let (q,r) = divMod (length a * (sizeOf . head) a) (sizeOf u)
    	let len = Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max Int
    1 (if Int
    r Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    0 then Int
    q Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1 else Int
    q)
    	let blank = Int -> CChar -> [CChar]
    forall a. Int -> a -> [a]
    replicate (Int
    len Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * b -> Int
    forall a. Storable a => a -> Int
    sizeOf b
    u) (CChar
    0::CChar)
    	b <- withArray blank $ \Ptr CChar
    ptr -> do
    		Ptr a -> [a] -> IO ()
    forall a. Storable a => Ptr a -> [a] -> IO ()
    pokeArray (Ptr CChar -> Ptr a
    forall a b. Ptr a -> Ptr b
    castPtr Ptr CChar
    ptr) [a]
    a
    		Int -> Ptr b -> IO [b]
    forall a. Storable a => Int -> Ptr a -> IO [a]
    peekArray Int
    len (Ptr CChar -> Ptr b
    forall a b. Ptr a -> Ptr b
    castPtr Ptr CChar
    ptr)
    	return $ if True then b else [u]