module Data.Unboxed (
UVec,
MUVec,
allocUnboxed,
unsafeFreezeUnboxed,
unsafeThawUnboxed,
freezeUnboxed,
thawUnboxed,
castUnboxed,
castMUnboxed,
Unboxed,
readUnboxed,
writeUnboxed,
indexUnboxed,
sizeOfUnboxed,
)
where
#ifdef __GLASGOW_HASKELL__
import GHC.Unboxed
#else
import Control.Monad.STorIO
import Data.Int
import Data.Word
import Foreign.ForeignPtr
import Foreign.Marshal.Utils ( copyBytes )
import Foreign.Ptr
import Foreign.StablePtr
import Foreign.Storable
import System.IO.Unsafe
newtype UVec a = UVec (ForeignPtr a)
newtype MUVec s a = MUVec (ForeignPtr a)
allocUnboxedBytes :: (STorIO m s, Integral bytes, Unboxed a)
=> bytes -> m (MUVec s a)
allocUnboxedBytes bytes = do
fp <- mLift (mallocForeignPtrBytes (fromIntegral bytes))
return (MUVec fp)
unsafeFreezeUnboxed :: (STorIO m s)
=> MUVec s a -> m (UVec a)
unsafeFreezeUnboxed (MUVec arr) = do
return (UVec arr)
unsafeThawUnboxed :: (STorIO m s)
=> UVec a -> m (MUVec s a)
unsafeThawUnboxed (UVec arr) = do
return (MUVec arr)
freezeUnboxed :: (STorIO m s)
=> MUVec s a -> Int -> m (UVec a)
freezeUnboxed (MUVec arr) size = mLift $ do
arr' <- mallocForeignPtrBytes size
withForeignPtr arr $ \p ->
withForeignPtr arr' $ \p' ->
copyBytes p' p size
return (UVec arr')
thawUnboxed :: (STorIO m s) => UVec a -> Int -> m (MUVec s a)
thawUnboxed (UVec arr) size = mLift $ do
arr' <- mallocForeignPtrBytes size
withForeignPtr arr $ \p ->
withForeignPtr arr' $ \p' ->
copyBytes p' p size
return (MUVec arr')
class (Storable value) => Unboxed value
instance (Storable value) => Unboxed value
readUnboxed :: (STorIO m s, Unboxed value, Integral index)
=> MUVec s value -> index -> m value
readUnboxed (MUVec arr) index = mLift $
withForeignPtr arr $ \a -> peekElemOff a (fromIntegral index)
writeUnboxed :: (STorIO m s, Unboxed value, Integral index)
=> MUVec s value -> index -> value -> m ()
writeUnboxed (MUVec arr) index value = mLift $
withForeignPtr arr $ \a -> pokeElemOff a (fromIntegral index) value
indexUnboxed :: (Unboxed value, Integral index)
=> UVec value -> index -> value
indexUnboxed (UVec arr) index = unsafePerformIO $
withForeignPtr arr $ \a -> peekElemOff a (fromIntegral index)
sizeOfUnboxed :: (Unboxed value, Integral size)
=> value -> size
sizeOfUnboxed = fromIntegral . sizeOf
castUnboxed :: UVec a -> UVec b
castUnboxed (UVec vec) = UVec (castForeignPtr vec)
castMUnboxed :: MUVec s a -> MUVec s b
castMUnboxed (MUVec mvec) = MUVec (castForeignPtr mvec)
#endif
allocUnboxed :: forall s a elems m. (STorIO m s, Integral elems, Unboxed a)
=> elems -> m (MUVec s a)
allocUnboxed elems =
allocUnboxedBytes (fromIntegral elems * sizeOfUnboxed (undefined::a))