module HaskellWorks.Foreign
  ( mallocForeignPtrBytesWithAlignedPtr
  , mallocForeignPtrBytesWithAlignedCastPtr
  ) where

import Foreign.ForeignPtr (ForeignPtr)
import Foreign.Ptr        (Ptr, alignPtr)
import Foreign.Storable   (Storable)

import qualified Foreign.ForeignPtr        as F
import qualified Foreign.ForeignPtr.Unsafe as F
import qualified Foreign.Ptr               as F

mallocForeignPtrBytesWithAlignedPtr :: Storable a => Int -> Int -> IO (ForeignPtr a, Ptr a)
mallocForeignPtrBytesWithAlignedPtr :: forall a. Storable a => Int -> Int -> IO (ForeignPtr a, Ptr a)
mallocForeignPtrBytesWithAlignedPtr Int
alignment Int
n = do
  ForeignPtr a
fptr <- forall a. Int -> IO (ForeignPtr a)
F.mallocForeignPtrBytes (Int
n forall a. Num a => a -> a -> a
+ Int
alignment)
  let alignedPtr :: Ptr a
alignedPtr = forall a. Ptr a -> Int -> Ptr a
alignPtr (forall a. ForeignPtr a -> Ptr a
F.unsafeForeignPtrToPtr ForeignPtr a
fptr) Int
alignment
  forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr a
fptr, Ptr a
alignedPtr)

mallocForeignPtrBytesWithAlignedCastPtr :: Storable a => Int -> Int -> IO (ForeignPtr a, Ptr b)
mallocForeignPtrBytesWithAlignedCastPtr :: forall a b. Storable a => Int -> Int -> IO (ForeignPtr a, Ptr b)
mallocForeignPtrBytesWithAlignedCastPtr Int
alignment Int
n = do
  ForeignPtr a
fptr <- forall a. Int -> IO (ForeignPtr a)
F.mallocForeignPtrBytes (Int
n forall a. Num a => a -> a -> a
+ Int
alignment)
  let alignedPtr :: Ptr a
alignedPtr = forall a. Ptr a -> Int -> Ptr a
alignPtr (forall a. ForeignPtr a -> Ptr a
F.unsafeForeignPtrToPtr ForeignPtr a
fptr) Int
alignment
  forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr a
fptr, forall a b. Ptr a -> Ptr b
F.castPtr Ptr a
alignedPtr)