module Data.Array.Comfort.Storable.Internal (
Array(Array, shape, buffer),
reshape,
mapShape,
(!),
unsafeCreate,
toList,
fromList,
vectorFromList,
createIO,
createWithSizeIO,
showIO,
readIO,
toListIO,
fromListIO,
vectorFromListIO,
) where
import qualified Data.Array.Comfort.Shape as Shape
import Foreign.Marshal.Array (pokeArray, peekArray, )
import Foreign.Storable (Storable, peekElemOff, )
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, mallocForeignPtrArray, )
import Foreign.Ptr (Ptr, )
import System.IO.Unsafe (unsafePerformIO, )
import Prelude hiding (readIO, )
data Array sh a =
Array {
shape :: sh,
buffer :: ForeignPtr a
}
instance (Shape.C sh, Show sh, Storable a, Show a) => Show (Array sh a) where
show = unsafePerformIO . showIO
reshape :: sh1 -> Array sh0 a -> Array sh1 a
reshape sh (Array _ fptr) = Array sh fptr
mapShape :: (sh0 -> sh1) -> Array sh0 a -> Array sh1 a
mapShape f (Array sh fptr) = Array (f sh) fptr
infixl 9 !
unsafeCreate ::
(Shape.C sh, Storable a) => sh -> (Ptr a -> IO ()) -> Array sh a
unsafeCreate sh = unsafePerformIO . createIO sh
(!) :: (Shape.C sh, Storable a) => Array sh a -> Shape.Index sh -> a
(!) arr = unsafePerformIO . readIO arr
toList :: (Shape.C sh, Storable a) => Array sh a -> [a]
toList = unsafePerformIO . toListIO
fromList :: (Shape.C sh, Storable a) => sh -> [a] -> Array sh a
fromList sh = unsafePerformIO . fromListIO sh
vectorFromList :: (Storable a) => [a] -> Array (Shape.ZeroBased Int) a
vectorFromList = unsafePerformIO . vectorFromListIO
createIO ::
(Shape.C sh, Storable a) => sh -> (Ptr a -> IO ()) -> IO (Array sh a)
createIO sh f = createWithSizeIO sh $ const f
createWithSizeIO ::
(Shape.C sh, Storable a) => sh -> (Int -> Ptr a -> IO ()) -> IO (Array sh a)
createWithSizeIO sh f = do
let size = Shape.size sh
fptr <- mallocForeignPtrArray size
withForeignPtr fptr $ f size
return $ Array sh fptr
showIO :: (Shape.C sh, Show sh, Storable a, Show a) => Array sh a -> IO String
showIO arr = do
xs <- toListIO arr
return $ "fromList " ++ showsPrec 11 (shape arr) (' ' : show xs)
readIO :: (Shape.C sh, Storable a) => Array sh a -> Shape.Index sh -> IO a
readIO (Array sh fptr) ix =
withForeignPtr fptr $ flip peekElemOff (Shape.offset sh ix)
toListIO :: (Shape.C sh, Storable a) => Array sh a -> IO [a]
toListIO (Array sh fptr) =
withForeignPtr fptr $ peekArray (Shape.size sh)
fromListIO ::
(Shape.C sh, Storable a) =>
sh -> [a] -> IO (Array sh a)
fromListIO sh xs =
createWithSizeIO sh $ \size ptr ->
pokeArray ptr $ take size $
xs ++
repeat (error "Array.Comfort.Storable.fromList: list too short for shape")
vectorFromListIO :: (Storable a) => [a] -> IO (Array (Shape.ZeroBased Int) a)
vectorFromListIO xs =
createIO (Shape.ZeroBased $ length xs) $ flip pokeArray xs